Docs/Authentication
Getting Started

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/.

HTTP header
X-API-Key: sf_live_abc12345.XYZ_your_secret_here
Never expose API keys in client-side code. Keys must only be used from your server or backend. If a key is exposed, revoke it immediately from the dashboard.

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:

Key anatomy
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.

The 2-minute revocation window exists because we cache key hashes for performance. In practice, most revocations propagate within seconds. Plan for up to 2 minutes if timing is critical.

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.

PlanMonthly emails
Starter50 (BYOC)
BYOCUnlimited*
Growth25,000
Pro100,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.

401 Unauthorized
{
  "detail": "Authentication credentials were not provided."
}

Best practices

PracticeWhy
One key per environmentRotate or revoke a single env's key without affecting others.
Use environment variablesNever hardcode keys in source code or config files.
Set expiry dates for short-lived tasksAutomation keys have a known lifespan - enforce it.
Revoke immediately on exposureIf a key leaks, there is no grace period - revoke at once.
Monitor for 401 spikesA sudden spike may indicate a key is being probed.