Skip to main content

Authentication

Every request carries one header:

Authorization: Bearer tix_live_...

There is no other authentication mechanism on the API. Keys are created in the dashboard under API Keys & SMTP, or through the API itself with a key holding api-keys:manage.

Reading a key​

The prefix tells you which environment a key belongs to.

PrefixMeaning
tix_live_Sends real mail and consumes quota
tix_test_Simulated only, see Test mode

The prefix is checked against the key, so a live secret presented with a test prefix is rejected with authentication_failed. You cannot make a key behave differently by editing its prefix.

Scopes​

A key grants only what it was created with. A request to a route the key does not cover returns insufficient_scope naming the scope it needed.

ScopeGrants
sendingSubmit, cancel, resend and pre-flight messages, and upload attachments
emails:readRead messages and their events
domains:manageAdd, verify, configure and remove sending domains
contacts:manageRead and write contacts and tags
webhooks:manageCreate and edit webhook endpoints, read and replay deliveries
suppressions:readRead the suppression list
suppressions:manageAdd and remove suppressions, and read them
templates:readRead templates and render them
templates:manageCreate, edit, publish and delete templates, and read them
inbound:readRead received messages, including their raw content
inbound:manageRelease quarantined mail and delete received messages, and read them
broadcasts:readList and read broadcasts
broadcasts:manageCreate, edit and archive drafts, and read them
broadcasts:sendSend, test and cancel broadcasts, and read them
analytics:readRead aggregate reporting
api-keys:manageCreate, edit and revoke API keys
*Everything, including scopes added later

*:manage includes the matching *:read, so a key with suppressions:manage can also list suppressions.

broadcasts:send is the exception. It includes broadcasts:read but not broadcasts:manage, so a key that triggers pre-approved broadcasts cannot author new ones or archive live drafts. See Broadcasts.

warning

api-keys:manage can create and manage credentials. Give it only to a service that needs that access. A key created through the API cannot receive scopes broader than its parent key, including domain restrictions. A test key can create only test keys.

Domain scoping​

Three scopes can be narrowed to particular domains: sending, emails:read and domains:manage. A key scoped that way can send from those domains and no others, which is how you give a subsystem the ability to send transactional mail without also letting it send as your marketing domain.

A request outside the allowed set returns domain_scope_restricted.

IP allow-lists​

A key can be limited to a set of CIDR ranges. Requests from anywhere else are rejected with api_key_ip_restricted, which turns a stolen token into a much smaller problem.

Leave the list empty and the key works from anywhere. Only set it when your sender's egress address is genuinely stable, because a cloud provider rotating your NAT address will take your sending down.

Expiry​

Every key has an expiry date and there is no way to create one without. This is deliberate: a credential nobody ever rotates is one nobody ever notices has leaked.

An expired key returns api_key_expired rather than a generic authentication failure, so it is obvious from the response what happened.

Rotate in this order: create the replacement, deploy it, confirm it is being used from its request count, then delete the old one. Deleting first means an outage that lasts as long as your deploy.

If a key leaks​

Delete it. There is no rotation and no grace period, because a leaked key is valid until it stops existing. A key that has ever been in a repository, a build log or a support ticket should be treated as public.