Tempio Docs
Platforms

Google

Google Ads is one customer account holding campaigns, ad groups, ads, keywords and Performance Max asset groups. Connect the account first — Connections covers the grant, the first sync and what each status means — and from then on Tempio reads the account's structure and daily numbers, and writes to it through drafts. Nothing here reaches Google directly: a change is a draft on the record first, applied when it is approved, by you or by a rule your workspace wrote.

What a draft can change

EntityWhat a draft can changeOn Google
CampaigncreateSearch, Display or Performance Max. Created paused, with its budget written in the same request
CampaignnameRenaming is its own draft, and takes effect immediately
CampaignstatusActive or paused. Google has no archive, so a draft asking for one is refused and points at removal instead
CampaignbudgetDaily or lifetime, written to the budget the campaign points at rather than to the campaign
CampaignbidManual CPC, maximize clicks, maximize conversions, maximize conversion value, target CPA or target return on ad spend, with the target where the strategy takes one. A strategy Google does not have is refused rather than mapped onto a different one
CampaignscheduleStart, end, and the dayparting hours
CampaigntargetingLocations, languages, audiences and networks, replaced whole rather than edited in place
Ad groupcreateUnder a campaign, created paused. Its type follows the campaign's, which is why the parent is read first
Ad groupnameRenaming is its own draft
Ad groupstatusActive or paused
Ad groupbidThe ad group's cost-per-click bid
Ad grouptargetingThe audience, replaced whole. A draft that names no audience leaves the ad group's audiences alone. Locations, languages and networks belong to the campaign
AdcreateA responsive search ad or a responsive display ad, created paused
AdstatusActive or paused, and the only field an existing Google ad has that a draft can change — a Google ad has no settable name
AdcreativeGoogle ads cannot be edited, so the change is a replacement ad plus the removal of the old one, in one request
Keywordcreate, update, removeText, match type and bid, positive or negative, at the ad group or the campaign
Negative keyword listcreate, updateA shared list, with its membership written whole
Asset groupcreate, updateThe Performance Max group with its headlines, descriptions, images, logos and search themes
MediauploadImages by their bytes, videos by their YouTube address
Account defaultsupdateThe account's primary conversion action
Campaign, ad group, ad, keyword, asset groupremovePermanent. See below

Everything Tempio creates on Google is created paused, and the paused status is written explicitly rather than left to Google's own default, so a new campaign, ad group or ad can never start spending because a platform default moved. Setting it live is a second change, drafted and approved on its own.

One change, one request

Every Google write Tempio makes is a single request that either commits whole or changes nothing. A campaign create is two operations — the budget, then the campaign that points at it — and a Performance Max asset group can be nineteen, covering the group, its text assets, the links between them and its search themes. Either way, Google applies all of them or none, so there is no state where half a draft landed and the rest has to be cleaned up by hand.

A batch of drafts is still one row per entity. If you approve a campaign, an ad group and three keywords together, each is its own record with its own status, because each is separately approvable, separately auditable and separately reversible. The all-or-nothing guarantee is about a single row's request, and the batch is an ordered set of those rows: a child row reads its parent's new id from the row before it, and a child whose parent was never created is refused rather than written under a guessed id.

If the connection drops after a request has been sent and before Google answers, Tempio does not send it again — Google offers no way to say "this is the same write, do not repeat it". Instead the draft is marked as an unknown outcome and Tempio looks: anything it creates carries a short marker in square brackets appended to the name, and that marked name is what a re-check searches for. The marker stays on the name, because it is also what keeps two attempts at the same create from colliding on Google's duplicate-name rule. An update is checked differently, by comparing the field against both the value the draft asked for and the value recorded before it: the first means the change landed, the second means it did not, and anything else parks the draft for a person rather than guessing.

A shared budget is refused, not fanned out

A Google budget is its own object, and one budget can be attached to several campaigns. Changing it changes the spend of every campaign attached to it.

So before writing a budget Tempio reads it, and if it is shared by more than one campaign the draft is refused rather than applied. The refusal names the number of campaigns the budget serves, so you can see what the change would have touched. To go ahead anyway, the draft has to acknowledge that exact number: an acknowledgement of three campaigns against a budget that turns out to serve four is refused again. The read happens twice, once when the draft is checked and once immediately before it is applied, because a budget can be attached to another campaign in between.

Removing on Google cannot be undone

