FastMailApp API
v2.0 ยท Public REST API

FastMailApp API

Public REST API to create disposable email addresses, receive and read mail. No registration required (optional API key for higher rate limits).

Base URL
https://fastmailapp.com
Format
JSON
Mailbox TTL
1800s (30 min)
Supported domains
@fastmailapp.com
@nmailbox.cc
@nmailbox.live
@nmailbox.org
@smailbox.us

Features

  • Create disposable mailbox (random or custom name)
  • Receive real mail from Gmail / Outlook / any MTA via SMTP port 25
  • Read mail as JSON (text + html)
  • Mailbox and all its mail are auto-destroyed after TTL
  • No storage, no tracking, no cookies

Authentication #

The API is fully public โ€” you can use it without registering. Registering an API key gives you a much higher rate limit.

Use an API key

Pass your key via the Authorization: Bearer <key> header:

# Anonymous (low rate limit)
curl https://fastmailapp.com/api/new

# With API key (high rate limit)
curl -H "Authorization: Bearer nmb_xxxxxxxxxxxxxx" \
     https://fastmailapp.com/api/new

Register an API key

Call POST /api/keys โ€” no authentication required:

curl -X POST https://fastmailapp.com/api/keys \
     -H "Content-Type: application/json" \
     -d '{"name":"my-app"}'

The response contains the key โ€” save it immediately; it will not be shown again:

{
  "id": "a1b2c3d4e5f6g7h8",
  "key": "nmb_XXXX...XXXX",
  "name": "my-app",
  "createdAt": 1778523000,
  "rateLimit": 2000
}
API keys are stored in memory โ€” they will be lost if the service restarts. Just register a new one when needed. Each IP can register up to 20 keys per day.

Rate limits #

Limits are per minute and reset every 60 seconds.

Anonymous (per IP)
120 req / min
With API key
2000 req / min

Every response includes the following headers:

  • X-RateLimit-Limit โ€” max requests per minute
  • X-RateLimit-Remaining โ€” requests left in the current minute
  • Retry-After โ€” seconds to wait (only when 429)

When you exceed the limit, the server responds with 429 Too Many Requests.

Quick start #

Create a mailbox โ†’ wait for mail โ†’ read the inbox. Three steps.

