Quick Start
The classic "automate a signup flow" pattern in three calls. Create an inbox, trigger your signup, wait for the OTP. Pick your language:
# 1. Create inbox
curl -X POST https://api.tempmailpro.io/v1/inbox \
-H "x-api-key: YOUR_KEY"
# 2. Trigger your signup flow with the returned address
# 3. Wait for the OTP email
curl "https://api.tempmailpro.io/v1/wait-for?address=YOUR_INBOX&otpOnly=true&timeout=30" \
-H "x-api-key: YOUR_KEY"Authentication
Every request must carry your API key in the x-api-key header. Keys look like sk_tmpro_… and are created in your dashboard. You see the full key only once on creation — store it securely.
Base URL & Rate Limits
All endpoints live under:
| Plan | Rate | Monthly quota |
|---|---|---|
| Free | 5 req/min | 100 checks (no main API) |
| Starter | 60 req/min | 5,000 calls + 5,000 checks |
| Pro | 300 req/min | 50,000 calls + 50,000 checks |
| Enterprise | 1,000 req/min | 500,000 calls + unlimited checks |
Rate-limit responses include RateLimit-Remaining and RateLimit-Reset headers (IETF draft-7). Quota hits return HTTP 429 with error: "QUOTA_EXCEEDED".
Inbox Management
/inboxCreate a new temporary inbox. Optional: provide `localPart` for a deterministic address, or `domain` for your verified custom domain.
curl -X POST https://api.tempmailpro.io/v1/inbox \
-H "x-api-key: YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"localPart":"signup-test-01"}'{
"success": true,
"data": {
"address": "signup-test-01@tempmailpro.io",
"expiresAt": "2026-05-21T14:30:00.000Z",
"retentionHours": 720
}
}/inboxList all of your active inboxes with their expiry timestamps.
curl https://api.tempmailpro.io/v1/inbox \
-H "x-api-key: YOUR_KEY"{
"success": true,
"count": 2,
"inboxes": [
{ "address": "signup-test-01@tempmailpro.io", "expiresAt": "...", "expired": false }
]
}/inbox/:addressDelete an inbox along with all its stored messages and attachment files.
curl -X DELETE "https://api.tempmailpro.io/v1/inbox/signup-test-01@tempmailpro.io" \
-H "x-api-key: YOUR_KEY"{"success": true, "message": "Deleted inbox ... along with 5 messages and 2 attachment files."}Messages
/inbox/:address/emailsList all messages for an inbox (up to 200, newest first). HTML body and attachments are excluded — use `/message/:id` for the full payload.
curl "https://api.tempmailpro.io/v1/inbox/signup-test-01@tempmailpro.io/emails?limit=10" \
-H "x-api-key: YOUR_KEY"{ "success": true, "count": 3, "data": [ { "id": "...", "from": "...", "subject": "...", "otpCode": "482915" } ] }/inbox/latestShortcut to fetch the most recent message for an inbox, with full body and OTP extracted.
curl "https://api.tempmailpro.io/v1/inbox/latest?address=signup-test-01@tempmailpro.io" \
-H "x-api-key: YOUR_KEY"{ "success": true, "data": { "id": "...", "from": "...", "subject": "Your verification code", "otpCode": "482915", "text": "...", "receivedAt": "..." } }/message/:idFetch a single message in full (HTML, attachments, headers).
curl https://api.tempmailpro.io/v1/message/6526abcd1234567890abcdef \
-H "x-api-key: YOUR_KEY"{ "success": true, "data": { "id":"...", "from":"...", "to":"...", "html":"<html>...</html>", "attachments": [...] } }/message/:idPermanently delete a single message + its attachment files.
curl -X DELETE https://api.tempmailpro.io/v1/message/6526abcd... \
-H "x-api-key: YOUR_KEY"{ "success": true }Real-time & Account
/wait-forKiller feature★ Long-poll for a new email. Blocks until the next message arrives for the given inbox, or the timeout (default 20s, max 30s). Returns `204 No Content` on timeout. Pass `otpOnly=true` to only resolve when an email with an extracted OTP code arrives.
curl "https://api.tempmailpro.io/v1/wait-for?address=signup-test-01@tempmailpro.io&timeout=30&otpOnly=true" \
-H "x-api-key: YOUR_KEY"{
"success": true,
"waitedMs": 4127,
"data": { "id":"...", "from":"...", "otpCode":"482915", "text":"...", "receivedAt":"..." }
}/usageYour current plan, limits, and month-to-date usage across both API buckets (main + disposable checks).
curl https://api.tempmailpro.io/v1/usage \
-H "x-api-key: YOUR_KEY"{
"success": true,
"plan": "pro",
"usage": {
"apiCalls": { "used": 12_430, "limit": 50_000 },
"disposableChecks": { "used": 3_200, "limit": 50_000 },
"inboxes": { "used": 12, "limit": 50 }
},
"resetDate": "2026-05-01T00:00:00.000Z"
}Disposable-Email Check
/disposable/checkCheck if a single email address uses a disposable / temp-mail provider. Consumes 1 check credit.
curl -X POST https://api.tempmailpro.io/v1/disposable/check \
-H "x-api-key: YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"email":"foo@mailinator.com"}'{
"success": true,
"data": {
"email": "foo@mailinator.com",
"domain": "mailinator.com",
"valid": true,
"disposable": true,
"riskScore": 100,
"source": "community",
"confidence": "high",
"reason": "community-list-match"
}
}/disposable/check-bulkCheck up to 100 addresses in one call. Consumes N credits (atomic — either all succeed or none charged).
curl -X POST https://api.tempmailpro.io/v1/disposable/check-bulk \
-H "x-api-key: YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"emails":["a@gmail.com","b@yopmail.com","c@10minutemail.com"]}'{
"success": true,
"creditsUsed": 3,
"summary": { "total": 3, "disposable": 2, "clean": 1, "malformed": 0, "heuristicOnly": 0 },
"results": [ /* per-email results */ ]
}Webhooks
Set a webhook URL in your dashboard and we'll POST to it whenever a new email arrives in any of your inboxes. Each payload is HMAC-SHA256 signed with a secret we show you once on setup.
Payload
{
"event": "email.received",
"timestamp": "2026-04-21T12:00:00.000Z",
"data": {
"id": "6526abcd1234567890abcdef",
"to": "signup-test-01@tempmailpro.io",
"from": "no-reply@example.com",
"subject": "Your verification code",
"otpCode": "482915",
"textPreview": "Your code is 482915. It expires in 10 minutes.",
"hasAttachments": false,
"receivedAt": "2026-04-21T12:00:00.000Z"
}
}Signature Verification (Node.js)
import crypto from "node:crypto";
app.post("/webhook/tempmail", express.raw({ type: "application/json" }), (req, res) => {
const signature = req.header("X-TempMail-Signature"); // "sha256=abc123…"
const expected = "sha256=" + crypto
.createHmac("sha256", process.env.TEMPMAIL_WEBHOOK_SECRET)
.update(req.body)
.digest("hex");
if (signature !== expected) return res.status(401).end();
const event = JSON.parse(req.body.toString("utf8"));
// handle event.data.otpCode, event.data.from, etc.
res.json({ received: true });
});We retry delivery up to 3 times (0s, 2s, 8s) on 5xx / timeouts. 4xx responses are considered intentional rejections — no retry.
Error codes
Every error response has the same shape: { success: false, error: CODE, message: "..." }. The error code is machine-readable; the message is for humans.
| Error code | Status | Meaning |
|---|---|---|
| UNAUTHORIZED | 401 | Missing x-api-key header. |
| INVALID_KEY | 401 | API key not recognised (revoked or typo). |
| SUSPENDED | 403 | Account suspended — contact support. |
| FORBIDDEN_PLAN | 403 | Your plan doesn't include this endpoint. |
| FORBIDDEN | 403 | You don't own the inbox / message being accessed. |
| QUOTA_EXCEEDED | 429 | Monthly quota exhausted. Wait for reset or upgrade. |
| RATE_LIMIT | 429 | Too many requests per minute for your plan. |
| ADDRESS_TAKEN | 409 | That inbox address is already in use — try another. |
| INBOX_LIMIT | 403 | Plan's inbox limit reached. Delete one or upgrade. |
| NOT_FOUND | 404 | Inbox / message does not exist. |
| INVALID_LOCAL_PART | 400 | localPart must be 1-32 chars: a-z, 0-9, underscore, hyphen. |
| INVALID_ID | 400 | Message ID must be a 24-char hex string. |
Ready to ship?
Free tier gives you 100 disposable-check calls per month with a real API key. Upgrade when you need the main temp-mail API.