Skip to main content
Every request carries an API key as a Bearer token:
The key identifies both the caller and the workspace - you never put an organization id in the path. A missing or revoked key returns 401.

Scopes

Keys are least-privilege: each carries only the scopes it needs, and every route declares the one scope it requires. A key missing a required scope returns 403.

Granular scopes

Every scope maps to a live capability - there are no scopes without an endpoint behind them.

Wildcard scopes

A key can also hold a wildcard that covers many scopes at once. A route always requires a granular scope; any wildcard that covers it is accepted just the same. For example, a route requiring emails:read accepts any of emails:read, emails:all, all:read, or all:all. all:read never covers a write, send, or lifecycle scope - those need the matching *:write / *:all / all:all.
apikeys:manage is opt-in and never covered by any wildcard (not even all:all). It is grantable only from the dashboard - never delegable through the API - and a key holding it can mint only keys whose scopes are a subset of its own, so there is no privilege escalation.

Rate limits

The API is rate-limited per workspace - the limit is shared across every API key in the workspace, so minting extra keys does not raise your ceiling. Exceed the limit and you get 429 with a Retry-After header (seconds) and the standard error envelope:
Watch X-RateLimit-Remaining and slow down before you hit 0. On a 429, wait Retry-After seconds before retrying; back off exponentially on repeated hits. For bulk lead loads, batch and space your calls rather than firing them all at once.

Managing keys

Create your first key in the dashboard (Settings → API Keys), where the full secret is shown once. After that you can rotate keys programmatically with the API Keys endpoints using a key that has apikeys:manage.

Related topics

Analytics