Skip to main content

Scopes

Each API key holds a set of Scopes, chosen under What this key may do when you create it. Every route needs exactly one Scope, and a key without it is refused.

ScopeIn the appLets the key
events:writeWrite eventsRecord Events against Contacts and organizations that already exist.
contacts:writeWrite contactsCreate and update Contacts by external ID or email address.
contacts:readRead contactsLook up a single Contact and read the fields stored on it.
contacts:exportExport contact dataDownload everything stored about one Contact, for a GDPR Article 15 request.
contacts:eraseErase contactsErase a Contact's personal data, for a GDPR Article 17 request.

Each route in the API reference names the Scope it needs.

Why a new key can only write​

A new key starts with events:write and contacts:write and nothing else. That is all a typical integration needs: it tells Throughline what happened and who it happened to, and never reads anything back.

A key that can only write is a small loss if it leaks. Whoever holds it can add noise, but cannot read your Contacts. A key that can read is a different matter: external IDs are usually sequential, so a leaked key with contacts:read can walk your whole contact database one ID at a time.

So grant the other three one at a time, and only to the tooling that needs them:

  • contacts:read to a service that has to look a Contact up.
  • contacts:export to whatever answers data access requests. It returns a person's complete personal data.
  • contacts:erase to whatever answers deletion requests. Erasure cannot be undone.

When a Scope is missing​

The request is refused with 403 and the code insufficient_scope, and the message names the Scope the key lacks:

{ "code": "insufficient_scope", "message": "This API key is missing the contacts:read scope." }

Do not retry. A key's Scopes are fixed when it is created, so the fix is a new key with the Scope added; see Rotate and revoke keys.