X Ads
Tempio connects X Ads accounts, lists them in your workspace, and carries raw requests to the X Ads API through the escape hatch. It reads no campaigns, line items, ads or daily numbers from X. Anything the X Ads API offers is one raw request away: a read runs at once, and a change is a draft that waits at the gate until a person approves it.
Connecting
Connect X from Connections. You need to be an owner or an admin of the workspace.
X signs in over OAuth 1.0a, which takes one more step than the other platforms. When you press connect, Tempio first asks X for a request token, signed with Tempio's app credentials and carrying Tempio's callback address. X hands back a one-time token, and Tempio sends you to X's consent screen with it.
The consent screen names Tempio's X app and the access it is registered with. OAuth 1.0a has no per-request scopes, so Tempio's request carries no scope list, and the screen shows the app's own permission level, read and write. Tempio needs write because a raw change you approve is sent to X under this sign-in.
When you approve, X returns you to Tempio with the same one-time token and a verifier. Before anything is exchanged, Tempio checks that the token X returned is the one this browser started with, that the sign-in began in the workspace you are in now, and that it began less than ten minutes ago. Any mismatch stops the connection and asks you to start again. If you cancel on X's consent screen instead, you land back where you started and nothing is stored.
Tempio then exchanges the verifier for your access token and its secret, seals both in the workspace's token vault, and opens the account picker.
The picker, funding sources and currency
The picker lists every X Ads account the signed-in X user can reach. Tempio reads each account's name, status and time zone from the account itself, and its currency from the account's funding sources, because X reports currency on a funding source rather than on the account. An active funding source is used first; a deleted or cancelled one is skipped.
An account with no funding source has no currency Tempio can store, so the picker shows it with its checkbox disabled and this reason:
X reports no currency for this account until it has a funding source.
When X refuses to show one account's funding sources, that account is disabled with a reason saying so, and the other accounts can still be picked.
Add a funding source to the account in X Ads, then connect again and the account can be picked. An account whose time zone X reports in a form Tempio cannot use is disabled the same way, with the time zone named in the reason.
After you pick, each account becomes a connection in the workspace, and Tempio checks it on your plan's sync schedule. The check reads the account and its funding sources again. If a connected account loses its last funding source, the check fails with the same sentence, and the currency and time zone Tempio stored stay as they were.
What Tempio reads
The account: its name, id, currency, time zone and status. X's account status maps to active when X has accepted the account, closed when it is deleted, and disabled when X has rejected or suspended it. Any other status shows as unknown rather than a guess.
What Tempio does not read
Campaigns, line items, promoted tweets, audiences and daily numbers stay on X. Tempio stores none of them, so Campaigns, the metrics views and the timeline show nothing for an X connection, and a modelled draft on it is refused. The only change it takes is a raw one.
Raw requests on X Ads
A workspace owner turns raw requests on in Settings → Raw platform requests, as for every platform. The rules on that page apply to X unchanged: the path is X's own, the base is never an argument, and every call is audited.
The base is https://ads-api.x.com/12, the X Ads API with its version segment.
A raw path starts with / and is composed under it, so /accounts/{id} is
sent to https://ads-api.x.com/12/accounts/{id}.
A GET is a read. Everything else is a change, including X's asynchronous analytics jobs: they are POSTs that create a job, so they are drafted like any other change.
Tempio signs every X request itself. Each one carries an Authorization: OAuth
header built from your access token and its secret, over the method, the URL
and every query parameter. A JSON body is sent as it is and is not part of the
signature. A query or body key that starts with oauth_ is refused before
anything is sent, because those parameters are Tempio's to sign.
A read
To list an account's campaigns:
{
"entity": "platform_request",
"action": "get",
"params": {
"connectionId": "…",
"method": "GET",
"path": "/accounts/18ce54d4x5t/campaigns",
"query": { "count": "50" }
}
}Tempio resolves the path to
https://ads-api.x.com/12/accounts/18ce54d4x5t/campaigns?count=50, signs it,
sends it, and hands back X's own response body. Nothing in it is converted:
amounts are in X's units, not minor units, and none of it reaches Tempio's
reports. The call writes an audit row with the method, host, path, status and
X's request id, and never the body.
A change
To pause a campaign:
{
"entity": "platform_request",
"action": "mutate",
"params": {
"connectionId": "…",
"method": "PUT",
"path": "/accounts/18ce54d4x5t/campaigns/8wku2",
"query": { "entity_status": "PAUSED" },
"description": "Pause the spring launch campaign while the landing page is down."
}
}This sends nothing to X. It creates a change request in Drafts with the method, the path and your description, and the description is required because it is what the reviewer reads at the gate. No approval rule clears a raw change, so it waits for a person with approve access on the connection. Once they approve it, Tempio checks the raw-request switches and the connection's kill switch again, signs the request and sends it once. X's response is stored on the draft, and the draft carries a warning that Tempio did not read the change back from X, since it models nothing there to compare against.
Rate limits
X counts requests per endpoint and per signed-in user, in 15-minute windows. When X answers that a limit is used up, Tempio reports the call as rate limited with the wait X gives in its reset header, or a full 15 minutes when X gives none.
Reconnecting
An X sign-in does not expire, so there is nothing to refresh and no scheduled renewal. It stays valid until it is revoked. When X refuses it, Tempio treats the sign-in as revoked: the next account check marks the connection as needing reconnection and the connection shows the reconnect action. Connecting X again from Connections issues a new sign-in. A sign-in whose stored secret is missing is treated the same way.
Connecting a Reddit Ads account, what Tempio reads from it, and how a raw read and a raw change reach the Reddit Ads API.
Microsoft Advertising
Connecting a Microsoft Advertising account, the customers and accounts Tempio lists, the developer token and headers Tempio sends, time zones, and raw requests to the five service hosts.