Skip to main content
A scoped API key is a SocialAPI API key restricted to some actions (its scopes), some brands, or both. A key with no restriction has full access: every action on every brand of your SocialAPI account. Two uses are common. A bot that only answers comments holds a key with inbox:read and inbox:write, and nothing else. An agency gives each client’s automation a key limited to that client’s brand, so a leaked key cannot reach another client.
An empty scopes array grants every scope, and an empty brand_ids array grants every brand. A key is restricted when at least one of the two arrays holds a value.

Create a scoped key

Pass scopes, brand_ids, or both to POST /v1/keys:
Response (HTTP 201):
raw_key is shown once. Creating keys needs full access (a full-access key, an OAuth access token, or the dashboard), so a scoped key can never create a key with more access than it has.
  • An unknown scope returns 400 validation.scope_invalid, and the message names it.
  • A brand ID that does not exist, is not a UUID, or belongs to another SocialAPI account returns 400 validation.brand_invalid.

Scopes

Scopes have the form resource:action. A scope-restricted key can perform an operation only when it holds the operation’s scope. GET /v1/keys/scopes returns this catalog with a group and a description per scope, so your app can render a scope picker from it:
Response (HTTP 200, first entry shown):

Automations need their actions’ scopes

An Automation carries out its actions long after the request that configured it. A key can configure only actions it can perform itself: besides automations:write, it needs the scope of each action. A key that holds only automations:write and creates an Automation with a send_dm action gets 403 auth.insufficient_scope with meta.required_scope set to dms:send. The check runs on every change that can make the Automation send more: creating it, resuming it, or changing its steps, post_ids, or once_per_person. Renaming, pausing, and deleting need only automations:write, so a key can always stop an Automation it can see.

Always available

Any valid key can call these endpoints, whatever its scopes and brands:
  • GET /v1/users/me
  • GET /v1/usage
  • GET /v1/billing/plans
  • GET /v1/media/storage
  • GET /v1/posts/validate
  • GET /v1/keys/scopes
  • GET /v1/webhooks/events
  • GET /v1/announcements and POST /v1/announcements/{id}/seen

Full-access operations

A restricted key can never perform these operations. They need full access: a full-access key, an OAuth access token, or the dashboard.
  • Managing API keys: list, create, edit, rotate, and revoke, including the key itself
  • Editing or deleting your SocialAPI account (PATCH and DELETE /v1/users/me)
  • Creating, editing, or deleting brands. Listing brands needs accounts:read
  • Listing, creating, and revoking invites
A key that can create keys can create itself an unrestricted one, so every key operation needs full access.
A restricted key cannot rotate or revoke itself. Rotate or revoke a leaked scoped key with a full-access key or from the dashboard.

Brand restrictions

A brand-restricted key behaves as if its brands are the only brands in your SocialAPI account. It never learns that other resources exist:
  • Reading an account, brand, or other resource outside the key’s brands returns the same 404 as a resource that does not exist, for example 404 account.not_found or 404 brand.not_found.
  • Lists (accounts, brands, posts, conversations, comments, mentions, Automations) return only resources inside the key’s brands. GET /v1/brands returns only the key’s brands. An Automation belongs to the brand of its account.
  • Connecting an account needs a brand_id from the key’s list. A connection without brand_id creates a new brand that the key cannot see. See Connect a social account.

Posts

A post belongs to the brands of its target accounts:
  • Read. A post is visible when at least one of its target accounts is in the key’s brands. A draft with no target is not visible to a brand-restricted key. A post the key cannot see returns 404 resource.not_found.
  • Change (edit, publish, retry, unpublish, delete). Every target account must be in the key’s brands. Otherwise the post returns 404 resource.not_found.
  • Create or retarget. Every account in the request must be in the key’s brands. Otherwise the request returns 404 account.not_found.

Media is shared

media:read and media:write work on the whole media library, whatever the key’s brands. A file in the library reaches a platform only when a post uses it, and creating or changing a post is limited to the key’s brands.

Webhooks and analytics need every brand

Webhook endpoints, their deliveries, the events log, and exports cover every brand of your SocialAPI account. A brand-restricted key is refused webhooks:manage and analytics:read operations even when it holds the scope, with 403 auth.insufficient_scope. A key restricted only by scopes can hold and use them.

Deleting a brand never widens a key

When you delete a brand that a key lists in brand_ids, its ID stays in the array and matches nothing. The key does not become unrestricted, even when that brand was its only one.

Read a key’s restrictions

GET /v1/keys returns scopes and brand_ids on every key. Both arrays are always present, and two empty arrays mean full access:

Change the restrictions on a key

PATCH /v1/keys/{id} replaces the key’s name, scopes, and brand_ids together. The secret does not change, so services using the key keep working:
Response (HTTP 200):
Send all three fields. name is required, or the request returns 400 validation.field_required. A scopes or brand_ids you leave out is saved as empty, which removes that restriction.
Editing a key needs full access. Editing a revoked key, or an ID that is not one of your keys, returns 404 resource.not_found. To issue a new secret with the same restrictions, rotate the key: see Authentication.

Errors

A restricted key that is refused gets 403 auth.insufficient_scope. meta.required_scope tells you what is missing:
  • The key lacks the scope. meta.required_scope names the missing scope.
  • A webhooks:manage or analytics:read operation with a brand-restricted key. meta.required_scope names that scope. Brand-restricted keys are refused it even when they hold it.
  • A full-access operation. meta.required_scope is absent.
  • An operation no scope covers. meta.required_scope is absent.
A resource outside the key’s brands returns its ordinary 404, never a 403. Full-access keys and OAuth 2.1 access tokens are never restricted.
Last modified on October 19, 2026