Meta archives; Google removes. A removed campaign, ad group, ad, keyword or asset group stays visible in reporting and its history stays in Tempio, but it is gone as a live object: it cannot be renamed, re-budgeted, re-enabled or even re-paused. There is no undo, no un-remove, and no support request that brings it back. Recreating it means creating a new one, with a new id, that carries none of its learning.

Because of that, a removal draft has to say in the payload that the change is irreversible before Tempio sends it, and a second removal of the same entity is refused by Google rather than quietly succeeding. Pausing is what you want almost every time; removal is for the case where you are certain.

A new Search campaign has no keywords in it

Keywords are their own rows, so a Search campaign create and the keywords that go in it are separate drafts inside one batch. The campaign lands first, and until its keywords land it can match nothing.

Tempio says so on the applied campaign rather than leaving you to notice: a Search campaign create comes back with a "campaign not serving" note explaining that it cannot serve until it has keywords. A Display or Performance Max create carries no such note, because neither needs keywords to run.

What an ad needs before Google accepts it

A responsive search ad needs at least three headlines and two descriptions. Below either minimum the draft is refused with the field named, before anything is sent.

A responsive display ad needs at least one headline, one description, one long headline and one marketing image. The long headline is a separate field from the headlines and Google requires exactly one, so a display draft that carries none is refused naming it.

A Performance Max asset group needs more: three headlines, one long headline, two descriptions, a business name, and at least one marketing image, one square marketing image and one logo. Search themes are optional, up to twenty-five. Every image an asset group references has to be an asset that already exists in the account, which is what the media upload below is for — an asset group draft naming an image Tempio has not uploaded is refused with the index of the one it cannot resolve.

Undoing an asset group update restores what Tempio's own copy of the group holds — its name, its status, its final URLs, its search themes, and its headlines, long headlines and descriptions — and names no image, logo or video, so the ones the group is running stay exactly as they are.

Uploading an image or a video

Google has no upload endpoint. An image asset carries its bytes inside the request, so Tempio reads the file and sends it inline, and Google's limit of 5 MB per image is checked against the size recorded when the file was added — an oversized file is refused without a single byte being fetched or an operation being spent. The bytes are checked again against that recorded size when they arrive, because a file of a different length is not the file that was approved. The content hash recorded with the file is checked too: same length, different bytes is still not the file that was approved.

Tempio reads those bytes from your own workspace's file store and from nowhere else. A draft that points at any other address is refused before anything is fetched, whoever wrote the draft.

A video asset on Google is a YouTube video and nothing else. A draft whose video is a YouTube address is accepted and the video is referenced by its id, with no bytes uploaded at all; a draft pointing anywhere else is refused rather than mapped onto some other video.

Uploading the same file twice under the same draft gives back the same asset: the upload is named with the draft's marker, so a retry finds the asset already there and adopts it instead of creating a second copy.

Checking a draft against the real account

Google is the one platform Tempio can ask "would this work?" without writing anything. The check sends the same request the apply would send, byte for byte, with one flag that tells Google to validate and discard it. Google runs the account's own validators — budget minimums, policy findings, duplicate names, bidding compatibility — and answers with the field path into your draft when it refuses.

The checks Tempio can answer itself run first and cost nothing: an unsupported campaign type, a rename on an ad, an archive Google cannot perform, an ad below its minimums, a shared budget. Those are refused locally, before any request. The check runs when the draft is written and again when it is applied, because an account can change while a draft waits for approval.

Targeting sits at two levels

Locations, languages and networks are campaign settings on Google. Audiences can be attached to an ad group.

So an ad-group targeting draft writes the audience, and says which fields it did not write. Tempio does not push a location or a language up to the campaign to satisfy an ad-group draft — that would change a campaign nobody reviewed — and it does not silently drop the field either. The applied draft names every campaign-level field the spec carried and the ad group could not take, so the gap is on the record. Draft the same field at the campaign level and it is written there.

An audience list the draft does not state is left exactly as it is. The audience is the only thing Google carries on an ad group, so a draft that names none — "target Australia", say — is a draft about the campaign's fields, and Tempio writes nothing rather than reading an unstated list as "remove every audience this ad group has". The applied draft says so. To change the audiences, name the ones to keep: the list you state replaces the list that is there.

Every targeting draft is a complete replacement of the criteria types it covers: Tempio reads what is on the entity, removes what the draft does not name and creates what is missing. Criterion types the draft does not cover are left exactly as they are.

