Webhooks
Vespy receives webhooks; it does not currently send them. The endpoints below are called by third-party providers, not by API clients, and none of them accept a bearer token — each authenticates by that provider’s own signature scheme.
They are documented for operators configuring a deployment. If you are building against the API and want change notifications, use server-sent events instead.
| Endpoint | Provider | Authenticated by |
|---|---|---|
POST /api/webhooks/stripe |
Stripe | Stripe-Signature header against the endpoint signing secret |
POST /api/webhooks/email/inbound |
Resend | Svix headers (svix-id, svix-timestamp, svix-signature) |
POST /api/webhooks/email/ses-inbound |
Amazon SES | SNS message signature |
POST /api/webhooks/sms/inbound |
Twilio | X-Twilio-Signature against the account auth token |
POST /api/webhooks/sms/status |
Twilio | X-Twilio-Signature against the account auth token |
POST /api/webhooks/sms/sns-inbound |
Amazon SNS | SNS message signature |
POST /api/webhooks/gmail/pubsub |
Google Pub/Sub | Verification token in the push subscription URL |
Behaviour
Section titled “Behaviour”Signature failures return 401. A receiver never processes a payload it could not
verify, and the failure is logged with the delivery identifiers.
Delivery is idempotent. The Stripe receiver records each event id before processing
and answers a replay with {"received": true, "duplicate": true}. Providers that retry on
timeout will not double-apply anything.
Processing is asynchronous. Receivers acknowledge quickly and hand the payload to a
worker, so a 200 means accepted, not applied.
202 means accepted but not matched. The SMS status callback returns 202 when the
message id does not correspond to anything Vespy sent — expected when a number is shared
with another system.
503 means unconfigured. A receiver whose secret is not set on the deployment returns
503 rather than silently accepting unverified traffic.