Skip to content

Testing

Some outcomes are hard to make happen on purpose: you can’t bounce an email when you like, and you shouldn’t wait for someone to mark one as spam. The simulator addresses make them happen. An emit to one of them goes through the same checks as any other, is recorded as a message, and produces the same states and webhooks as real mail would, but nothing is sent anywhere.

Address What it plays What your endpoint gets
delivered@simulator.sendtruss.com A delivery. message.delivered
bounce@simulator.sendtruss.com A hard bounce. The address is then suppressed for every email. message.bounced with bounce hard, and contact.suppressed with reason hard_bounce when a contact holds the address
complaint@simulator.sendtruss.com A delivery, then a complaint. The address is then suppressed for marketing. message.delivered, then message.complained, and contact.suppressed with reason complaint when a contact holds the address

Every one of those webhooks carries simulated: true, and so does the emit’s answer, in data.message.simulated. Any other mailbox at simulator.sendtruss.com is refused with a 422, so a typo can’t pass for a delivery.

Emit to a simulator address the way you emit to anyone, as a bare address or through a contact that holds it:

Terminal window
curl -X POST https://api.sendtruss.com/v1/workspaces/ref:cust_4821/events \
-H "Authorization: Bearer $SENDTRUSS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"type": "welcome",
"idempotency_key": "test-bounce-1",
"recipient": {"email": "bounce+signup-1@simulator.sendtruss.com"},
"payload": {"first_name": "Ada"}
}'
  • They work before your domain verifies. While your DNS records propagate, an emit to a real address is refused with domain_not_sendable, and an emit to a simulator address goes through. Only a suspended or deleted workspace stops them.
  • Add a +label to tell tests apart. bounce+signup-1@simulator.sendtruss.com plays the same bounce as bounce@simulator.sendtruss.com, and each label is its own address. Since a simulated bounce suppresses its address, give each test run a new label, or the next emit to that address answers suppressed instead of bouncing. Case doesn’t matter.
  • A contact gets contact.suppressed. Emit through a contact holding the address to see contact.suppressed; a bare address has no contact to name.
  • Suppressions expire. A suppression a simulator address caused is removed after 24 hours, so a bare bounce@ works again the next day.

A simulated email counts toward nothing that judges or bills a workspace: no usage, no health rate and no bill sees it.

Everything that protects you and your recipients still applies, as for any emit:

  • your platform’s request rate limit, which answers rate_limited;
  • the limit of 30 emits an hour to one address, which answers recipient_rate_limited; each +label is its own address;
  • the workspace’s pace for transactional email, so a burst of simulated emits goes out at the speed real ones would;
  • idempotency: the same key and body give back the first answer;
  • the suppression list, as described above.

The simulator proves your code handles every outcome. It can’t prove your domain sends: that takes a real email. Once your domain verifies, emit to your own inbox and watch it arrive, as the last step of the Quickstart does.