TempMailGrab Developer API

Create disposable inboxes and read incoming mail programmatically — with one-time passcodes and verification links extracted for you. Built for QA, test automation, and bots.

Download the OpenAPI 3.1 spec → — import into Postman, Insomnia, or Swagger UI.

JavaScript and TypeScript SDK

The official zero-dependency SDK includes typed inboxes, OTP and verification-link waiters, Playwright fixtures, webhook signature verification, retries, and 46 tests. Review the source on GitHub.

Install the official v1.0.0 package

npm install tempmailgrab

Get an API key

Create a free account on the developer dashboard (email/password or GitHub), then mint an API key. Every key is tied to your account, so all of your keys and the dashboard share the same private inboxes.

Authentication

Send your key on every request, either as a bearer token or the legacy header — both work:

  • Authorization: Bearer tmg_live_xxx
  • X-API-Key: tmg_live_xxx

The base URL is https://tempmailgrab.com/api/v1. Inboxes are private to the key's account — you can only read mail for inboxes you created.

Endpoints

  • POST /api/v1/inbox — Create a private disposable inbox. Optional JSON body { prefix?, domain? }.
  • GET /api/v1/inbox/:id/messages — List messages (newest first) with a snippet and the extracted OTP.
  • GET /api/v1/inbox/:id/messages/:mid — Fetch one message: sanitized HTML, extracted OTP & links, attachments.
  • DELETE /api/v1/inbox/:id — Permanently delete an inbox and all stored mail.
  • DELETE /api/v1/inbox/:id/messages — Purge every message while keeping the inbox address.
  • GET /api/v1/messages/:id — Fetch one parsed message by id (flat alias).
  • POST /api/v1/inbox/:id/test-message — Inject a synthetic email into your inbox — useful for developing and testing your message-parsing logic without waiting for a real email.
  • POST /api/v1/inbox/:id/webhook — Register a delivery webhook for a single inbox.
  • POST /api/v1/webhooks — Register an account webhook — fires for every inbox you own.
  • GET /api/v1/webhooks — List your account webhooks.
  • DELETE /api/v1/webhooks/:id — Delete an account webhook.
  • POST /api/v1/byod — Register a custom domain and receive its required DNS records.
  • POST /api/v1/byod/:domain/verify — Verify custom-domain ownership and MX routing.
  • GET /api/v1/byod — List custom domains registered to this API key.

DELETE /api/v1/inbox/:id — Permanently delete an inbox and all of its messages and attachments immediately. Use this in test teardown instead of waiting for the TTL.

POST /api/v1/inbox — optional body parameters

  • prefix (string): Custom prefix for the email address
  • domain (string): Email domain to use when multiple domains are available
  • ttl_seconds (integer): Inbox lifetime in seconds. Min: 600 (10 min). Default: 86400 (24 h). Max: 259200 (72 h).

Create inbox with custom TTL

curl -X POST https://tempmailgrab.com/api/v1/inbox \
  -H "Authorization: Bearer $TMG_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"ttl_seconds": 3600}'

Message pagination: GET /api/v1/inbox/:id/messages returns all messages for the inbox (newest first). There is no limit or page parameter — typical inboxes stay small; for high-volume tests, poll and process incrementally.

Smart parsing

Every incoming message is parsed at ingestion. Responses include extracted_otp (the detected one-time passcode, or null) and extracted_links (verification / confirmation URLs) — so you rarely have to scrape the email body yourself.

Quickstart — automate an OTP

Create an inbox, sign up with its address, then poll until the code is extracted:

cURL

# 0. Create a free API key in the dashboard, then export it.
export TMG_API_KEY="tmg_live_xxx"

# 1. Create a private inbox.
curl -s -X POST https://tempmailgrab.com/api/v1/inbox \
  -H "Authorization: Bearer $TMG_API_KEY"
# → {"id":"inb_…","address":"a1b2c3d4e5f6@tempmailgrab.com","expires_at":…}

# 2. Use that address to sign up on the target site, then poll for the code.
#    The one-time passcode + verification links are auto-extracted for you.
curl -s https://tempmailgrab.com/api/v1/inbox/<INBOX_ID>/messages \
  -H "Authorization: Bearer $TMG_API_KEY"
# → {"messages":[{"sender":"…","subject":"…","extracted_otp":"123456"}]}

Python

import time, requests, os

BASE = "https://tempmailgrab.com/api/v1"
H = {"Authorization": f"Bearer {os.environ['TMG_API_KEY']}"}

def create_inbox():
    r = requests.post(f"{BASE}/inbox", headers=H, timeout=10)
    r.raise_for_status()
    return r.json()

def wait_for_otp(inbox_id, timeout=30, poll_interval=2):
    """Poll for OTP with timeout. Returns OTP string or raises TimeoutError."""
    deadline = time.time() + timeout
    while time.time() < deadline:
        try:
            r = requests.get(f"{BASE}/inbox/{inbox_id}/messages", headers=H, timeout=10)
            r.raise_for_status()
            msgs = r.json().get("messages", [])
            for msg in msgs:
                if msg.get("extracted_otp"):
                    return msg["extracted_otp"]
        except requests.RequestException as e:
            print(f"Polling error (retrying): {e}")
        time.sleep(poll_interval)
    raise TimeoutError(f"OTP not received within {timeout}s")

