verification
use it
# add to stunt.yaml
services:
sendgrid:
adapter: embedded:sendgrid-style
# then
$ stunt upThe embedded: source extracts this adapter from the binary — no git clone, fully offline.
how to mock the Twilio SendGrid v3 API locally
Install stunt, paste the service block above into stunt.yaml, run stunt up — then point your client at localhost instead of Twilio SendGrid v3 API. It works offline, keeps state across requests and restarts, and every response is synthetic: the route shapes, status codes, pagination, and webhook delivery follow the real Twilio SendGrid v3 API v3 surface — the data is fake, the behavior is real.
backing stores
mail
api surface (5)
generated from the adapter manifest — exactly what boots, nothing more · covers 15% of the real API's 26 routes (derived from spec sendgrid-oai tsg_mail_v3 + tsg_email_activity_v3 + tsg_webhooks_v3 @ 1.0.0, 1.0.0, 1.0.0)
5 routes
POST/v3/mail/send
GET/v3/messages
POST/v3/user/webhooks/event/settings
GET/v3/user/webhooks/event/settings
POST/v3/user/webhooks/event/test
VM-verified behaviors (7)
- ✓the bearer gate rejects missing and unknown keys with SendGrid's grant envelope
- ✓mail send answers 202 with an empty body, an X-Message-Id, and flattened personalizations
- ✓the retrieval endpoint pages with limit and the opaque offset cursor
- ✓the delivery lifecycle derives processed -> delivered (or dropped) on read, exactly once
- ✓the Email Activity query language narrows the list
- ✓event webhook settings round-trip and require a URL when enabled
- ✓deliveries are ECDSA P-256 signed over timestamp + raw body and fire once per recipient stage
Not implemented (7)
- No single-message fetch (GET /v3/messages/{msg_id})
- No GET of event-webhook settings (POST-only)
- No suppression lists (bounces, blocks, invalid emails, spam reports)
- No scheduled-send management (/v3/scheduled_sends)
- No API keys management (/v3/api_keys)
- No sender authentication or domains setup
- No templates surface (/v3/templates)
Differs from the real API (6)
- Webhook ECDSA signature is raw r||s (64 bytes), not Twilio ASN.1 DER encoding
- simulate_fail: true in send body forces dropped terminal (simulator extension)
- delivered derives at fixed +3s on first list read, not real async delivery
- Email Activity query subset: =, !=, CONTAINS terms AND-ed over six fields
- Each delivery wraps one event in the transport envelope; real SendGrid batches a JSON array of events
- asm, sandbox_mode, and batch_id are accepted but not modeled
want more of the Twilio SendGrid v3 API surface? adapters are YAML + Starlark — the authoring guide covers adding routes, fixtures, and state machines. Open an issue for anything big first, or just file a PR — merged routes ship in the next release.