# Connect ad accounts and see what ads return

> Read your ad spend from Google, Meta, TikTok, Microsoft and Reddit, add spend by hand, and see new customers, revenue, CAC and ROAS per platform.

Source: https://www.coritan.com/docs/organizations/ad-spend/

In the dashboard:

- /dashboard/organizations/…/settings/ads: https://www.coritan.com/dashboard/organizations

Ad spend shows what you pay each ad platform and what that spending brings back. Coritan reads the cost, clicks and impressions of each campaign, day by day, from your Google Ads, Meta Ads, TikTok Ads, Microsoft Ads and Reddit Ads accounts. It then matches your orders to the platform their last visit came from, and works out how many new customers each platform won, what they paid, what each customer cost (CAC) and what each unit of spend returned (ROAS).

Money is never added across currencies. An ad account that bills in dollars and one that bills in euros give separate rows and separate totals.

## Before you begin

- You need the Owner or Admin role in the organization. No other role can read or change anything here.
- The platform must be available to connect. Coritan sets up the sign-in app for each platform. A platform that is not set up shows the status `not_configured` and refuses to connect with a `409` answer.
- You need an account on the platform with access to the ad account you want to read. For Google Ads and Microsoft Ads that can be a manager account that holds your ad account.
- Read access is all Coritan asks for. It cannot change a campaign, a budget or an ad.
- Orders get matched to a platform through the tracker that runs on your storefront. Your ads need `utm_source`, `utm_medium` and `utm_campaign` in their links, or the platform's click ID, so the tracker can name the platform. See [How customers and orders are attributed](/docs/organizations/attribution/).

## Set it up in your dashboard

Owners and admins connect ad accounts in the dashboard. Your team can do the same in the staff console, as [Team and settings](/docs/organizations/staff-console/team-and-settings/) describes. A member with another role does not see the page, and its address opens **Overview**.

