Skip to content

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

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.