Skip to main content
Target vendor: Twilio REST API. Webhook signing: HMAC-SHA1 with the X-Twilio-Signature header. Payloads are form-encoded, matching Twilio’s exact format.

Mirror URL

https://twilio-<session_id>.mirra.run
Example: https://twilio-a7k2.mirra.run.

SDK compatibility

Official Twilio SDKs work against the mirror with zero code changes:
import twilio from 'twilio';

const client = twilio(
  process.env.TWILIO_ACCOUNT_SID,
  process.env.TWILIO_AUTH_TOKEN,
);

const message = await client.messages.create({
  from: '+15555550123',
  to:   '+15555550199',
  body: 'Your code is 424242.',
});
// → routed to twilio-a7k2.mirra.run

Supported surface

Resources

Send, retrieve, list. Status transitions (queued → sending → sent → delivered / failed / undelivered). Media attachments.
Start verification, check verification. Channels: sms, call, email. Code delivery tracking. Retry limits per Twilio’s exact policy.
Search available numbers, provision, list, release. Capabilities (SMS, MMS, voice). Incoming number configuration.
Create, update, retrieve. Sender pool management. Country and compliance configuration.

Status callbacks

Twilio fires status callbacks on message state changes. The mirror fires them with vendor-correct HMAC-SHA1 signatures and Twilio’s form-encoded payload shape:
  • queued — on create
  • sending — immediately after
  • sent — a few seconds later (configurable per fixture)
  • delivered — after that
  • failed / undelivered — if the fixture or simulate triggers it
Signing uses Twilio’s exact scheme:
X-Twilio-Signature: HD/vEfkS7yLmBDVE1Lf8C4HHuAE=
Content-Type: application/x-www-form-urlencoded
Verify with Twilio’s SDK, no changes:
import twilio from 'twilio';

const valid = twilio.validateRequest(
  process.env.TWILIO_AUTH_TOKEN,
  req.headers['x-twilio-signature'],
  fullWebhookUrl,
  req.body,
);

Built-in fixtures

No phone numbers, no messages. A blank Twilio account.
Two verified phone numbers for sending: +15555550123 and +15555550124. Good for testing your outbound flow without provisioning.
Configured messaging service with a sender pool of 5 numbers. Good for testing services that fan out across sender pools.
Verify service pre-configured with SMS channel and sensible retry limits. Good for testing OTP flows.
Account that returns 429 after 10 sends per minute, matching Twilio’s trial-account throttle. Good for testing rate-limit handling.
Load a fixture:
mirra up --mirrors=twilio --seed=twilio:verify-flow

Coverage gaps

  • Voice / TwiML — not yet mirrored.
  • Conversations API — not yet mirrored.
  • Studio (workflow builder) — not yet mirrored.
  • Twilio SendGrid — use the SendGrid mirror (Months 3–6 roadmap).
  • Carrier-specific routing — simplified to a single delivery timeline per fixture; no real carrier-level behavior.
See status.mirra.run/twilio for the live list.

Simulating events

# Force a message to fail delivery
curl -X POST https://twilio-a7k2.mirra.run/_mirra/simulate \
  -H "Content-Type: application/json" \
  -d '{ "event": "message.failed", "messageId": "SM_abc", "errorCode": 30003 }'

# Force an OTP check to fail
curl -X POST https://twilio-a7k2.mirra.run/_mirra/simulate \
  -H "Content-Type: application/json" \
  -d '{ "event": "verify.check_failed", "sid": "VE_xyz" }'
See API reference for the full event list.

Where to go next

Resend

The email mirror.

Stripe

The payments mirror.