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.
| Prefix | Meaning |
|---|---|
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.
| Scope | Grants |
|---|---|
sending | Submit, cancel, resend and pre-flight messages, and upload attachments |
emails:read | Read messages and their events |
domains:manage | Add, verify, configure and remove sending domains |
contacts:manage | Read and write contacts and tags |
webhooks:manage | Create and edit webhook endpoints, read and replay deliveries |
suppressions:read | Read the suppression list |
suppressions:manage | Add and remove suppressions, and read them |
templates:read | Read templates and render them |
templates:manage | Create, edit, publish and delete templates, and read them |
inbound:read | Read received messages, including their raw content |
inbound:manage | Release quarantined mail and delete received messages, and read them |
broadcasts:read | List and read broadcasts |
broadcasts:manage | Create, edit and archive drafts, and read them |
broadcasts:send | Send, test and cancel broadcasts, and read them |
analytics:read | Read aggregate reporting |
api-keys:manage | Create, 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.
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.