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_...
DeliverySimulated — nothing is ever sentReal, via our sending infrastructure
Sender domainAny syntactically valid addressMust be a verified domain
Monthly quotaUntouched (own cap: 100 test sends/day)Counts against your plan
Statuses, timeline, webhooksIdentical to live
Data visibilityA test key sees only test dataA live key sees only live data
RetentionDeleted 7 days after creationDeleted 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:

RecipientOutcome
any addressdelivered 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/emails responses 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/emails with 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