Skip to main content

Authentication

Every request carries a bearer API key:

Authorization: Bearer mcf_74b5dd1e6a29150ab5ab6081d0b30ac043aadf7d2c948e80d330775d0b6382e8

A key looks like mcf_ followed by 64 lowercase hex characters. There is no other auth mechanism — no cookies, no OAuth, no session tokens — on this API.

Creating a key​

Keys are created in the Mocart dashboard, under Settings → API keys. The full key is shown exactly once, at creation time; Mocart stores only a hash of it afterward. Copy it somewhere safe immediately — if you lose it, revoke it and mint a new one, there is no way to retrieve it later.

Scopes​

A key carries one or more scopes, chosen when it's created:

ScopeGrants
readEvery read-plane endpoint: Catalog, Campaigns & Creatives, Deliveries, The run plane's reads are separate: they need runs:read.
runs:readThe run plane's reads: POST /runs/estimate (estimateRun) to price a run without charging for it, and the GET /runs* endpoints (listRuns, getRun, listRunItems) and GET /presets (listPresets) to poll and discover. Spends nothing. Requires read on the key.
runs:writePOST /runs (createRun) and POST /runs/{id}/stop (stopRun) — the only two operations that spend money. Implies runs:read (everything runs:write needs to read back what it created), which in turn requires read on the key.
creatives:writePATCH /creatives/{id} (updateCreative), DELETE /creatives/{id} (deleteCreative) and POST /creatives/{creativeId}/undelete (undeleteCreative) — editing, deleting and restoring creatives. Spends nothing. Implies read. See Managing creatives.
creatives:reviewPOST /creatives/{creativeId}/approve (approveCreative) and POST /creatives/{creativeId}/reject (rejectCreative) — deciding what ships. Spends nothing. Implies read. See Reviewing creatives.
assets:writePATCH /assets/{id} (updateAsset), POST /assets/{assetId}/archive (archiveAsset), POST /assets/{assetId}/unarchive (unarchiveAsset), DELETE /assets/{id} (deleteAsset) and POST /assets/{assetId}/undelete (undeleteAsset). Spends nothing. Implies read. See Managing assets.
campaigns:writeCreating, editing, deleting and restoring campaigns: POST /campaigns, PATCH /campaigns/{id}, DELETE /campaigns/{id} and POST /campaigns/{campaignId}/undelete. Spends nothing. Implies read. See Managing campaigns.

Approving or rejecting needs creatives:review, not creatives:write: "may decide what ships" and "may edit or delete creatives" are separate grants, so you can give an integration one without the other. A key that needs both carries both scopes.

In practice you mint a key with read alone (a read-only integration — reporting, syncing a catalog into another system), and add only the write scopes an integration needs: runs:write for one that generates creatives, creatives:review for one that approves or rejects them, creatives:write, assets:write or campaigns:write for one that manages those resources. There's no scope finer than that today — every read-scoped key can see every resource group.

Scopes are fixed when a key is created. There's no way to add or remove a scope on an existing key: to change what an integration can do, create a new key with the scopes you want, switch over, and revoke the old one. The Permissions column under Settings → API keys shows what each key can do.

POST /runs/estimate (estimateRun) needs runs:read — it prices a run but writes nothing, so it doesn't need runs:write. read alone does not reach the run plane.

Plans​

Create API access (minting a runs:write key, and everything that scope grants) requires a Core plan or above. A read-only key works on any plan. If your account's plan changes after a key was minted, the key's entitlement is re-checked on every request — see Errors for what that looks like when it fails.

The write scopes for creatives and assets (creatives:review, creatives:write, assets:write) need no plan beyond what a read key needs: they ride on the same API access, so any account that can read through the API can also review, edit and delete through it. campaigns:write also needs a plan that includes campaigns — without it, a campaign write answers 403 TIER_REQUIRED.

Creating or changing a campaign can also run into your plan's limits — how many campaigns you can have, and how many products one campaign can cover. See Managing campaigns.

Receiving webhooks needs a plan with the webhooks feature.

Write keys expire​

A key with any write scope — runs:write, creatives:review, creatives:write, assets:write or campaigns:write — must have an expiry, chosen when it's created: 30, 90 or 365 days, and never more than 365 days out. A read-only key may still be created without one. Once a key expires, every request made with it returns 401.

Keys that have runs:write and were created before this rule keep working without an expiry. A new runs:write key needs one.

Fourteen days before a write key expires, the account owner gets an email naming the key and its expiry date. That's the cue to rotate — see below. An expiry can't be extended; the replacement is a new key.

401 vs 403​

StatusMeaningWhat to do
401The token itself is missing, malformed, unknown, revoked, or expired — or the account it belongs to no longer has the plan the operation requires.Nothing about the request will fix a 401. Mint a new key, or have the account owner restore the plan.
403The token is valid, but doesn't carry the scope this operation needs (code: "API_TOKEN_SCOPE_DENIED").Mint or request a key with the right scope. Don't retry the same key with a different request body — the body isn't the problem.

Neither status leaks which one is true when the underlying reason is a lapsed plan versus a missing scope versus a bad token — the response body is deliberately uniform. React to the HTTP status, not to guessed detail text.

Rotating and revoking keys​

Create a new key, switch your integration over to it, then revoke the old one from the dashboard — there's no atomic "rotate in place." A revoked key starts failing with 401 on its very next request; there's no grace period, so revoke only after you've confirmed the new key works.

The same sequence is how you replace a write key before it expires: create the new key with the same scopes and a fresh expiry, switch over, then revoke the old one — ideally when the 14-day reminder arrives, not on the day the key stops working.

Keep keys server-side​

A key that can create runs can spend credits, a key that can review creatives decides what your brand approves, and a key with a write scope can edit or delete your creatives, assets and campaigns. Never embed a key in a client-side app, a mobile binary, or a public repository — treat it like any other server-side secret (an environment variable, a secrets manager), and if one leaks, revoke it immediately from the dashboard.