Conventions
The rules that cross the AdCrunch APIs — ids, provider values, money, time, casing, paths, and pagination — including the places where the APIs do not agree yet.
This page states each rule as the API applies it today. Where the four APIs do not agree, the page says so.
Ids
- An advertiser id is
acc_and the account id of the provider, for exampleacc_1203456789012345for a Meta ad account andacc_4829301756for a Google Ads customer. An advertiser is an ad account that your organization connects. - An entity id is the id that its provider gives, with no prefix: a campaign, an ad group, an ad, a creative, or an asset group. The same id can exist at two providers, or for two types at one provider. So an entity is unique for its
provider, itstype, and itsidtogether. - A Google Ads ad has a composite id,
{adGroupId}~{adId}, because Google Ads keeps an ad on the link between the ad group and the ad. - A Skill, a Brand, a Persona, and a Campaign Plan have a
slug. The slug is the handle in the path, for example/context/brands/acme. A Persona belongs to one Brand, so its handle is the pair:/context/brands/acme/personas/loyalists. - An id that AdCrunch makes has a prefix:
ast_for an Asset,doc_for a Document,lni_for a Line Item, andpsn_for a Persona. - A Mutation has the
workflowIdthatPOST /mutationsreturns.
Providers
The field provider takes the API value of a provider, for example meta, tiktok, or gads. Send the value exactly. gads is Google Ads, and no value is google. What each provider supports lists the API value of each provider, and what each provider can do.
Which providers an operation works with
Some operations work with some providers only. A creative comes from Meta, an asset group comes from Google Ads, and a change runs on Meta. Each of those operations starts with one line of badges:
The same operation carries those API values in x-adcrunch-providers, beside its description in the OpenAPI document. A code generator reads that field, and it reads no prose.
An operation with no badges works the same way whatever your organization connects. The mutation history, every Context operation, and every Asset operation except registration are of this kind.
The line names the providers and stops there. To read what each provider supports, and where it stops, use the one table.
Money
A read and a write use different units today.
| Where | Unit | 50.00 is |
|---|---|---|
Observe: budget on an entity |
whole units | 50 |
Observe: spend and each money metric on an Insight |
whole units, with decimals | 50 |
Mutations: dailyBudget, lifetimeBudget |
integer minor units | 5000 |
| Context: each amount on a Campaign Plan and a Line Item | integer minor units | 5000 |
A minor unit is the smallest unit of the currency: a cent of a dollar or of a euro.
Each amount is in the currency of its advertiser or of its Campaign Plan. A currency field names that currency as an ISO 4217 code.
GET /observe/insights also takes a currency parameter. With it, AdCrunch converts each row at the European Central Bank rate of the date of that row. It converts the rows before it adds them. Without the parameter, a group that mixes two currencies answers currency: null.
Time
- A timestamp that AdCrunch writes is a number: milliseconds since the Unix epoch, in UTC.
createdAtandupdatedAtare examples. - A calendar date is a string,
YYYY-MM-DD:sinceanduntilon Insights, and each date on a Campaign Plan. - A delivery time of Meta is an ISO 8601 string:
startTimeandendTimewhen you create an ad set.
Casing
The APIs do not use one casing for field names.
- Observe, Mutations, and Assets use camelCase:
advertiserId,dailyBudget. - Context takes snake_case in a request, and answers camelCase. You send
website_url, and you readwebsiteUrl. The query parameterbase_revisionis snake_case too. - An Insight mixes the two in one row:
advertiserIdandentityIdbesideconversion_valueandaction_add_to_cart.
Send each field in the casing that its operation page shows.
Paths
Some published paths end in a slash, for example /context/skills/ and /assets/. Others do not, for example /observe/campaigns. Send each path as its operation page shows it.
Pagination
The lists use three forms today.
| Operations | Send | Read | The last page |
|---|---|---|---|
| The entity lists of Observe | limit (default 500, maximum 500) and offset |
data, and pagination with limit, offset, and total |
offset + limit is total or more |
GET /observe/insights |
limit (maximum 100) and offset |
an array of rows | a page with fewer rows than limit |
GET /mutations |
cursor, from the previous answer |
mutations and nextCursor |
the answer has no nextCursor |
| The lists of Context and Assets | nothing | the whole list | the first page |
A live read (fresh=true) refuses an offset above 0 with 422, because a provider pages with its own cursor. To read more rows live, raise limit. A live read can also answer with no pagination.total. What each provider supports says which provider does this.