HomeDocsREST API Reference

REST API Reference

The SES Mailbox API lets you add and update contacts, trigger transactional emails, and manage suppressions programmatically. All endpoints require authentication with an API key.

API access is available on the Pro plan. Generate your API key in Settings → API Keys → Create key.

Authentication

Pass your API key as a Bearer token in the Authorization header on every request:

Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxxxxxx

Base URL

https://api.sesmailbox.com/v1

Response format

All responses are JSON. Successful responses return a 200 or 201 status. Errors return a 4xx or 5xx with an error field explaining the problem.

# Success
{ "id": "msg_01abc...", "status": "queued" }

# Error
{ "error": "Invalid API key", "code": "auth_invalid" }

Send a transactional email

Send a single email to one or more recipients. Useful for transactional messages (welcome emails, password resets, notifications) triggered by your application.

POST /v1/send

{
  "to": ["ada@example.com"],
  "from": "noreply@yourcompany.com",
  "from_name": "Acme Corp",
  "subject": "Welcome to Acme, {{first_name}}!",
  "html": "<h1>Hi {{first_name}},</h1><p>Your account is ready.</p>",
  "text": "Hi {{first_name}}, your account is ready.",
  "variables": {
    "first_name": "Ada"
  }
}

Request fields

FieldTypeRequiredDescription
tostring[]YesRecipient email addresses (max 50)
fromstringYesSender address — must be a verified domain
from_namestringNoSender display name
subjectstringYesEmail subject. Supports {{variable}} syntax
htmlstringYes*HTML body. *Required if text not provided
textstringNoPlain-text body (auto-generated from HTML if omitted)
variablesobjectNoKey-value pairs for {{variable}} substitution
reply_tostringNoReply-to address
headersobjectNoCustom email headers

Example response

{
  "id": "msg_01j9k2m...",
  "status": "queued",
  "recipient_count": 1,
  "created_at": "2026-05-23T10:41:00Z"
}

Contacts API

Add or update a contact

POST /v1/contacts

{
  "email": "grace@example.com",
  "first_name": "Grace",
  "last_name": "Hopper",
  "fields": {
    "plan": "pro",
    "company": "Navy Labs"
  }
}

If a contact with the same email already exists, this updates their fields. If they don't exist, it creates them. Subscription status is preserved on update unless you pass "subscribed": false explicitly.

Get a contact

GET /v1/contacts/{email}

# Example
GET /v1/contacts/grace%40example.com

Delete a contact

DELETE /v1/contacts/{email}

Deleting a contact removes them from your contacts list but does not add them to your suppression list. To prevent future sends, use the unsubscribe endpoint instead.

Unsubscribe a contact

POST /v1/contacts/{email}/unsubscribe

Marks the contact as unsubscribed and adds them to the suppression list. They will not receive any future campaigns.

Suppressions API

Add to suppression list

POST /v1/suppressions

{
  "email": "do-not-email@example.com",
  "reason": "unsubscribed"
}

Valid reasons: unsubscribed, bounced, complained, other.

Check suppression status

GET /v1/suppressions/{email}

# Response if suppressed
{ "email": "do-not-email@example.com", "reason": "unsubscribed", "created_at": "..." }

# Response if not suppressed
{ "error": "Not found", "code": "not_found" }  // 404

Remove from suppression list

DELETE /v1/suppressions/{email}

Error codes

HTTP statusCodeMeaning
401auth_missingNo Authorization header
401auth_invalidAPI key is invalid or revoked
403plan_requiredThis endpoint requires Pro plan
404not_foundResource does not exist
422validation_errorRequest body has missing or invalid fields — details in errors array
429rate_limitedToo many requests — retry after the seconds specified in Retry-After header
500server_errorInternal error — contact support if this persists

Rate limits

API requests are rate-limited per API key:

  • Send endpoint: 100 requests per minute
  • All other endpoints: 300 requests per minute

When rate-limited, the response includes a Retry-After header with the number of seconds to wait before retrying.