API Reference

A REST API for creating ephemeral inboxes and retrieving emails. Designed to be called from test scripts, not browsers.

Introduction

AssertMail gives you real email addresses you can create and destroy via API. The typical pattern in an integration test is:

  1. Create an inbox — get back an email address.
  2. Feed that address into your app and trigger the email send.
  3. Long-poll the inbox until the email arrives (or timeout).
  4. Assert on subject, body, links, whatever you care about.

Inboxes expire automatically at their TTL, so there's no cleanup to manage between runs. Parallel test workers can each create their own inbox with no coordination needed.

Authentication

All API requests require an API key passed in the Authorization header as a Bearer token. Create and manage your keys in the dashboard.

Authorization: Bearer j8Kp3mN9xR2vL5tQ7wY0aB4cD6eF1gH_zX

Key format

API keys are 43-character base64url strings generated when you create a key in the dashboard.

Keep keys secret

API keys are long-lived. Don't commit them to source control — use environment variables or a secrets manager and inject them into your test environment at runtime.

Quick start

The full flow as a shell script — create an inbox, trigger your app, poll for the result.

# 1. Create an inbox (TTL 5 minutes)
$ INBOX=$(curl -sX POST https://assertmail.com/api/inboxes \
    -H "Authorization: Bearer $ASSERTMAIL_KEY" \
    -H "Content-Type: application/json" \
    -d '{"ttlSeconds":300}')

$ EMAIL=$(echo $INBOX | jq -r '.emailAddress')
$ ID=$(echo $INBOX | jq -r '.id')

# 2. Trigger your app's send flow
$ curl -sX POST https://yourapp.test/api/register \
    -d "{\"email\": \"$EMAIL\"}"

# 3. Long-poll until the email arrives (max 25s)
$ curl -s "https://assertmail.com/api/inboxes/$ID/emails?wait=25" \
    -H "Authorization: Bearer $ASSERTMAIL_KEY" \
  | jq '.emails[0].subject'

Base URL

All endpoints are relative to:

https://assertmail.com/api

All requests and responses use JSON. Set Content-Type: application/json on requests with a body.

Create inbox

POST /inboxes API key required

Creates a new inbox and returns its email address. The inbox and all its emails are automatically deleted when the TTL expires.

Request body

All fields are optional. Send an empty body or omit it entirely to use defaults.

Field Type Description
ttlSeconds integer optional Lifetime in seconds. Capped at your plan maximum (86400 for 24h). Defaults to the plan maximum.
allowedSenders string[] optional If set, only emails matching these rules are delivered. Each entry can be a full address (noreply@yourapp.com) or a domain (@yourapp.com or yourapp.com).

Response — 201

Field Type Description
id string Inbox ID (ULID). Pass this to subsequent requests.
emailAddress string The full inbox email address. Send email here.
allowedSenders string[] Echo of the request field, empty array if not set.
ttl integer Unix timestamp of when the inbox expires.

Example

$ curl -sX POST https://assertmail.com/api/inboxes \
    -H "Authorization: Bearer $ASSERTMAIL_KEY" \
    -H "Content-Type: application/json" \
    -d '{"ttlSeconds": 120, "allowedSenders": ["noreply@yourapp.com", "@yourapp.com"]}'
{
  "id":             "01JXKP7N3MQVW4RBSTDYFZ8EG2",
  "emailAddress":   "illustration-1234@in.assertmail.com",
  "allowedSenders": ["noreply@yourapp.com", "@yourapp.com"],
  "ttl":            1751000520
}

Delete inbox

DELETE /inboxes/{id} API key required

Immediately deletes the inbox and all its emails. Useful for explicit cleanup in teardown, though most test suites can rely on TTL expiry instead.

Response — 204

No body.

Example

$ curl -sX DELETE https://assertmail.com/api/inboxes/01JXKP7N3MQVW4RBSTDYFZ8EG2 \
    -H "Authorization: Bearer $ASSERTMAIL_KEY"

List emails

GET /inboxes/{id}/emails API key required

Returns emails in the inbox. Pass ?wait=N to long-poll: the request blocks until an email arrives or N seconds pass, whichever comes first.

Query parameters

Parameter Type Description
wait integer optional Seconds to long-poll. Range 0–25. Default: 0 (no waiting — returns immediately with whatever's in the inbox).
after string optional Email ID cursor. Only returns emails received after this ID. Used for continuous polling — see below.

Response — 200

Field Type Description
emails[].id string Email ID. Pass as after cursor in the next call.
emails[].sender object | null Parsed sender from the From header, or null if absent.
emails[].sender.address string Sender email address.
emails[].sender.name string | null Display name from the From header, if present.
emails[].subject string Email subject line.
emails[].html string | null HTML body, if the email included one.
emails[].plaintext string | null Plain text body, if present.
emails[].truncated boolean true if the email exceeded 10KB and was truncated.
emails[].attachmentNames string[] Names of any attachments. Attachment content is not returned.

Example — wait for the first email

$ curl -s "https://assertmail.com/api/inboxes/$ID/emails?wait=25" \
    -H "Authorization: Bearer $ASSERTMAIL_KEY"
{
  "emails": [{
    "id":              "01JXKP8R2A4BNCVTSFGZ9MW1HK",
    "sender":         { "address": "noreply@yourapp.com", "name": "Your App" },
    "subject":        "Confirm your email address",
    "html":           "<p>Click <a href=\"...\">here</a> to confirm.</p>",
    "plaintext":     "Click the link to confirm: https://...",
    "truncated":     false,
    "attachmentNames": []
  }]
}

Continuous polling

If your test expects multiple emails, use the after cursor to only receive new ones. Take the id of the last email you processed and pass it back on the next call.

# First call — get everything currently in the inbox
$ RESULT=$(curl -s "https://assertmail.com/api/inboxes/$ID/emails?wait=25" \
    -H "Authorization: Bearer $ASSERTMAIL_KEY")

# Save the last email ID as a cursor
$ CURSOR=$(echo $RESULT | jq -r '.emails[-1].id // empty')

# Subsequent calls — only get emails received after the cursor
$ curl -s "https://assertmail.com/api/inboxes/$ID/emails?wait=25&after=$CURSOR" \
    -H "Authorization: Bearer $ASSERTMAIL_KEY"

Error codes

Errors return JSON with an error field describing what went wrong.

{
  "error": "Inbox not found"
}
Status Meaning
400 Bad request — missing or invalid field in the request body or query string.
401 Unauthorized — the Authorization header is missing or the key is invalid.
403 Forbidden — your org has no inbox allocation (no active subscription).
404 Not found — the inbox doesn't exist or has expired.
500 Internal server error — something went wrong on our end. Try again; if it persists, let us know.