Test the email your application sends
A receive-only email testing API for developers, CI pipelines, QA teams and AI agents. Create a real inbox in one call, trigger your signup or password reset, wait for the message, assert on it. No mail server to run, no sleep() in your tests.
Free. API keys are issued to DevDome accounts, and a DevDome account is free too.
What a test looks like
Three requests: create an inbox, let your app mail it, wait for the code.
# 1. A fresh inbox for this test run
curl -X POST https://inboxdome.com/v1/inboxes \
-H "Authorization: Bearer $INBOXDOME_KEY"
# → { "inbox": { "id": "inb_…", "emailAddress": "qa-1b7f@mailoca.com" } }
# 2. Your app sends its signup mail to that address…
# 3. Block until it arrives and extract the OTP (max 30 s)
curl "https://inboxdome.com/v1/inboxes/$INBOX_ID/wait?for=otp&timeoutSeconds=30" \
-H "Authorization: Bearer $INBOXDOME_KEY"
# → { "otp": { "value": "482913", "confidence": 0.95 }, "message": { … } }const BASE = 'https://inboxdome.com';
const headers = { Authorization: `Bearer ${process.env.INBOXDOME_KEY}` };
// 1. a fresh inbox
const { inbox } = await fetch(`${BASE}/v1/inboxes`, { method: 'POST', headers }).then(r => r.json());
// 2. your app mails inbox.emailAddress …
// 3. wait for the code
const { otp } = await fetch(
`${BASE}/v1/inboxes/${inbox.id}/wait?for=otp&timeoutSeconds=30`, { headers }
).then(r => r.json());
await page.fill('#code', otp.value);import os, requests
BASE = "https://inboxdome.com"
H = {"Authorization": f"Bearer {os.environ['INBOXDOME_KEY']}"}
# 1. a fresh inbox
inbox = requests.post(f"{BASE}/v1/inboxes", headers=H).json()["inbox"]
# 2. your app mails inbox["emailAddress"] …
# 3. wait for the code
otp = requests.get(f"{BASE}/v1/inboxes/{inbox['id']}/wait",
params={"for": "otp", "timeoutSeconds": 30}, headers=H).json()["otp"]
assert otp["value"]Full flows in the Playwright,Cypress, Node,Python, PHP,GitHub Actions,WordPress and MCP guides.
Everything a test suite needs from email
Inboxes on demand
POST /v1/inboxes returns a working address in one call. One inbox per test, isolated, auto-expiring. No mailbox setup, no IMAP.
Wait for the mail, not for a sleep()
Long-poll an inbox until the message lands. Extract OTP codes and verification links directly, with a timeout instead of a flaky fixed delay.
Assertions and scenarios
Declarative checks on delivery, content, links, spam score, HTML client compatibility and SPF, DKIM and DMARC. Save named sets and run them per test.
Signed webhooks
Push message.received events to your own systems. Every payload is HMAC-signed with replay protection, retried five times, replayable by hand.
MCP server for AI agents
Claude Code, Cursor and any MCP client get create_inbox, wait_for_email and run_assertions as native tools, so an agent can test a signup flow end to end.
Private pool and your own domain
A private domain pool isolated from anonymous traffic, plus bring-your-own-domain: add a TXT record and receive test mail on infrastructure whose reputation is yours.
The endpoints, in the order a test uses them
Every route lives under /v1 with a Bearer key. TheOpenAPI spec has every field.
1. Create an inbox
Optional domain (a pool name or an exact domain) andttlSeconds. The address is live the moment the call returns.
POST /v1/inboxes
{ "domain": "smart", "ttlSeconds": 3600 }
→ { "inbox": { "id": "inb_…", "emailAddress": "h4x8s2kq@mail.inboxdome.com", … } }2. Wait for the OTP or the message
Blocks up to timeoutSeconds until something arrives.for=otp returns the detected code with a confidence score;for=message returns the full message with its links.
GET /v1/inboxes/{id}/wait?for=otp&timeoutSeconds=30
→ { "message": { … }, "otp": { "value": "482913", "confidence": 0.95 } }3. Read messages, headers, attachments
Newest first with cursor pagination. HTML exactly as received, every header in order, the raw .eml and binary attachments. Delete one message, empty the inbox or purge it.
GET /v1/inboxes/{id}/messages
GET /v1/inboxes/{id}/messages/{mid}
GET /v1/inboxes/{id}/messages/{mid}/headers
GET /v1/inboxes/{id}/messages/{mid}/raw
GET /v1/inboxes/{id}/messages/{mid}/attachments/{attId}
DELETE /v1/inboxes/{id}/messages/{mid}
DELETE /v1/inboxes/{id}/messages
DELETE /v1/inboxes/{id}4. Assert in one call
Wait for the email and verify it in the same request: OTP present, text contained, link responds, SPF, DKIM or DMARC passed, spam score under a limit, HTML renders in Gmail and Outlook. Save a named set with POST /v1/scenarios and run it per test.
POST /v1/inboxes/{id}/assert
{ "timeoutSeconds": 45, "assertions": [
{ "type": "otpPresent" },
{ "type": "containsText", "text": "Welcome" },
{ "type": "linkResponds", "urlContains": "verify" },
{ "type": "auth", "check": "dkim" },
{ "type": "spamScore", "max": 5 },
{ "type": "htmlCompatibility", "clients": ["gmail", "outlook"], "maxIssues": 3 }
] }
→ { "passed": true, "arrived": true, "arrivalSeconds": 2.1, "results": [ … ] }5. Signed webhooks
Register a URL, get the secret once. Every message.received POST carries an immutable event id, a timestamp and an HMAC-SHA256 signature. Verify constant-time, reject timestamps older than five minutes. Failed deliveries retry five times; replay any of them from the delivery log.
POST /v1/webhooks { "url": "https://ci.example.com/hook" }
X-InboxDome-Event: message.received
X-InboxDome-Event-Id: whd_…
X-InboxDome-Timestamp: unix seconds
X-InboxDome-Signature-Version: v1
X-InboxDome-Signature: hex(HMAC-SHA256(secret, timestamp + "." + body))
GET /v1/webhooks/deliveries
POST /v1/webhooks/deliveries/{id}/replayBeyond the REST calls
MCP server
Point any AI coding agent at https://inboxdome.com/mcp and it can create inboxes and read OTPs while testing your app.
GitHub Action
Create, wait and assert steps for CI signup tests, straight from a workflow file.
GuideWordPress plugin
One-click wp_mail and WooCommerce deliverability test with SPF, DKIM and DMARC results.
GuideTeam keys and environments
POST /v1/keys mints named keys scoped to live or test environments, with admin and member roles.
Bring your own domain
POST /v1/domains, add the TXT record, verify, and receive test mail on your own domain.
SDKs and integrations
Playwright, Cypress, Node, Python, PHP and the OpenAPI spec for everything else.
All integrationsGet your API key
InboxDome is free. There is nothing to buy. API keys are issued to DevDome accounts, so the key, the private domain pool and the full limits all come from one login.
Create a free DevDome account
One account for every DevDome product. Sign up on DevDome.com if you do not have one yet.
Copy the key from your account
Your key is shown once under Account. Rotate it there whenever you need to.
| With a DevDome account | |
|---|---|
| Inbox tests per month | 20,000 |
| Requests per minute | 300 |
| Concurrent waits | 50 |
| Webhook endpoints | 25 |
| Private domain pool | Included |
| Bring your own domains | 10 |
| Message retention | Up to 180 days |
| Price | Free |
Monthly allowances reset on the 1st, UTC. See the API Terms.
Built for testing, and only for testing
InboxDome is for testing the email flows of applications you own or are authorized to test. It is receive-only: nothing can be sent from an InboxDome address, ever. Using it to create accounts on third-party services, bypass OTP or verification checks, farm accounts or evade bans is prohibited, enforced and grounds for termination under ourAcceptable Use Policy.
Start testing email in CI today
Every capability included, no card, no plan to pick. Log in with DevDome and go.