Test mode and sandbox

Two things let you build without touching an inbox: test keys, which never send, and the sandbox domain with its simulator addresses, which work in both modes.

Test keys

Keys that start with av_test_ run the whole pipeline: validation, sender rules, suppressions, the event log and webhooks. The only thing that does not happen is the send itself. About two seconds after a test send is accepted, the email is marked sent and then delivered (or bounced or complained, if you used a simulator recipient), and your webhooks receive the same payloads they would in live mode, with "mode": "test".

curl -X POST https://api-staging.avelto.dev/v1/emails \
  -H "Authorization: Bearer av_test_..." \
  -H "Content-Type: application/json" \
  -d '{
    "from": "Acme <hello@mail.acme.com>",
    "to": "jane@example.com",
    "subject": "Password reset",
    "text": "Nothing is sent. The events and webhooks still fire."
  }'

Test emails are free, do not count towards your monthly limit, and show up in the dashboard and in GET /v1/emails with mode: "test".

A test key only ever sees test data

The mode is a boundary, not a filter on a shared pile. A test key reads test emails and nothing else:

  • GET /v1/emails returns test emails. ?mode=live does not change that.
  • GET /v1/emails/:id returns 404 for a live email, as do its events and its webhook deliveries. It is the same 404 you get for an id that does not exist.
  • A few things touch live sending rather than live data, and need a live key: DELETE /v1/domains/:id, adding or removing a suppression, GET /v1/account/export and POST /v1/recipients/erase. These return 403 forbidden with a message saying so.

You can still read your suppression list with a test key, because a test send is checked against it like any other — if a test send comes back recipient_suppressed, you need to be able to see why.

A live key reads both modes: it defaults to live, and ?mode=test shows test emails.

The practical upshot is that a test key is safe to put somewhere a live key is not — CI, a shared staging environment, a colleague's machine. Losing one costs you nothing but the key.

The sandbox domain

Every account can send from sandbox.avelto.dev before it has verified a domain. Any local part works, so you@{site.sandboxDomain} is a valid from. Two rules apply:

  • Sends to the simulator addresses below are always allowed.
  • Sends to anyone else are allowed only when every other recipient across to, cc and bcc is your account's owner email, and that email is verified. Simulator addresses can be mixed in.

Anything else returns 403 sandbox_recipient_not_allowed:

JSON
{
  "error": {
    "code": "sandbox_recipient_not_allowed",
    "message": "The sandbox sender @sandbox.avelto.dev only delivers to the account owner (you@example.com). Verify a domain to send to anyone.",
    "details": { "recipients_not_allowed": ["jane@example.com"] }
  }
}

Verify a domain to send to anyone.

Simulator recipients

Three addresses on the sandbox domain produce a fixed outcome. They work with live keys as well as test keys, and they never add anything to your suppression list.

RecipientOutcome
delivered@sandbox.avelto.devemail.delivered
bounced@sandbox.avelto.devemail.bounced, a hard bounce
complained@sandbox.avelto.devemail.complained
curl -X POST https://api-staging.avelto.dev/v1/emails \
  -H "Authorization: Bearer av_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "from": "you@sandbox.avelto.dev",
    "to": "bounced@sandbox.avelto.dev",
    "subject": "Bounce test",
    "text": "This one bounces."
  }'

Use them to exercise your webhook handler for every path before real traffic arrives.

What test mode does not cover

  • Rendering in a real mail client. Send a live email to your own account address from the sandbox domain for that.
  • Provider throttling or deferrals. Test sends always complete in about two seconds.