Notify-Sim sandbox

Docs

Conformance report.

A simulator is only useful if you know exactly where it is faithful and where it is not. This page is generated from the same route table the server runs, and it states both.

Version policy

Provider APIs move; a sandbox pinned to one version becomes a liability. Where a provider puts the version in the path, Notify-Sim accepts any version and routes it to the same handler - so /v19.0/…, /v25.0/… and a version that ships next year all work without an upgrade on our side. Examples in these docs use v25.0.

SurfaceVersion handling
Meta WhatsApp Cloud Any path segment matching v<major>[.<minor>] is accepted. Requests and responses follow the Cloud API's additive shape, which has not broken across the versions we track.
SendGridv3 - the mail-send version SendGrid still ships.
FCMv1 (HTTP v1 API). The legacy server-key API is not emulated.
Expov2 push API, send and getReceipts.
Exotelv1 SMS send.
TwilioThe dated 2010-04-01 Messages resource, the only version Twilio ships.
MSG91v5 Flow API. The older v2 sendsms endpoint is not emulated.
Amazon SESv2 (/v2/email/outbound-emails). The v1 Query API is not emulated.
Amazon SNSThe 2010-03-31 query protocol, Action=Publish only.
Infobip/sms/2/text/advanced.
GupshupEnterprise WhatsApp /wa/api/v1, message and template send.
Kaleyrav1 messages.
Route MobileThe bulksms dialect, which is unversioned.
SmartPing / SPARCThe /fe/api/v1/send query-string dialect.

Emulated surfaces

ProviderRequestAuthSuccess response
SmartPing / SPARC GET /fe/api/v1/send username + password in the query string {"state":"SUBMIT_ACCEPTED", "transactionId":"…"}
Exotel POST /v1/Accounts/{key}/Sms/send HTTP Basic; the account in the path must match the key {"SMSMessage":{"Sid":"…","Status":"queued"}}
Meta WhatsApp Cloud POST /v…/{phone_id}/messages Bearer nss_… {"messages":[{"id":"wamid.…"}]}
Meta template registry POST/GET /v…/{waba_id}/message_templates Bearer nss_… Template created (auto-approved) or listed
MSG91 POST /api/v5/flow authkey header {"type":"success","message":"…"}
Route Mobile GET|POST /bulksms/bulksms username + password in the query string 1701|<destination>|<id> (plain text)
Kaleyra POST /v1/{key}/messages api-key header; the sid must match the key {"id":"…","status":"queued","total_count":1}
Twilio POST /2010-04-01/Accounts/{key}/Messages.json HTTP Basic; the AccountSid in the path must match the key 201 {"sid":"SM…","status":"queued"}
Infobip POST /sms/2/text/advanced Authorization: App nss_… {"bulkId":"…","messages":[{"status":{"name":"PENDING_ACCEPTED"}}]}
Gupshup POST /wa/api/v1/msg
POST /wa/api/v1/template/msg
apikey header {"status":"submitted","messageId":"…"}
Amazon SES v2 POST /v2/email/outbound-emails SigV4 header; the access key id in Credential= is the routing credential {"MessageId":"…"}
Amazon SNS POST /aws/sns (Action=Publish) SigV4 header, as SES above <PublishResponse><MessageId>…
SendGrid POST /v3/mail/send Bearer nss_… 202, X-Message-Id header
Expo push POST /--/api/v2/push/send
POST /--/api/v2/push/getReceipts
Bearer nss_… {"data":[{"status":"ok","id":"…"}]}
FCM HTTP v1 POST /v1/projects/{key}/messages:send The unguessable project key in the path {"name":"projects/…/messages/…"}
SMTP smtp.notify-sim.io:2587 STARTTLS, AUTH LOGIN with the project key and secret Standard SMTP acceptance
Generic capture POST /v1/capture/{sms|whatsapp|email|push} X-Api-Key: nsk_… The captured message as JSON

Failed authentication returns the provider's own error shape and status, not ours - SmartPing's AUTH_FAILED, Exotel's RestException, Meta's error.type, SendGrid's errors[]. Your error handling is exercised, not bypassed.

Where a gateway documents several bodies for the same condition, we return the one its own documentation leads with - Twilio's 21211, Route Mobile's 1706, Infobip's REJECTED status group. If your integration depends on a code we do not return, tell us and we will add it.

Deterministic failure triggers

Failures are addressable rather than random, so a test that asserts a bounce is not flaky. Nothing is special-cased beyond these.

ChannelTriggerResult
SMS, WhatsAppRecipient's digits end in 0000 Provider-native rejection, message stored as failed
EmailRecipient starts with fail@ Simulated bounce
PushToken contains fail DeviceNotRegistered (Expo) / UNREGISTERED 404 (FCM)
AllOutage realism profile 503 from every provider surface, so retry and circuit-breaker paths run

What is not emulated

Stated plainly, because finding out later is worse.

Verify this yourself

Do not take the table on trust. The local edition is the same server image this site runs, so every claim above can be checked on your own machine in a few minutes - point your app at it, send what you send in production, and compare the response to your provider's documentation.