First 200 users get the Growth plan for $19/mo.

Claim
Browse the docs

Start

Authentication

Bearer keys, the eight scopes, expiry, and the status codes a bad credential produces.

The header

Every request carries the key as a bearer token. There is no other way to authenticate on /public/v1.

Authorization: Bearer sk_live_YOUR_KEY

Keys are created in Settings > API Keys & MCP. Each key is bound to the workspace it was created in; the API never accepts a workspace parameter to move a key elsewhere.

Scopes

A key carries a list of scopes chosen when it is created. Each route declares the scope it needs; a call without it answers 403 with code SCOPE_MISSING. Scopes are all-or-nothing per route: a route that lists two needs both.

ScopeUnlocks
posts:readRead posts and their per-account delivery log
posts:writeCreate, edit, schedule, cancel and publish posts
connections:readList connected social accounts and their token health
media:writeUpload media and ingest media by URL
analytics:readRead ad accounts, metrics and the landing-page crawl
workflows:runTrigger workflows and read their runs
webhooks:manageRegister and manage outbound webhooks
workspaces:manageCreate client workspaces, mint their keys and hosted connect links

On the MCP server the same scopes decide which tools tools/list returns. A tool outside the key's scopes is not listed and cannot be called.

Keys created before scopes were enforced carry an empty scope list and keep full access. A key created in the app today always carries an explicit list.

Expiry and revocation

A key may carry an expiresAt. Past that instant it answers 401 like a key that never existed. Revoking a key in the app has the same effect immediately. There is no refresh flow: make a new key.

Status codes

StatusBodyMeaning
401{ "statusCode": 401, "message": "Missing API key" }No Authorization: Bearer sk_live_... header.
401{ "statusCode": 401, "message": "Invalid API key" }Unknown, revoked or expired key.
402flat bodyThe workspace's plan does not include API access. Keys work on Growth and Scale.
403{ "error": { "code": "SCOPE_MISSING" } }The key lacks the scope this route needs.
429flat body with retryAfterSecondsRate limit, see Rate limits.

Managed workspaces

An agency key may act for a client workspace it created over POST /workspaces by sending x-overads-workspace: <workspace id> on any public route or MCP call. The swap happens before any other check, so scopes, rate limits and idempotency all apply to the client workspace. Only a direct child counts: a managed workspace cannot itself manage others.

Authorization: Bearer sk_live_AGENCY_KEY
x-overads-workspace: c0ff3e00-1a2b-4c3d-8e4f-5a6b7c8d9e0f
CaseAnswer
Header names a workspace the key's workspace managesThe call acts on that workspace.
Header names the key's own workspaceSame as no header.
Header names any other workspace403 with WORKSPACE_NOT_MANAGED.
Header is not a single uuid400 with WORKSPACE_NOT_MANAGED and field: "x-overads-workspace".
Header on /workspaces/* routes400 with WORKSPACE_HEADER_NOT_ALLOWED; those routes always act on the agency.

The alternative is a key that belongs to the client workspace, minted with POST /workspaces/:id/api-keys; it needs no header. The whole flow is on Managed workspaces.