Getting started
fabricatedemail gives your automated tests disposable email addresses and an HTTP API to read the mail that arrives at them. You register an address, your system under test sends mail to it, and you poll for the message — typically about a second after SMTP delivery. Nothing has to be reachable from the internet on your side, so it works from a CI runner with no tunnel and no relay.
It is a tool for developers and CI pipelines. There is no page here where you click a button and read a stranger's mail in your browser.
Before your first request
| Base URL | https://api.fabricatedemail.com |
| Mail domain | fabricatedemail.com — addresses are local-part@fabricatedemail.com, not @api.fabricatedemail.com |
| API key | 64 hex characters, created in the dashboard and shown once |
Send the key as Authorization: Bearer <key>. Keep it out of your repository;
in CI it belongs in the secret store.
Read your first message
BASE=https://api.fabricatedemail.com
KEY=$TEMPMAIL_KEY
# 1. Register an address. Use a random local part — see below.
SID=$(curl -sS -X POST "$BASE/subscriptions" \
-H "Authorization: Bearer $KEY" -H 'Content-Type: application/json' \
-d '{"localPart":"run-8f2c1d94a7b30e56","ttlSeconds":3600}' \
| sed -n 's/.*"id":"\([^"]*\)".*/\1/p')
# 2. Have the system under test send mail to
# run-8f2c1d94a7b30e56@fabricatedemail.com
# 3. Wait for it. The request holds open for up to 30 seconds.
curl -sS "$BASE/subscriptions/$SID/messages?wait=30" \
-H "Authorization: Bearer $KEY"
The long poll returns as soon as a message lands, so a passing test costs one
request and about a second. Poll with the after cursor to read only what is
new. The full request and response shapes are in the
HTTP API contract and the
API reference.
Random local parts are mandatory
Two jobs that pick the same local part share a mailbox, and each sees the other's mail. Generate at least 64 bits of randomness per address — a UUID, or 16 hex characters from your language's secure random source. The service does not enforce this and cannot detect the collision for you.
Read this before you trust a negative assertion
Cloudflare Email Routing rejects inbound mail that fails both SPF and DKIM, mail that fails the sending domain's DMARC policy, and mail from blocklisted IP addresses — before this service runs, and we cannot switch it off. Mail from an unauthenticated development or staging SMTP server therefore vanishes with no trace here: no message, no error, no log line you can read.
Test mail must come from a properly configured sender — Amazon SES, SendGrid, Postmark or your own server with SPF, DKIM and DMARC set up. Verify that once, explicitly, before you write a test that asserts a message did not arrive.
The other reasons a message never shows up — the monthly cap, a suspended account, retention — are collected in Why mail might not arrive. It is the first page to open when a test goes red.
Where to go next
- Why mail might not arrive — every silent failure mode, in the order worth checking.
- HTTP API contract — every endpoint, status code, limit and assertion recipe. Self-contained.
- API reference — the same surface generated from the OpenAPI document.
- One-time codes and links — pull a verification code out of a message without writing a regular expression.
- MCP server — the same tools for a coding agent.
- Stability policy — what we may change under a working client, and what we may not.
- Pricing — the tiers and their caps.