otpbox

OTPBox / Guides / Temp mail API

REST API · Free key

A temp mail API with a free key and no signup

Consumer temp-mail sites are built for a person in a browser tab. A test suite, a script or an AI agent needs the same idea as an API: create a throwaway address, wait for the email, and get the one-time code back as JSON. OTPBox is that disposable email API. You can have a working key in one request, with no account and no card, and the whole round trip (create, wait, read, delete) is four calls.

1. Mint a free API key

curl -X POST https://otpbox.io/api/v1/keys/free

{ "id": "lic_...", "key": "...", "plan": "free", "quotaLimit": 200 }

Send the key as a bearer token on every other call. The examples below read it from $OTPBOX_KEY:

export OTPBOX_KEY=...   # the "key" from the response above

2. Create an inbox

curl -X POST https://otpbox.io/api/v1/inboxes \
  -H "authorization: Bearer $OTPBOX_KEY" \
  -H "content-type: application/json" \
  -d '{}'

201 Created
{ "id": "a1b2c3d4e5f6", "address": "bold.quartz844@otpbox.io", "domain": "otpbox.io",
  "createdAt": 1790000000000, "expiresAt": 1790003600000, "token": "..." }

The address can receive mail right away. Use it in whatever sign-up or login form you're testing. Pass "local" in the body to choose the part before the @ (409 address_unavailable if it's taken). An inbox expires 1 hour after creation by default, and you can delete it sooner.

3. Wait for the OTP code

Don't write a polling loop. Ask for the code with a timeout, and OTPBox holds the request open until a code arrives or the timeout passes:

curl "https://otpbox.io/api/v1/inboxes/a1b2c3d4e5f6/otp?timeout=20" \
  -H "authorization: Bearer $OTPBOX_KEY"

{ "code": "482913", "messageId": "msg_...", "from": "noreply@example.com",
  "subject": "Your verification code", "receivedAt": 1790000300000 }

4. Or read the extracted link

Plenty of flows email a link instead of a code. OTPBox extracts links too, and labels each one verification, password_reset, magic_login, unsubscribe, tracking or general:

curl "https://otpbox.io/api/v1/inboxes/a1b2c3d4e5f6/links?type=verification&timeout=20" \
  -H "authorization: Bearer $OTPBOX_KEY"

{ "links": [ { "messageId": "msg_...", "url": "https://example.com/verify?t=...",
               "host": "example.com", "type": "verification",
               "from": "noreply@example.com", "subject": "Confirm your email",
               "receivedAt": 1790000300000 } ] }

/links takes the same filters and timeout as /otp, plus type. If nothing matches, the list comes back empty. To read a whole message (text, sanitized HTML, attachments), call GET /api/v1/messages/:id with the messageId, or use POST /api/v1/inboxes/:id/wait to wait for the next full message. See Waiting for mail.

5. Delete the inbox

curl -X DELETE https://otpbox.io/api/v1/inboxes/a1b2c3d4e5f6 \
  -H "authorization: Bearer $OTPBOX_KEY"

{ "ok": true }

The inbox and every message in it are deleted immediately. If you forget, it's removed when it expires anyway.

The same round trip in JavaScript

Plain fetch, built into Node 18 and later, with no package to install:

const API = 'https://otpbox.io/api/v1';
const headers = { authorization: `Bearer ${process.env.OTPBOX_KEY}` };

const inbox = await fetch(`${API}/inboxes`, {
  method: 'POST',
  headers: { ...headers, 'content-type': 'application/json' },
  body: '{}',
}).then((r) => r.json());

console.log('Sign up with', inbox.address);
// ...trigger the email from the app you're testing...

const res = await fetch(`${API}/inboxes/${inbox.id}/otp?timeout=20`, { headers });
const otp = res.ok ? (await res.json()).code : null; // 404 no_otp if nothing arrived

await fetch(`${API}/inboxes/${inbox.id}`, { method: 'DELETE', headers });

Prefer a client library? otpbox-sdk on npm and otpbox on PyPI wrap the same endpoints. For a browser test, see the Playwright guide.

How this differs from a consumer temp-mail site

A consumer temp-mail site, OTPBox's own homepage inbox included, is a web page for a person. You open it, copy the address and read the email. That works when you're signing up by hand. It breaks down when code has to do it, and the usual workaround is to scrape the site. Here is what changes when the inbox is an API:

Scraping a consumer temp-mail siteOTPBox temp mail API
InterfaceHTML meant for people, which can change without noticeDocumented REST endpoints that return JSON
AccessWhatever the site allows, including any bot checks it addsA bearer key, free with one request
Getting the codeFind it in the email body yourselfAlready extracted, in a code field
LinksPick the right href out of the HTMLExtracted and labeled (verification, magic_login, ...)
Waiting for mailReload and re-parse in a loopServer-side wait of up to 25 s, one request
Push notificationsUsually noneSigned webhooks (otp.extracted, link.detected, ...)
AI agentsThe agent has to drive the web pageAn MCP server with 13 tools
CleanupDepends on the siteDELETE the inbox, or it expires 1 hour after creation

For a feature-by-feature look at one well-known consumer site, see OTPBox vs. Temp-Mail.org. For developer test-email tools, see OTPBox vs. Mailinator vs. Mailosaur, vs. Mailosaur and vs. MailSlurp.

Beyond create, read, delete

Limits and plans

PlanRequests / monthPrice
Personal free key200 per key$0, no account
Organization Free200, pooled across keys$0
Organization Pro5,000, pooled across keys$9 / month
EnterpriseCustomCustom

Going over the quota returns 429 quota_exceeded. Overage is never charged; you upgrade or wait for the next cycle. GET /api/v1/usage shows where a key stands. Details are on the pricing page.

OTPBox only receives mail and can't send it. Some services block known disposable-email domains, so the API works best for testing sign-up and login flows you control.

Next steps

Sign up, mint a key, and the dashboard shows your first code arriving live. Try it in the dashboard

Rather skip the account? curl -X POST https://otpbox.io/api/v1/keys/free gives you a free key with 200 requests a month.

← Back to OTPBox