Skip to content
Coritan Docs

Organization API: Organizations & Members: Ads

The 10 Organization API operations for ads.

View as Markdown

Part of Organizations & Members.

Method Path Summary
GET /api/v1/orgs/{org_slug}/ads Get ads
DELETE /api/v1/orgs/{org_slug}/ads/connections/{connection_id} Disconnect one ad account
POST /api/v1/orgs/{org_slug}/ads/connections/{connection_id}/sync Read one ad account now
GET /api/v1/orgs/{org_slug}/ads/return Get ad return
GET /api/v1/orgs/{org_slug}/ads/spend What was spent, grouped by platform, campaign or day
GET /api/v1/orgs/{org_slug}/ads/spend/manual Spend entered by hand, newest first
POST /api/v1/orgs/{org_slug}/ads/spend/manual Enter spend for a channel that has no connection
DELETE /api/v1/orgs/{org_slug}/ads/spend/manual/{entry_id} Remove an entry of spend entered by hand
POST /api/v1/orgs/{org_slug}/ads/{platform}/accounts Pick which of the platform's accounts to read
POST /api/v1/orgs/{org_slug}/ads/{platform}/connect Start signing in to an ad platform

GET /api/v1/orgs/{org_slug}/ads

Every ad platform with its status, every connected ad account, and the last 30 days of spend.

Needs the Admin or Owner role. platforms lists Google Ads, Meta Ads, TikTok Ads, Microsoft Ads and Reddit Ads. A platform's status is not_configured (Coritan has not added its app credentials, so it cannot be connected), not_connected, pending (signed in, no account picked yet), connected, failing (an account has had errors and no successful read for an hour) or reauth (the sign-in ended, so connect again). connections has one entry for each ad account the sign-in found, with the same status words (an account that is found but not picked reads pending), when it was last read, the last error, how far its 13 month history has been read and its spend per currency. summary is the last 30 days of spend per currency, with entered spend included. warning is set when a sign-in ends within 14 days. Nothing here carries a token.

Name In Type Required
org_slug path string yes
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

DELETE /api/v1/orgs/{org_slug}/ads/connections/{connection_id}

Disconnect one ad account.

Needs the Admin or Owner role. The account's saved sign-in is deleted and nothing is read from it again. The spend already imported stays in your reports. Connect the platform again to read the account again.

Name In Type Required
connection_id path integer yes
org_slug path string yes
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

POST /api/v1/orgs/{org_slug}/ads/connections/{connection_id}/sync

Read one ad account now.

Needs the Admin or Owner role. With no body it reads today and the two days before. With from and to it reads those days again (at most 400, none before 13 months ago), which is how to refresh a month after the platform adjusts its numbers. The read runs in the background: check last_sync_at on the account. Answers 409 when the account's sign-in has ended or the account is not picked, and 429 after 4 requests an hour for one account.

Name In Type Required
connection_id path integer yes
org_slug path string yes

application/json

Field Type Required Description
from string (date) or null no The first day to read again. Send it with to, or send neither.
to string (date) or null no The last day to read again.
Status Meaning
202 Success.
422 The request is not valid. detail lists each problem.

GET /api/v1/orgs/{org_slug}/ads/return

What the ad spend returned: orders, new customers, revenue, CAC and ROAS per platform, and per campaign.

Needs the Admin or Owner role. An order counts for the platform its last touch came from, when its invoice is paid and it is not free: the touch's source and medium name the platform, and when they do not, its click ids do. Within a platform an order counts for the campaign whose name (or id) equals its utm_campaign, ignoring case. new_customers counts customers whose first paid order it was. roas is revenue without tax over spend, cac_minor is spend over new customers, and platform_roas is the value the platform reports over spend. Each is empty when its divisor is zero. Rows are per currency: spend and revenue meet only when they are in the same currency, so an ad account billed in one currency and customers paying in another show as separate rows with no CAC or ROAS. Payback is not computed, because it needs a gross margin that is not kept. truncated is true when more than 50,000 orders were in the range.

Name In Type Required Description
org_slug path string yes
from query string (date) or null no The first day, as YYYY-MM-DD. The default is 30 days before to.
to query string (date) or null no The last day, as YYYY-MM-DD, included. The default is today in the organization's time zone.
group query string no platform or campaign. Default: platform.
currency query string or null no Only this currency.
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

What was spent, grouped by platform, campaign or day

Section titled What was spent, grouped by platform, campaign or day

GET /api/v1/orgs/{org_slug}/ads/spend

