Test Mode
Develop and test the full email flow — statuses, timeline, webhooks — without sending real email
Every workspace has two key environments, Stripe-style:
Test — tratto_test_... | Live — tratto_live_... | |
|---|---|---|
| Delivery | Simulated — nothing is ever sent | Real, via our sending infrastructure |
| Sender domain | Any syntactically valid address | Must be a verified domain |
| Monthly quota | Untouched (own cap: 100 test sends/day) | Counts against your plan |
| Statuses, timeline, webhooks | Identical to live | — |
| Data visibility | A test key sees only test data | A live key sees only live data |
| Retention | Deleted 7 days after creation | Deleted 90 days after sending, on every plan |
The point: your integration — sending, status polling, webhook handling, bounce handling — runs against the exact same pipeline as production, before any DNS work and with zero risk of emailing a real person.
Simulator addresses
The recipient address picks the simulated outcome:
| Recipient | Outcome |
|---|---|
| any address | delivered event, email ends delivered |
[email protected] | permanent bounce — email ends failed, bounced event with type: "Permanent" |
[email protected] | transient bounce — bounced event with type: "Transient" |
[email protected] | spam complaint — complained event |
The simulator.tratto.email domain never receives mail; it exists only as a
selector.
The livemode flag
Everything a test key touches is marked:
POST /v1/emailsresponses include"livemode": false- webhook payloads include
"livemode": false(live events carry"livemode": true) — key on this field, not on heuristics - the dashboard shows a Test mode banner and TEST badges when the Live/Test toggle is on Test
Environment isolation
Test and live are separate views of your workspace:
GET /v1/emailswith a test key lists only test emails; with a live key, only live ones- fetching, canceling or rescheduling an email of the other environment
returns
404— indistinguishable from a missing id - idempotency keys are scoped per environment
Campaigns
A campaign belongs to the environment of the key that created it:
POST /v1/campaigns stamps livemode from the key, never from the request
body. Every campaign endpoint then checks it — reading a campaign,
PATCH, DELETE, /stats, /links, /send, /pause, /unschedule and
/test-send. A test key that addresses a live campaign gets 404, on all of
them.
This is stricter than it was before 2026-09-04. POST /v1/campaigns/{id}/pause
and POST /v1/campaigns/{id}/unschedule used to act on a live campaign when
called with a test key. They now return 404 and do nothing. If a script
pauses live campaigns, it needs a live key.
404, not 403 — deliberately. A campaign belonging to the other
environment answers exactly like one that does not exist, so an id cannot be
probed across environments.
A campaign created before the field existed carries no livemode and counts as
live.
What test keys cannot do
Endpoints that reach real recipients reject test keys with
403 TEST_MODE_NOT_SUPPORTED, whichever environment the resource is in:
- sending or scheduling a campaign (
POST /v1/campaigns/{id}/send) - campaign and template test-sends (they deliver real email)
- activating a flow
Everything else on a campaign is available to a test key — but only on a
test campaign. On a live one it is a 404, per the rule above. Since a
test campaign can never be dispatched, /pause and /unschedule have nothing
to act on in test mode: they exist there, they just never have work to do.
Simulated events also never touch your analytics, your contacts' suppression status, or campaign statistics.
Going live
Swap the key. That's it — same request shape, same webhook signature scheme. A live key requires a verified sender domain and counts against your plan quota.
Edit this page on GitHub
Last updated on