Authentication

Two kinds of credential, and which one a given endpoint wants.

There are two ways to authenticate, and they are not interchangeable. A session token identifies a person using the dashboard; an API key identifies a program. Sending an API key where a session token is expected fails with 401 even though the key is perfectly valid.

API keys

This is what you want for anything programmatic — sending mail, server-side integrations, background jobs. Keys look like re_… and go in the same header:

Authorization: Bearer re_your_api_key

Creating one

Create keys from API Keys in the dashboard, or with POST /api-keys. The full key is returned once, at creation, and is not recoverable afterwards — the server keeps only what it needs to verify a key, not the key itself. If you lose one, revoke it and create another.

Permissions

  • sending_access — may send email, and nothing else. The right choice for a production sending key, and the default.
  • full_access — everything the API offers: sending, reading messages and their events back, the request logs, and managing domains, templates, contacts, webhooks, segments and the rest.
A few endpoints take a dashboard session and nothing else, because they act on a person rather than an organization: signing in and changing a password, accepting an invitation, exporting or deleting the account, and managing team members and roles. There is nobody for an API key to be in those operations. Calling one with a key says so, rather than reporting the key as invalid and sending you to regenerate something that works.

A key can also be restricted to a single domain. If you send on behalf of several customers from one organization, one key per domain means a leaked key cannot be used to send as anybody else.

Never put an API key in client-side code, a mobile app, or a public repository. A browser or app bundle is readable by anyone who has it, and a key with sending_access in the wrong hands is someone sending mail as your domain. Call the API from your server.

Session tokens

The dashboard authenticates with a JSON Web Token obtained from POST /auth/login or POST /auth/register, sent the same way:

Authorization: Bearer <jwt_token>

The token carries the user id, the organization id, and a role, which is what makes role checks possible on the endpoints that need them. Roles are owner, admin and member.

Several endpoints require a session token rather than an API key — reading the domain list and the organization's settings among them. If an endpoint returns 401 Invalid token to a key you know is valid, that is usually the reason: check whether the endpoint is one of the dashboard ones.

Endpoints that need no credential

  • POST /auth/register and POST /auth/login — you cannot authenticate before you have authenticated.
  • GET /track/open/:email_id/:token and GET /track/click/:email_id/:token — opened by mail clients and by people clicking links. Neither can present a credential, which is why these carry their own signed token instead.
  • GET /health.

When it goes wrong

Both failures come back in the standard error shape, and the distinction matters:

  • 401 — no credential, or one that is not valid. The key was revoked, mistyped, or is the wrong kind for this endpoint.
  • 403 — the credential is valid but the role does not permit the action. A member trying to do something reserved for an owner or admin gets this rather than a 401.

Revoking

Revoke a key with DELETE /api-keys/:id or from the dashboard. Revocation takes effect immediately — the next request with that key is refused. Rotating a key is create-then-revoke rather than an edit, so there is always a window where both work and you can deploy without downtime.