Skip to content

Authentication

All API requests require authentication via an API key. Keys can be created in your workspace settings.

API Key Format

TopMail API keys use a prefix to indicate their type:

PrefixTypeDescription
tm_live_LiveProduction key. Sends real emails and modifies live data.
tm_test_SandboxTest key. All API calls work normally but email sends return mock results.

Sending Requests

Include your API key in the Authorization header using the Bearer scheme:

curl https://api.topmail.so/api/v1/contacts \
-H "Authorization: Bearer tm_live_abc123"

A legacy header is also supported: X-API-Key: tm_live_.... We recommend using the Authorization header for new integrations.

Rate Limiting

API requests are rate limited per API key using a sliding window. Rate limit details are returned in response headers:

NameTypeRequiredDescription
X-RateLimit-RemainingnumberOptionalNumber of requests remaining in the current window.
X-RateLimit-ResetISO 8601OptionalTimestamp when the rate limit window resets.
Retry-AfternumberOptionalSeconds to wait before retrying (only present on 429 responses).

When you exceed the rate limit, you will receive a 429 Too Many Requests response:

Permissions

API keys have granular permissions per resource. Each resource can be granted read, write, and delete access independently.

ResourceAvailable Permissions
contactsread, write, delete
listsread, write, delete
campaignsread, write
templatesread, write
flowsread, write
analyticsread
formsread, write
conversionsread, write

If a key lacks the required permission, the API returns a 403 Forbidden response:

Idempotency Keys

For mutating endpoints (like sending emails), you can include an Idempotency-Key header to prevent duplicate operations from network retries.

curl -X POST https://api.topmail.so/api/v1/email/send \
-H "Authorization: Bearer tm_live_abc123" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: unique-request-id-123" \
-d '{"to": "user@example.com", "subject": "Hello", "html": "<p>Hi</p>"}'

If a request with the same idempotency key has already been processed, the API returns the cached response with an X-Idempotency-Status: cached header. If a request with the same key but a different body is sent, you will receive a 409 Conflict response.

Request IDs

Every API response includes an X-Request-Id header. You can also pass your own via the request header to correlate logs. Include this ID when contacting support.

Developer Docs - TopMail