1. In the [dashboard](https://www.coritan.com/dashboard/organizations), open the organization, then **Settings**, then **Ad spend**.
2. Find the platform's card, "Google Ads", "Meta Ads", "TikTok Ads", "Microsoft Ads" or "Reddit Ads", and select **Connect**. A card with the badge **Not set up** says **Not set up on this platform yet.** and its **Connect** button stays off. Nothing on your side fixes that: ask support.
3. Sign in on the platform's own page with the account that can open your ad accounts, and allow read access. The link works for 15 minutes. The platform then sends you back to **Ad spend**, which says the platform is connected and how many ad accounts it found. When the platform refused, the page says it was not connected and shows the platform's reason. Select **Connect** again to start over.
4. Choose the accounts to read. A sign-in that finds one account, on a platform where you have chosen none yet, chooses it for you. Otherwise the card's badge reads **Choose accounts**. Select **Choose accounts…**, tick the accounts that belong to your organization and select **Save accounts**. A sign-in to a manager account can list accounts that are not yours, so tick only your own. You can choose up to 50 accounts for one platform.
5. Read the card. **Accounts read** says how many of the accounts found we read, **Last read** says when, and **Spend, 30 days** adds up each currency's spend. Each account has a row with its **Status**, **Last read**, **History**, which says how far back we have read, and **Spend, 30 days**.

When it works, the badge reads **Connected**, an account's **Last read** shows a time within the last 15 minutes and **Last 30 days** at the top of the page shows spend in each currency. A new account's history fills in over several passes: **History** reads "Reading it now" until the first one lands.

What a card's badge means:

**Connected**
: We read the chosen accounts every 15 minutes.

**Choose accounts**
: The sign-in found accounts and none is chosen, so nothing is read.

**Failing**
: An account has had errors and no successful read for an hour. Its row shows the platform's reason, such as the signed-in person losing access to the ad account. Fix it in the platform. We try again every 15 minutes, and **Sync now** tries at once.

**Sign in again**
: The platform no longer accepts the saved sign-in. Select **Connect again** and sign in with the person who owns the ad accounts. Your history and the spend you entered stay.

**Not connected**
: Nothing is signed in yet.

**Not set up**
: Coritan has not added the sign-in app for this platform yet.

A Meta sign-in ends after about 60 days. When it has 14 days or fewer left, the card says **The sign-in is about to end**. Select **Connect again** before it does.

To read an account now, open the actions menu of its row and select **Sync now**. The page says it is reading the account, and the new figures show in a few minutes. You can do this 4 times an hour for one account, and the next try says how long to wait. To stop reading an account, open the same menu and select **Disconnect…**. The question names the account. Confirm with **Disconnect account**: we delete its saved sign-in, and the spend we already read stays in your reports.

**Spend you enter by hand** holds spend for a channel with no connection, such as X, LinkedIn or a print ad, so the return report counts it.

1. Select **Add spend…**.
2. Choose the **Channel** and name the spend in **What it was for**. Choose the **Currency** and type the **Amount**: the whole amount for the days, in whole units and cents, such as 300.00. Enter the **First day** and the **Last day**. One entry covers at most 400 days.
3. Select **Add spend**. We spread the amount evenly over the days.

A channel that is connected takes no typed spend, because its own numbers cover the days: the form says so under **Channel**. An entry whose channel was connected later shows **Not used** under **Used in reports**, and the reports leave it out. To remove an entry, open the actions menu of its row, select **Delete…** and confirm with **Delete entry**.

**Last 30 days** adds up the spend of every platform and every entry, one row for each currency, and **See what it returned** opens the [Acquisition page](/docs/organizations/traffic/#read-where-customers-came-from), where **Return on ad spend** works out CAC and ROAS.

## Connect a platform

Each platform has its own sign-in page. The steps are the same for all five, and the examples below use Google Ads (`google`). The platform words are `google`, `meta`, `tiktok`, `microsoft` and `reddit`.

1. Ask for the sign-in address with `POST /api/v1/orgs/{org_slug}/ads/google/connect`. A console sends `return_path`, the page to come back to, from a page on one of your storefront's hosts. A script sends nothing. The answer holds `authorization_url`.
2. Send the person who owns the ad account to `authorization_url`. They sign in to the platform and allow read access. The link works for 15 minutes.
3. The platform sends them back to Coritan, which finds every ad account the sign-in can read and returns them to your `return_path`. The address ends with `ads=connected`, or with `ads=error` and a `message` that says what went wrong. With no `return_path`, the browser stops on a page that says whether the sign-in finished.
4. Read `GET /api/v1/orgs/{org_slug}/ads`. Each account the sign-in found is in `connections` with the status `pending`. A sign-in that finds exactly one account, on a platform where you have picked none yet, picks it for you.
5. Pick the accounts to read with `POST /api/v1/orgs/{org_slug}/ads/google/accounts`. Send `account_ids`, the whole list. Accounts you leave out stop being read.

Pick only accounts that belong to your organization. A sign-in to a manager account can list accounts of other advertisers, and Coritan cannot tell which are yours.

Coritan reads each picked account's last 13 months first, then keeps it up to date. Check `backfilled_through` on the account. It holds a date once the history has been read.

| Platform | Sign in with | What Coritan counts as a conversion | Days follow |
| --- | --- | --- | --- |
| Google Ads | A Google account that can open the ad account or its manager account | Conversions and conversion value that Google reports | Each ad account's own time zone |
| Meta Ads | Facebook, with the `ads_read` permission | Purchases, taken from the first purchase action Meta lists | Each ad account's own time zone |
| TikTok Ads | An advertiser who approves the app | Completed payments. The value is the spend times TikTok's payment ROAS | Each advertiser's own time zone |
| Microsoft Ads | A Microsoft account that can open the ad account | Conversions and revenue that Microsoft reports | Your organization's time zone |
| Reddit Ads | A Reddit account that is a member of the business | Purchase conversions and their value | Your organization's time zone |

The numbers the platforms call conversions are shown beside yours as `platform_conversions` and `platform_value_minor`. They are the platform's own count, which can include conversions from visits that never reached your orders.

A Meta sign-in lasts about 60 days. Coritan renews it each day in its last 20 days. If the renewal fails and the sign-in has 14 days or fewer left, the account carries a `warning` with `sign_in_ends_soon` and the number of days left. The other platforms' sign-ins have no end date.

## How often spend is read

Coritan reads every picked account every 15 minutes.

- Each read covers today and the two days before, because platforms revise recent days.
- Once each night, after 05:00 in your organization's time zone, it reads the last 35 days.
- A new account reads its whole 13 month history first, in steps. If the read stops, it carries on from where it stopped.

To read an account at once, use `POST /api/v1/orgs/{org_slug}/ads/connections/{connection_id}/sync`. With no body it reads the recent days. With `from` and `to` it reads those days again, up to 400 of them and none before the 13 month history. You can ask four times an hour for one account. The read runs in the background, so check `last_sync_at` afterwards.

Reading a day again replaces what was saved for it. A day the platform stops listing is removed from that account. An answer with no days at all changes nothing, so a platform that returns nothing never wipes your history.

## Add spend by hand

Some channels have no connection, such as X, LinkedIn, Snapchat, Pinterest or a sponsorship. Add their spend with `POST /api/v1/orgs/{org_slug}/ads/spend/manual`:

- `channel` is one of `google`, `meta`, `tiktok`, `microsoft`, `reddit`, `x`, `linkedin`, `snapchat`, `pinterest` or `other`.
- `label` says what the spend was for.
- `currency` is the three letter code and `amount_minor` is the whole amount in the currency's smallest unit (cents for dollars).
- `starts_on` and `ends_on` are the first and last day it covers, at most 400 days apart. The last day can be up to 31 days after today.

Reports spread the amount evenly over the days. The shares always add up to the whole amount, and any leftover unit goes to the first days. An amount of 1000 cents over three days reads as 334, 333 and 333.

A platform with a picked account, or one that was already read for some of the days you name, refuses an entry with `409`. Its own numbers cover those days. If you pick an account of a platform after you added spend for it, the entry stays in the list marked `ignored: true` and reports leave it out. A day an account read and then disconnected still covers, so an old entry never counts it a second time.

Remove an entry with `DELETE /api/v1/orgs/{org_slug}/ads/spend/manual/{entry_id}`. Each organization can keep 1000 entries.

## Read the spend

`GET /api/v1/orgs/{org_slug}/ads/spend` answers what was spent. It takes:

- `from` and `to`, both included, as `YYYY-MM-DD`. The default is the last 30 days. A range is at most 400 days.
- `group`: `platform` (the default), `campaign` or `day`.
- `currency`: only this currency.
- `limit`: for `campaign`, the rows to return for each currency, up to 500.

Every row names its `currency`. A platform that spent in two currencies has two rows. `totals` holds the whole range for each currency, even when `limit` cuts the rows.

The same call exists for staff under `/api/v1/orgs/{org_slug}/staff/marketing/ads/spend`, and it gives the same answer.

## How CAC and ROAS are worked out

`GET /api/v1/orgs/{org_slug}/ads/return` answers what the spend brought back. It takes `from`, `to` and `currency` like the spend call, and `group` as `platform` (the default) or `campaign`.

An order counts for a platform when all of these hold:

1. Its invoice is paid, the order is not free, and the order started in the range. Days are your organization's days.
2. Its last touch was paid: the visit that came last before the order, not the first one the customer ever made.
3. The touch names the platform. Its source and medium come first (`utm_source=facebook` with a paid medium is Meta Ads). When they do not name one, the click IDs on the order do: `gclid` is Google Ads, `msclkid` is Microsoft Ads, `fbclid` is Meta Ads, `ttclid` is TikTok Ads and `rdt_cid` is Reddit Ads. An order that is paid media but names no platform counts under "Other paid traffic".

Inside a platform, an order counts for a campaign when its `utm_campaign` equals the campaign's name (ignoring capitals and spaces around it) or its ID. Campaigns that share a name inside one platform count as one campaign. An order that matches no campaign counts for the platform only, in the row with no campaign name.

Each row has these figures, all in one currency:

| Field | Meaning |
| --- | --- |
| `spend_minor` | What the platform's accounts (and your entered spend) cost. |
| `orders` | Orders matched to the row. |
| `new_customers` | Customers whose first paid order is one of those orders. |
| `revenue_minor` | The orders' invoice totals without tax. |
| `cac_minor` | `spend_minor` divided by `new_customers`. Empty when there are no new customers or no spend. |
| `roas` | `revenue_minor` divided by `spend_minor`. A ROAS of 2.5 means 2.50 back for each 1.00 spent. Empty when there is no spend. |
| `platform_roas` | The conversion value the platform reports, divided by the spend. |
| `cost_per_click_minor` | Spend divided by clicks. |

For example, if Google Ads cost 150.00 USD in a range and won two new customers whose orders came to 55.00 USD without tax, CAC is 75.00 USD and ROAS is 0.37.

Spend and revenue meet only in the same currency. If your Meta account bills in dollars and your customers pay in euros, the dollar row has spend and no orders, the euro row has orders and no spend, and neither shows CAC or ROAS. To see CAC and ROAS for them, run the ad account in the currency your customers pay in.

Payback is not worked out. It needs the gross margin of a customer's first month, which Coritan does not hold.

One call reads at most 50,000 orders. `truncated` is `true` when there were more.

## Disconnect an account

`DELETE /api/v1/orgs/{org_slug}/ads/connections/{connection_id}` ends one account's connection. Its saved sign-in is deleted and Coritan reads nothing more from it. The spend Coritan already read stays in your reports. Other accounts that came from the same sign-in keep working. To read the account again, connect the platform again.

You can also remove Coritan's access in the platform's own settings. The next read then fails and the account shows `reauth`.

## Privacy and what Coritan keeps

- The sign-in's tokens are sealed when they are saved, and no call, log or screen shows them again.
- Coritan asks each platform for read access to ad accounts only.
- Coritan stores one row for each account, campaign and day: the cost, clicks, impressions, conversions and conversion value. It stores no information about the people who saw or clicked an ad.
- Only the Owner and Admin roles of your organization, and Coritan staff who manage organizations, can read or change this.
- Every change is in the [audit log](/docs/organizations/audit-log/): connecting, picking accounts, reading an account on request, disconnecting, and adding or removing spend.
- Deleting the organization deletes the connections and every spend row with it.

## Limits

- 5 platforms, up to 50 accounts for each.
- 13 months of history for a new account.
- A read of days, or a spend or return range, covers at most 400 days.
- 4 requests an hour to read one account now.
- 1000 spend entries, each over at most 400 days.

## Troubleshooting

`not_configured`
: Coritan has not set up the sign-in app for that platform. Connecting answers `409` with this word. Nothing on your side fixes it.

`reauth`
: The platform no longer accepts the saved sign-in. The person who owns the ad account must connect the platform again. Their accounts, history and entered spend are kept.

`failing`
: The account has had an error and no successful read for an hour. The account's `last_error` says why, for example that the signed-in person lost access to the ad account. Fix it at the platform. The next 15 minute read tries again.

`pending`
: The sign-in found the account and nobody picked it. Pick it with `POST .../accounts`.

The spend is lower or higher than the platform's own report
: Days follow each ad account's time zone (Microsoft Ads and Reddit Ads follow yours), so a report in another zone cuts the day somewhere else. Recent days also change for a few days while the platform settles them. A read of the last 35 days each night corrects them.

The first read has no days yet
: Reading 13 months takes several 15 minute passes when an account has many campaigns. Check `backfilled_through`.

`409 channel_connected` or `409 already_imported` when adding spend
: The platform is connected or its spend was already read for those days. Remove the connection first, or choose days it did not cover.

`429` when reading an account
: You asked more than four times in an hour for that account. Wait an hour.

A sign-in fails with a message on the way back
: The message comes from the platform, such as "did not allow access". Start again with `POST .../connect`, and allow every permission the platform asks for.

Orders show under "Other paid traffic" or under no campaign
: The links of those ads carry no `utm_source` that names the platform, or a `utm_campaign` that differs from the campaign's name. Add `utm_campaign={campaign name}` to the ad's link, or the platform's own `{campaignid}` value.

## With the API

Send an access token as `Authorization: Bearer $CORITAN_TOKEN`. The owner calls are under `/api/v1/orgs/{org_slug}/ads`. Staff members with the Admin role use the same calls under `/api/v1/orgs/{org_slug}/staff/marketing/ads`.

```bash title="Start a Google Ads sign-in"
curl -X POST "https://api.coritan.com/api/v1/orgs/acme/ads/google/connect" \
  -H "Authorization: Bearer $CORITAN_TOKEN"
```

Open `authorization_url` in a browser. A console that wants the browser back on one of its own pages sends `{"return_path": "/marketing/ads"}` from a page on one of your storefront's hosts. A request with a `return_path` from any other host is refused with `422`. The answer:

```json
{
  "authorization_url": "https://accounts.google.com/o/oauth2/v2/auth?client_id=...&state=...",
  "redirect_uri": "https://api.coritan.com/api/v1/ads/google/callback",
  "expires_in": 900
}
```

After the sign-in, pick the accounts to read:

```bash title="Read two accounts"
curl -X POST "https://api.coritan.com/api/v1/orgs/acme/ads/google/accounts" \
  -H "Authorization: Bearer $CORITAN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"account_ids": ["7778889999", "7778880000"]}'
```

Read the status of every platform and account:

```bash
curl "https://api.coritan.com/api/v1/orgs/acme/ads" -H "Authorization: Bearer $CORITAN_TOKEN"
```

`platforms[].status` is one of `not_configured`, `not_connected`, `pending`, `connected`, `failing` or `reauth`. Each entry of `connections` has the same words for an account, plus `account_name`, `currency`, `last_sync_at`, `last_error`, `backfilled_through`, `warning` and `spend_30d`, the last 30 days for each currency. `summary` is the last 30 days for the whole organization, for each currency.

Read what the spend returned, for a month, by campaign:

```bash
curl "https://api.coritan.com/api/v1/orgs/acme/ads/return?from=2026-09-01&to=2026-09-30&group=campaign" \
  -H "Authorization: Bearer $CORITAN_TOKEN"
```

```json
{
  "from": "2026-09-01",
  "to": "2026-09-30",
  "group": "campaign",
  "currencies": ["USD"],
  "rows": [
    {
      "platform": "google", "label": "Google Ads", "channel": "paid_search", "campaign": "Brand", "currency": "USD",
      "spend_minor": 10000, "clicks": 100, "impressions": 4200, "cost_per_click_minor": 100,
      "orders": 1, "new_customers": 1, "revenue_minor": 2500, "cac_minor": 10000, "roas": 0.25,
      "platform_conversions": 3.5, "platform_value_minor": 21026, "platform_roas": 2.1
    }
  ],
  "totals": [{ "currency": "USD", "spend_minor": 10000, "orders": 1, "new_customers": 1, "revenue_minor": 2500, "cac_minor": 10000, "roas": 0.25 }],
  "truncated": false,
  "basis": { "touch": "last", "revenue": "excluding_tax", "new_customers": "first_paid_order" }
}
```

Add spend by hand:

```bash title="Add 30.00 USD of X spend over a week"
curl -X POST "https://api.coritan.com/api/v1/orgs/acme/ads/spend/manual" \
  -H "Authorization: Bearer $CORITAN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"channel": "x", "label": "Launch week", "currency": "USD", "amount_minor": 3000, "starts_on": "2026-10-01", "ends_on": "2026-10-07"}'
```

A request that breaks a rule answers `409` or `422` with `detail.error` (a word such as `channel_connected`) and `detail.message` (the sentence to show).

## Related

- [How customers and orders are attributed](/docs/organizations/attribution/)
- [Add analytics and ad tags to your storefront](/docs/organizations/tags/)
- [Send purchases to your ad platforms](/docs/organizations/conversions/)
- [Read the organization audit log](/docs/organizations/audit-log/)

## Next steps

- [Check that your ads' links carry the UTM values](/docs/organizations/attribution/) the matching rule reads.
- [Read your storefront's traffic](/docs/organizations/traffic/) to compare visits with spend.

## API

- `GET /api/v1/orgs/{org_slug}/ads`: Get ads (https://www.coritan.com/docs/api/reference/organizations/organizations-members/ads/#op-get-api-v1-orgs-org-slug-ads)
- `POST /api/v1/orgs/{org_slug}/ads/{platform}/connect`: Start signing in to an ad platform (https://www.coritan.com/docs/api/reference/organizations/organizations-members/ads/#op-post-api-v1-orgs-org-slug-ads-platform-connect)
- `POST /api/v1/orgs/{org_slug}/ads/{platform}/accounts`: Pick which of the platform's accounts to read (https://www.coritan.com/docs/api/reference/organizations/organizations-members/ads/#op-post-api-v1-orgs-org-slug-ads-platform-accounts)
- `POST /api/v1/orgs/{org_slug}/ads/connections/{connection_id}/sync`: Read one ad account now (https://www.coritan.com/docs/api/reference/organizations/organizations-members/ads/#op-post-api-v1-orgs-org-slug-ads-connections-connection-id-sync)
- `DELETE /api/v1/orgs/{org_slug}/ads/connections/{connection_id}`: Disconnect one ad account (https://www.coritan.com/docs/api/reference/organizations/organizations-members/ads/#op-delete-api-v1-orgs-org-slug-ads-connections-connection-id)
- `GET /api/v1/orgs/{org_slug}/ads/spend/manual`: Spend entered by hand, newest first (https://www.coritan.com/docs/api/reference/organizations/organizations-members/ads/#op-get-api-v1-orgs-org-slug-ads-spend-manual)
- `POST /api/v1/orgs/{org_slug}/ads/spend/manual`: Enter spend for a channel that has no connection (https://www.coritan.com/docs/api/reference/organizations/organizations-members/ads/#op-post-api-v1-orgs-org-slug-ads-spend-manual)
- `DELETE /api/v1/orgs/{org_slug}/ads/spend/manual/{entry_id}`: Remove an entry of spend entered by hand (https://www.coritan.com/docs/api/reference/organizations/organizations-members/ads/#op-delete-api-v1-orgs-org-slug-ads-spend-manual-entry-id)
- `GET /api/v1/orgs/{org_slug}/ads/spend`: What was spent, grouped by platform, campaign or day (https://www.coritan.com/docs/api/reference/organizations/organizations-members/ads/#op-get-api-v1-orgs-org-slug-ads-spend)
- `GET /api/v1/orgs/{org_slug}/ads/return`: Get ad return (https://www.coritan.com/docs/api/reference/organizations/organizations-members/ads/#op-get-api-v1-orgs-org-slug-ads-return)
- `GET /api/v1/orgs/{org_slug}/staff/marketing/ads`: Get ads (https://www.coritan.com/docs/api/reference/organizations/org-staff-marketing/staff/#op-get-api-v1-orgs-org-slug-staff-marketing-ads)
- `DELETE /api/v1/orgs/{org_slug}/staff/marketing/ads/connections/{connection_id}`: Disconnect one ad account (https://www.coritan.com/docs/api/reference/organizations/org-staff-marketing/staff/#op-delete-api-v1-orgs-org-slug-staff-marketing-ads-connections-connection-id)
- `POST /api/v1/orgs/{org_slug}/staff/marketing/ads/connections/{connection_id}/sync`: Read one ad account now (https://www.coritan.com/docs/api/reference/organizations/org-staff-marketing/staff/#op-post-api-v1-orgs-org-slug-staff-marketing-ads-connections-connection-id-sync)
- `GET /api/v1/orgs/{org_slug}/staff/marketing/ads/return`: Get ad return (https://www.coritan.com/docs/api/reference/organizations/org-staff-marketing/staff/#op-get-api-v1-orgs-org-slug-staff-marketing-ads-return)
- `GET /api/v1/orgs/{org_slug}/staff/marketing/ads/spend`: What was spent, grouped by platform, campaign or day (https://www.coritan.com/docs/api/reference/organizations/org-staff-marketing/staff/#op-get-api-v1-orgs-org-slug-staff-marketing-ads-spend)
- `GET /api/v1/orgs/{org_slug}/staff/marketing/ads/spend/manual`: Spend entered by hand, newest first (https://www.coritan.com/docs/api/reference/organizations/org-staff-marketing/staff/#op-get-api-v1-orgs-org-slug-staff-marketing-ads-spend-manual)
- `POST /api/v1/orgs/{org_slug}/staff/marketing/ads/spend/manual`: Enter spend for a channel that has no connection (https://www.coritan.com/docs/api/reference/organizations/org-staff-marketing/staff/#op-post-api-v1-orgs-org-slug-staff-marketing-ads-spend-manual)
- `DELETE /api/v1/orgs/{org_slug}/staff/marketing/ads/spend/manual/{entry_id}`: Remove an entry of spend entered by hand (https://www.coritan.com/docs/api/reference/organizations/org-staff-marketing/staff/#op-delete-api-v1-orgs-org-slug-staff-marketing-ads-spend-manual-entry-id)
- `POST /api/v1/orgs/{org_slug}/staff/marketing/ads/{platform}/accounts`: Pick which of the platform's accounts to read (https://www.coritan.com/docs/api/reference/organizations/org-staff-marketing/staff/#op-post-api-v1-orgs-org-slug-staff-marketing-ads-platform-accounts)
- `POST /api/v1/orgs/{org_slug}/staff/marketing/ads/{platform}/connect`: Start signing in to an ad platform (https://www.coritan.com/docs/api/reference/organizations/org-staff-marketing/staff/#op-post-api-v1-orgs-org-slug-staff-marketing-ads-platform-connect)