# 1. Create a mailbox with a custom name
ADDR=$(curl -s https://fastmailapp.com/api/new/john | jq -r .address)
echo "Mailbox: $ADDR"

# 2. List inbox (poll every 5s)
curl -s "https://fastmailapp.com/api/inbox?address=$ADDR" | jq

# 3. Read a specific mail
curl -s https://fastmailapp.com/api/mail/MAIL_ID | jq
import requests, time

# 1. Create mailbox
r = requests.get("https://fastmailapp.com/api/new/john")
addr = r.json()["address"]
print(f"Mailbox: {addr}")

# 2. Poll inbox until mail arrives
while True:
    r = requests.get("https://fastmailapp.com/api/inbox", params={"address": addr})
    data = r.json()
    if data["emails"]:
        print(f"Got {len(data['emails'])} mail(s)")
        break
    time.sleep(5)

# 3. Read the first mail
first_id = data["emails"][0]["id"]
mail = requests.get(f"https://fastmailapp.com/api/mail/{first_id}").json()
print(mail["subject"], "\n", mail["text"])
// 1. Create mailbox
const r = await fetch("https://fastmailapp.com/api/new/john");
const { address } = await r.json();
console.log("Mailbox:", address);

// 2. Poll inbox
async function poll() {
    const r = await fetch(`https://fastmailapp.com/api/inbox?address=${address}`);
    return (await r.json()).emails;
}

// 3. Read mail
const mails = await poll();
if (mails.length) {
    const mail = await (await fetch(`https://fastmailapp.com/api/mail/${mails[0].id}`)).json();
    console.log(mail.subject, mail.text);
}

Mailbox #

Create / inspect / delete a disposable email address.

GET /api/new

Create a random mailbox โ€” the server generates a 10-character local part.

Request

curl https://fastmailapp.com/api/new

Response 200 OK

{
  "address": "k7p2qe9w3x@fastmailapp.com",
  "createdAt": 1778523000,
  "expiresAt": 1778524800,
  "secondsLeft": 1800,
  "lifetime": 1800,
  "reused": false
}
GET /api/new/{local}

Create a mailbox with a custom local part. If the name already exists, the server returns reused: true (you will share the inbox with the previous user).

Path parameters

NameTypeDescription
localrequiredstringPart before @. Allowed: a-z 0-9 . _ -, 2-32 chars.

Request

curl https://fastmailapp.com/api/new/john

Response 200 OK

{
  "address": "john@fastmailapp.com",
  "createdAt": 1778523000,
  "expiresAt": 1778524800,
  "secondsLeft": 1800,
  "lifetime": 1800,
  "reused": false
}

Errors

  • 400 โ€” invalid local part
  • 503 โ€” no domains configured
POST /api/mailbox

Create a mailbox using a JSON body โ€” useful when you also want to specify the domain (when multiple are available).

Body (JSON)

FieldTypeDescription
addressstringFull user@domain. Omit for random.

Request

curl -X POST https://fastmailapp.com/api/mailbox \
     -H "Content-Type: application/json" \
     -d '{"address":"hello@fastmailapp.com"}'
GET /api/mailbox/{address}

Get mailbox info (remaining TTL). Returns 404 if not found or expired.

curl https://fastmailapp.com/api/mailbox/john@fastmailapp.com
DELETE /api/mailbox/{address}

Delete the mailbox immediately and all of its emails. Returns the number of mails deleted.

curl -X DELETE https://fastmailapp.com/api/mailbox/john@fastmailapp.com
{"deleted": 3}

Mail #

List the inbox and read individual messages.

GET /api/inbox?address={address}

List all mails in a mailbox, newest first.

Query parameters

NameTypeDescription
addressrequiredstringFull mailbox address.

Request

curl "https://fastmailapp.com/api/inbox?address=john@fastmailapp.com"

Response 200 OK

{
  "address": "john@fastmailapp.com",
  "secondsLeft": 1542,
  "count": 2,
  "emails": [
    {
      "id": "a5259346b1f446d4a1fc285dd2b44bb3",
      "subject": "Welcome",
      "fromAddress": "noreply@example.com",
      "toAddress": "john@fastmailapp.com",
      "createdAt": 1778523450,
      "expiresAt": 1778524800,
      "readAt": null,
      "hasHtml": true,
      "hasText": true
    }
  ]
}
Legacy endpoint GET /api/email/{recipient} still works (path param instead of query).
GET /api/mail/{email_id}

Fetch the full content of a single mail. The first call marks the mail as read.

Request

curl https://fastmailapp.com/api/mail/a5259346b1f446d4a1fc285dd2b44bb3

Response 200 OK

{
  "id": "a5259346b1f446d4a1fc285dd2b44bb3",
  "subject": "Welcome",
  "fromAddress": "noreply@example.com",
  "toAddress": "john@fastmailapp.com",
  "createdAt": 1778523450,
  "expiresAt": 1778524800,
  "readAt": 1778523500,
  "hasHtml": true,
  "hasText": true,
  "html": "<p>Hello</p>",
  "text": "Hello"
}
Legacy alias: GET /api/inbox/{email_id} still works.
DELETE /api/mail/{email_id}

Delete a single mail.

curl -X DELETE https://fastmailapp.com/api/mail/a5259346b1f446d4a1fc285dd2b44bb3

Verification codes #

The API auto-detects verification codes (OTPs) and magic links from every mail. The detection is language-agnostic โ€” works for English, Vietnamese, Japanese, Korean, Arabic, Chinese, etc.

Compatible with mail.tm's verifications field. Same detection logic, same field name โ€” drop-in for code written against mail.tm's API.

The verifications field

Every GET /api/mail/{id} response includes two extra fields:

  • verifications โ€” array of detected codes, most likely OTP first
  • links โ€” array of detected magic / confirmation URLs
{
  "id": "a5259346b1f446d4a1fc285dd2b44bb3",
  "subject": "Welcome",
  "html": "<p>Your code is <b>728493</b>...</p>",
  "text": "Your code is 728493...",
  "verifications": ["728493"],
  "links": []
}

Detection rules

  • Tokens inside HTML emphasis tags (<b>, <strong>, <h1-h6>, <center>, <mark>)
  • Tokens that appear alone on their own line
  • 4-12 chars alphanumeric (with dashes), must contain โ‰ฅ1 digit
  • Year-like numbers 1900-2099 are filtered out
  • Numbers near street suffixes / phone prefixes / state-zip patterns are filtered out
  • Magic links: URLs containing verify / confirm / activate / token= / code= / otp=
GET /api/verifications?address={address}

Convenience polling endpoint: returns the newest mail that contains a verification code or magic link. Poll this every few seconds while waiting for an OTP โ€” much simpler than fetching the inbox list and iterating mails yourself.

Query parameters

NameTypeDescription
addressrequiredstringFull mailbox address.

Request

curl "https://fastmailapp.com/api/verifications?address=john@fastmailapp.com"

Response 200 OK โ€” code found

{
  "address": "john@fastmailapp.com",
  "mailId": "d387c683769942eeb67e2266dd67f9ea",
  "subject": "Your verification code",
  "fromAddress": "support@example.com",
  "createdAt": 1778527050,
  "verification": "728493",
  "verifications": ["728493"],
  "links": []
}

Response 200 OK โ€” no code yet

{
  "address": "john@fastmailapp.com",
  "mailId": null,
  "verification": null,
  "verifications": [],
  "links": []
}

Polling example (Python)

import requests, time

addr = requests.get("https://fastmailapp.com/api/new/myapp-signup").json()["address"]
print("Mailbox:", addr)

# Trigger signup elsewhere that sends a code to `addr`...

while True:
    r = requests.get("https://fastmailapp.com/api/verifications", params={"address": addr})
    code = r.json()["verification"]
    if code:
        print("Got code:", code)
        break
    time.sleep(3)

System #

API keys, allowed domains, health check.

POST /api/keys

Register a new API key. No authentication required. Each IP can create up to 20 keys per day.

Body (JSON, optional)

FieldTypeDescription
namestringFriendly label (max 64 chars).
curl -X POST https://fastmailapp.com/api/keys \
     -H "Content-Type: application/json" \
     -d '{"name":"my-bot"}'
GET /api/keys/me

Get info about the currently used key. Requires Authorization: Bearer ... header.

curl -H "Authorization: Bearer nmb_xxxxxxxx" \
     https://fastmailapp.com/api/keys/me

Revoke the key:

curl -X DELETE \
     -H "Authorization: Bearer nmb_xxxxxxxx" \
     https://fastmailapp.com/api/keys/me
GET /api/domains

List of allowed domains.

curl https://fastmailapp.com/api/domains
["@fastmailapp.com", "@nmailbox.cc", ...]
GET /api/health

Health check. Not rate-limited.

curl https://fastmailapp.com/api/health
{
  "status": "healthy",
  "ts": 1778523000,
  "mailboxes": 12,
  "emails": 45,
  "apiKeys": 3
}