# Usage
inbox = create_inbox()
print(f"Sign up with: {inbox['address']}")
# ... trigger sign-up on target service ...
otp = wait_for_otp(inbox["id"])
print(f"OTP: {otp}")

Node.js

const BASE = "https://tempmailgrab.com/api/v1";
const H = { Authorization: "Bearer tmg_live_xxx" }; // or { "X-API-Key": "tmg_live_xxx" }

// 1. Create an inbox and hand its address to your signup flow.
const inbox = await fetch(`${BASE}/inbox`, { method: "POST", headers: H }).then((r) => r.json());
console.log("Sign up with:", inbox.address);

// 2. Poll until the verification code arrives (auto-extracted).
let otp = null;
for (let i = 0; i < 30 && !otp; i++) {
  const { messages } = await fetch(`${BASE}/inbox/${inbox.id}/messages`, { headers: H })
    .then((r) => r.json());
  otp = messages.find((m) => m.extracted_otp)?.extracted_otp ?? null;
  if (!otp) await new Promise((r) => setTimeout(r, 2000));
}
console.log("OTP:", otp);

Webhooks

Prefer push to polling? Register a webhook and we'll POST the full parsed message (including extracted_otp and extracted_links) to your URL the instant mail arrives. Each delivery is signed with HMAC-SHA256 in the X-TMG-Signature header; verify it with the secret returned at creation.

Register an account webhook

# Get a push the instant mail arrives — no polling.
curl -s -X POST https://tempmailgrab.com/api/v1/webhooks \
  -H "Authorization: Bearer $TMG_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://your-app.example.com/tmg-hook"}'
# → {"id":"wh_…","secret":"whsec_…"}  ← store the secret to verify deliveries

Webhook payload example

{
  "event": "email.received",
  "sent_at": 1788157327,
  "data": {
    "id": "msg_xyz789",
    "inbox_address": "ci-test@tempmailgrab.com",
    "sender": "noreply@example.com",
    "subject": "Your verification code",
    "text_body": "Your code is 847291",
    "html_body": "<p>Your code is <strong>847291</strong></p>",
    "extracted_otp": "847291",
    "extracted_links": [],
    "timestamp": 1788157327
  }
}

Verify HMAC signature (Node.js)

import crypto from "node:crypto";

function verify(body, signature, secret) {
  if (!/^[a-f0-9]{64}$/i.test(signature)) return false;
  const expected = crypto.createHmac("sha256", secret).update(body).digest("hex");
  return crypto.timingSafeEqual(Buffer.from(signature, "hex"), Buffer.from(expected, "hex"));
}

Verify HMAC signature (Python)

import hmac, hashlib

def verify(body: bytes, signature: str, secret: str) -> bool:
    expected = hmac.new(secret.encode(), body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, signature)

Error responses

  • 401 Unauthorized — Missing or invalid API key
  • 404 Not Found — Inbox ID does not exist or has expired
  • 429 Too Many Requests — Rate limit exceeded; see Retry-After header
  • 500 Internal Server Error — Transient error; retry with exponential backoff

Rate limits

Up to 100 requests per second (6,000 per 60-second window) per API key. Inbox creation has a separate limit of 2 per second. Rate limit headers (X-RateLimit-Remaining, X-RateLimit-Reset) are returned on every response. Exceeding the limit returns 429 Too Many Requests with a Retry-After header — implement exponential backoff and retry.

Testing integration

For complete test-runner patterns, start with the email testing API overview, then use the dedicated Playwright temp mail API guide or Cypress temp mail API guide for framework-specific fixtures. The QA testing guide covers broader CI/CD strategy.

API Changelog

v1 (current) — Launched 2025

  • POST /api/v1/inbox — Create disposable inbox
  • GET /api/v1/inbox/:id/messages — List messages with extracted OTP
  • GET /api/v1/inbox/:id/messages/:mid — Single message details
  • DELETE /api/v1/inbox/:id — Delete an inbox and its stored mail
  • DELETE /api/v1/inbox/:id/messages — Purge mail while keeping the address
  • POST /api/v1/inbox/:id/test-message — Inject a synthetic delivery test
  • POST /api/v1/webhooks — Account-level webhook registration
  • GET /api/v1/webhooks — List webhooks
  • DELETE /api/v1/webhooks/:id — Delete webhook
  • POST /api/v1/byod — Register a custom domain
  • POST /api/v1/byod/:domain/verify — Verify custom-domain DNS
  • GET /api/v1/byod — List custom domains

The API is versioned. Breaking changes will be introduced under /api/v2 with migration documentation published in advance.

Try it — Interactive Playground

Paste your API key and run live requests against the real API. Get a free key →

POST /api/v1/inbox