What was spent, grouped by platform, campaign or day.

Needs the Admin or Owner role. Every row is in one currency, and a platform that spent in two currencies has two rows: amounts in different currencies are never added. totals is the whole range per currency, even when limit (rows for each currency, by campaign) cuts the rows. Spend entered by hand is included, spread evenly over its days. The range is at most 400 days. Days follow each ad account's own time zone (Microsoft Ads and Reddit Ads follow the organization's), so a day's spend can differ a little from the platform's own report in another zone.

Name In Type Required Description
org_slug path string yes
from query string (date) or null no The first day, as YYYY-MM-DD. The default is 30 days before to.
to query string (date) or null no The last day, as YYYY-MM-DD, included. The default is today in the organization's time zone.
group query string no platform, campaign or day. Default: platform.
currency query string or null no Only this currency.
limit query integer no Rows to return for each currency when grouping by campaign. Default: 100.
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

Spend entered by hand, newest first

Section titled Spend entered by hand, newest first

GET /api/v1/orgs/{org_slug}/ads/spend/manual

Spend entered by hand, newest first.

Needs the Admin or Owner role. ignored is true for an entry whose channel has since been connected, which reports leave out because the platform's own numbers cover it.

Name In Type Required Description
org_slug path string yes
limit query integer no Entries to return, newest first. Default: 100.
offset query integer no Entries to skip. Default: 0.
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

Enter spend for a channel that has no connection

Section titled Enter spend for a channel that has no connection

POST /api/v1/orgs/{org_slug}/ads/spend/manual

Enter spend for a channel that has no connection.

Needs the Admin or Owner role. amount_minor is the whole amount over starts_on to ends_on (at most 400 days), and reports spread it evenly over those days. A platform with a picked account, or one that was already read for some of these days, is refused with 409 because its own numbers cover it. Answers 422 for a channel, currency, amount or dates that do not fit.

Name In Type Required
org_slug path string yes

application/json (required)

Field Type Required Description
channel string yes Where the money was spent: a platform key or another network such as x, linkedin, snapchat, pinterest or other.
label string yes What the spend was for, in your words.
currency string yes The three letter code of the currency it was paid in.
amount_minor integer yes The whole amount over the days, in the currency's smallest unit (cents for USD).
starts_on string (date) yes The first day the spend covers.
ends_on string (date) yes The last day the spend covers.
Status Meaning
201 Success.
422 The request is not valid. detail lists each problem.

Remove an entry of spend entered by hand

Section titled Remove an entry of spend entered by hand

DELETE /api/v1/orgs/{org_slug}/ads/spend/manual/{entry_id}

Remove an entry of spend entered by hand. Needs the Admin or Owner role.

Name In Type Required
entry_id path integer yes
org_slug path string yes
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

Pick which of the platform's accounts to read

Section titled Pick which of the platform's accounts to read

POST /api/v1/orgs/{org_slug}/ads/{platform}/accounts

Pick which of the platform's accounts to read.

Needs the Admin or Owner role. account_ids is the whole list: accounts you name start being read (their 13 month history first), and accounts of this platform you leave out stop being read but keep the spend already imported. At most 50 accounts for one platform. Answers 422 for an account that is not on the sign-in. Pick only the accounts that belong to this organization: a sign-in to a manager account can list accounts that are not yours.

Name In Type Required Description
platform path string yes One of google, meta, tiktok, microsoft, reddit.
org_slug path string yes

application/json (required)

Field Type Required Description
account_ids array of string yes The accounts to read, by the platform's own ids. Accounts of the platform that are not listed stop being read.
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

Start signing in to an ad platform

Section titled Start signing in to an ad platform

POST /api/v1/orgs/{org_slug}/ads/{platform}/connect

Start signing in to an ad platform. Answers authorization_url, the platform's own page.

Needs the Admin or Owner role. Send the person to authorization_url. The platform sends the browser back to Coritan, which finds the accounts the sign-in can read and returns the person to return_path (a page of the console on the host of this request) with ads=connected or ads=error in the address. The link is good for 15 minutes. Answers 409 not_configured when the platform's app credentials have not been added to Coritan, and 422 when the request does not come from one of your console's hosts.

Name In Type Required Description
platform path string yes One of google, meta, tiktok, microsoft, reddit.
org_slug path string yes

application/json

Field Type Required Description
return_path string or null no The page of the console to come back to when the sign-in is done, such as /staff/marketing/ads. It is a path on the host the request came from.
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.