Authentication
All API requests are authenticated with an API key passed in the X-API-Key request header. Keys are SHA-512 hashed before storage - the raw secret is shown exactly once at creation.
Sending your key
Pass your API key in the X-API-Key header on every request to /api/send/.
X-API-Key: sf_live_abc12345.XYZ_your_secret_here
Security model
SHA-512 hashing
When you create a key, we generate a random secret, show it to you once, then store only its SHA-512 hash. On each request, we hash the incoming key and compare against the stored hash using a constant-time comparison. This means:
- ✓ A database breach cannot expose your raw secrets
- ✓ Lookup is fast - a prefix index (first 8 chars) narrows the DB query
- ✕ Lost keys cannot be recovered - generate a new one instead
Key structure
Every key has two parts separated by a dot:
abc12345.XYZ_32_random_chars_here_XXXXXXXXXXXXXXXX ┗━━━━━━┛ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ prefix secret (32-char random, never stored)
The prefix (8 characters) is stored in plaintext and displayed in your dashboard - it helps you identify which key is which. The secret is hashed with SHA-512 and never stored in recoverable form.
Expiry dates
When creating a key you can set an optional expiry date. After the expiry, the key is automatically rejected with a 401 Unauthorized. Expired keys are not automatically deleted - you can see them in your dashboard.
Revocation
Revoke any key instantly from Dashboard → API Keys. Revocation is propagated within ~2 minutes via a Redis cache. Once revoked, a key can never be un-revoked - this is enforced at the database level.
Rate limiting
Requests are rate-limited per API key. The default limit is 60 requests per minute for all plans.
When you exceed the limit, the API returns 429 Too Many Requests with a standard error body. Back off and retry after 1–5 seconds.
| Plan | Monthly emails |
|---|---|
| Starter | 50 (BYOC) |
| BYOC | Unlimited* |
| Growth | 25,000 |
| Pro | 100,000 |
* Unlimited means no SendFleet cap - your AWS SES quota applies.
Failed authentication
Requests with a missing, invalid, or revoked key return 401 Unauthorized. Repeated failed attempts from the same IP are automatically blocked after 10 failures within 60 seconds.
{
"detail": "Authentication credentials were not provided."
}Best practices
| Practice | Why |
|---|---|
| One key per environment | Rotate or revoke a single env's key without affecting others. |
| Use environment variables | Never hardcode keys in source code or config files. |
| Set expiry dates for short-lived tasks | Automation keys have a known lifespan - enforce it. |
| Revoke immediately on exposure | If a key leaks, there is no grace period - revoke at once. |
| Monitor for 401 spikes | A sudden spike may indicate a key is being probed. |