Authentication and API keys
Every request to the API carries an API key as a bearer token:
curl https://api.postilio.eu/v1/domains \
-H "Authorization: Bearer $POSTILIO_KEY"
SMTP uses the same keys: user name apikey, the key as the password (see Sending email).
Keys
A key belongs to one project and works only on that project's domains, messages, suppressions and webhooks. Create keys in the portal under Keys & SMTP: Owners and Admins of the organization in every project, Developers in the projects they have access to.
- A key is
pk_live_orpk_test_followed by 32 letters and digits. - It is shown once. Postilio stores only a hash of it; the portal shows the first characters, so you can tell keys apart. Lost a key? Revoke it and create a new one.
- Revoking takes effect at once. An SMTP connection that logged in with the key before gets its next message refused.
- The portal shows when a key was last used (to the minute).
Live and test keys
| What | Live key pk_live_… | Test key pk_test_… |
|---|---|---|
| Checks (sender domain, restrictions, suppression list, validation) | yes | the same |
| Delivers mail | yes | never: every message gets simulated events at once |
| Sandbox limits | yes, while the organization is in the sandbox | no |
| Counts as usage | yes | no |
| Scopes | any | emails:send and emails:read at most |
Test and live messages are kept apart: a test key finds only test messages and a live key only live ones; the other kind answers 404. Webhook endpoints have a mode too: a test endpoint gets the events of test messages only. The simulator addresses are in Suppressions and test mode.
Scopes
A key has one or more scopes. A call outside them answers 403 with {"error": "insufficient_scope"}.
| Scope | Allows |
|---|---|
emails:send | POST /v1/emails, and SMTP submission |
emails:read | GET /v1/emails/{id} |
domains:manage | GET /v1/domains, POST /v1/domains, GET /v1/domains/{id}, DELETE /v1/domains/{id}, POST /v1/domains/{id}/check |
suppressions:manage | GET /v1/suppressions, POST /v1/suppressions, DELETE /v1/suppressions/{id} |
webhooks:manage | everything under /v1/webhooks |
Give each key only what it needs: the key on a web server that sends sign-in codes needs emails:send, nothing more.
Restrictions
Two optional limits per key, set when you create it (at most 20 entries each):
- Sending domains. The key sends only from these domains of the project. A message from another domain answers
422with{"error": "sender_domain_not_allowed_for_key"}; over SMTP theMAIL FROMis refused with553 5.7.1 sender_domain_not_allowed_for_key. - Networks. The key works only from these networks: CIDR (
192.0.2.0/24,2001:db8::/32) or a single address. The address must be the network's own (10.0.0.0/8, not10.0.0.1/8). From anywhere else the answer is403with{"error": "client_ip_not_allowed"}, and over SMTP the login fails with535 5.7.1 client_ip_not_allowed.
Without restrictions a key sends from every verified domain of the project, from anywhere.
Errors
| Status | error | Why |
|---|---|---|
401 | invalid_api_key | no Authorization: Bearer pk_… header, or a key that does not exist or was revoked |
403 | insufficient_scope | the key lacks the scope this call needs |
403 | client_ip_not_allowed | the key is restricted to networks this request does not come from |
A key of an organization that is being deleted stops working too, until the deletion is cancelled.