mail.cx
登入

API

A tiny REST API for receiving mail at any address you pick. Free. No mailbox to create, no quota to track — give us a string, point your test signup at it, then read what arrives.

Base URL

https://api.mail.cx/v1

All endpoints live under /v1 and require HTTPS.

Authentication

Every request carries a token in the x-api-token header. Register an account, then create a token from Dashboard → Tokens. Tokens look like tm_live_… (72 chars).

curl https://api.mail.cx/v1/inbox/test@mail.cx \
  -H "x-api-token: tm_live_your_token_here"

Receive mail

Pick any local-part under one of the system domains (or a custom domain you own) and read the inbox. Nothing is created server-side — the SMTP gateway accepts mail for any address under a system domain, and the inbox endpoint just returns whatever is currently buffered. Mail lives for one hour.

GET
/v1/inbox/:address

Long-poll one address. Holds up to 25s for new mail, then returns 200 with results or 204 on timeout. Query params: since (cursor), count (default 1), limit (default 20, max 50), from, subject.

DELETE
/v1/inbox/:address

Clear the inbox — delete every email currently buffered for the address.

GET
/v1/email/:id

Read one full email (text body, HTML body, attachments metadata, headers).

GET
/v1/email/:id/raw

Stream the original .eml. Returns message/rfc822. 410 if the message has expired.

GET
/v1/email/:id/attachments/:index

Download one attachment by zero-based index. Returns the original Content-Type.

DELETE
/v1/email/:id

Delete a single email. 204 No Content on success.

Wait for the first email:

curl "https://api.mail.cx/v1/inbox/test@mail.cx" \
  -H "x-api-token: tm_live_your_token_here"

// → 200
{
  "emails": [
    {
      "id": "uuid",
      "from_email": "sender@example.com",
      "subject": "Verify your email",
      "preview_text": "Your code is 123456",
      "created_at": "2026-05-14T12:00:00Z"
    }
  ],
  "next_since": "1715706012"
}

Real-time push (SSE)

Server-Sent Events over plain HTTP. The browser EventSource API handles reconnection and Last-Event-ID replay automatically. Pass the token as a query parameter — EventSourcecannot set custom headers.

GET
/v1/sse/addr?address=<addr>&token=<token>

Stream events for a single address.

GET
/v1/sse/user?token=<token>

Stream events across every owned address.

const es = new EventSource(
  "https://api.mail.cx/v1/sse/user?token=tm_live_your_token_here"
);

es.addEventListener("email", (e) => {
  const data = JSON.parse(e.data);
  // { id, address, from, subject, preview }
});

Custom domains

Add a domain you own and receive mail on every address under it. Verification requires two DNS records: a TXT record at _tempmail.<domain> with value tempmail-verify=<token>, and an MX record pointing to smtp.mail.cx. Verifier polls every 5 minutes; pending domains time out after 72 hours.

POST
/v1/domains

Add a custom domain. Body: { domain }. Returns the DNS records to configure.

GET
/v1/domains

List your custom domains with verify_status (pending / verified / failed).

DELETE
/v1/domains/:id

Remove a custom domain.

GET
/v1/domain/:domain

Long-poll every address under one of your verified custom domains. Same query params as /v1/inbox/:address.

Account

GET
/v1/config

Server config: system domains list, local-part rules, default TTL, OAuth client IDs. Public — no auth. Cached 5 min.

GET
/v1/me

Long-poll across every owned address.

POST
/v1/tokens

Create a new API token. Body: { name? }. The plaintext token is returned only once.

GET
/v1/tokens

List your tokens (id, name, prefix, created_at, last_used_at).

DELETE
/v1/tokens/:id

Revoke a token. Cache invalidation is immediate.

Rate limit

10 requests per second per user, enforced by a sliding-window counter in Redis. A 429 response with { "error": "rate_limit_exceeded" } sets a Retry-After header. Long-poll concurrency is separately capped (one in-flight wait per token, ten per address) to keep one client from holding the connection pool.

Errors

Errors are JSON with a machine-readable error key. The HTTP status code carries the category.

{ "error": "rate_limit_exceeded" }
StatusDescription
400Bad request.
401Missing or invalid x-api-token.
403Account disabled, or you don't own the custom domain.
404Resource not found.
410Email body expired (error: email_expired).
429Rate limit (rate_limit_exceeded) or long-poll concurrent-cap. Retry-After header included.
503Real-time push transport unavailable.