Research and reports

Five reads answer the questions that come before a draft and after a number moves. All five take a Google connection and read that account only.

ReadWhat it answers
Keyword, topic and interest researchWhat to target, and the id to target it with
Location searchWhich numeric location id a place name means
Search termsWhat people actually typed before an ad showed
PlacementsWhich sites, apps and channels the money went to
Change historyWho changed what, when, and which fields moved

Resolve the id before you target it

Google's locations, topics and audiences are numbers. "Australia" is 2036 and "Sydney, New South Wales, Australia" is 1000286; there is no string form a campaign accepts. A targeting draft carrying a guessed id is a draft that fails when it is applied, so the location search resolves the name first and hands back both forms a targeting payload takes — the bare id and the geoTargetConstants/2036 resource name — with the canonical name beside them, which is the only thing that tells Sydney, Australia apart from Sydney, Nova Scotia. Narrow an ambiguous name with a two-letter country code.

Topic and interest research works the same way and for the same reason: each row carries the id a criterion takes. A topic seed matches a path segment exactly — Music & Audio, not music — because Google stores a topic as a path and offers no partial match over one. An interest seed is a substring of the audience name, so Running finds Running & Jogging Enthusiasts. Two characters in an interest seed carry more weight than they look: % matches any run of characters and _ matches any single one, and Google offers no way to escape them, so a seed containing either matches more than it reads like.

Keyword research is the exception that proves the rule: a keyword idea has no id at all. Its text is what a keyword criterion carries, so the row's id is empty on purpose rather than by omission. What it does carry is the average monthly searches, the competition (low, medium or high, with the 0–100 index behind it), and the low and high top-of-page bid estimates. Pass location ids from the location search to scope those figures to the places you actually advertise in.

Money, and what is never stored

Every amount these reads return is an integer of minor units beside the ad account's currency — 988 and AUD, never 9.88. Google states its money in micros of a major unit, one million micros to the unit, and Tempio converts with integer arithmetic: the cents instinct is a hundred times wrong for yen.

No ratio is stored. Click-through rate, cost per click, cost per thousand, cost per acquisition and return on ad spend are computed when the report is read, from the base counts, and each is empty rather than zero when its denominator is — a campaign with no conversions has no cost per acquisition, which is not the same as a cost per acquisition of nothing.

The reports

The search-terms and placements reports take a date range in the ad account's own timezone, because that is where Google buckets a day, and optionally a campaign or ad group to narrow to. Both come back ordered by cost, highest first, so a row limit that bites drops the cheap tail rather than an arbitrary slice. Placements read at two levels: the detail level is the individual page, video or app, and the group level is the domain or channel above it, which is where a placement exclusion is usually written.

When a limit ends the list, the result says so. A report that was cut short is not a smaller report, and Tempio marks it rather than letting a partial answer read as a complete one.

Change history

Google keeps its own record of every change made to the account, and this read returns it: the time in the account's timezone, the email of the person Google attributes the change to, whether it came from the Google Ads web interface, the API or an automated rule, the operation, the exact list of fields that moved, and the before and after values for those fields alone.

Where the changed thing is a campaign or ad group Tempio holds for this workspace, the row carries a link straight to it. A row without a link is a resource Tempio does not mirror, not a missing record.

The before and after values are Google's own fields, passed through as they arrive rather than rewritten. A field named in micros there is millionths of one unit of the account's currency — 750000 is seventy-five cents, not seven hundred and fifty thousand of them — and Tempio converts nothing inside them, because they are snapshots of Google's shapes and not of ours.

Google keeps this history for thirty days. A since more than thirty days back is clamped to the window Google keeps, and the result says so, because the API refuses a longer window rather than answering it with fewer rows. An empty result over an old window means the history has aged out, not that nothing changed.

Account defaults

Google stores no account defaults. A Google campaign is self-contained: there is no account-level identity, page or pixel object of the kind other platforms require, so the defaults Tempio keeps for a Google account are kept by Tempio.

The one that matters is the primary conversion action, the conversion the account's reporting is anchored to. When a draft names one, Tempio reads the account's conversion actions and refuses the draft if the account has no such action — a wrong id is worth catching here rather than in a report that quietly counts the wrong thing. Fields that belong to another platform are refused by name rather than ignored.

Access

An unverified Google OAuth consent screen admits 100 accounts over its lifetime; brand verification of the Cloud project lifts that cap.