How It Works
Transyt processes every webhook through a reliable 7-step pipeline. Each step is designed to ensure no webhook is lost, even when your application is temporarily unavailable.
The Webhook Flow
Section titled “The Webhook Flow”Provider → Ingest → Verify → Deduplicate → Deliver → Retry → Alert → ReplayStep 1: Webhook Arrives
Section titled “Step 1: Webhook Arrives”Your provider sends a POST request to Transyt’s ingestion endpoint:
POST https://ingest.transyt.com/{provider}/{account_slug}The raw payload and headers are immediately persisted to PostgreSQL before returning a 200 OK response. This ensures no data is lost, even if subsequent processing fails.
Step 2: Signature Verified
Section titled “Step 2: Signature Verified”Transyt applies the provider-specific signature verification algorithm:
| Provider | Algorithm |
|---|---|
| Stripe | HMAC-SHA256 with timestamp |
| Twilio/SignalWire | HMAC-SHA1 / HMAC-SHA256 |
| Mailgun | HMAC-SHA256 (body fields) |
| Resend | Svix HMAC-SHA256 |
| SES/SNS | RSA certificate validation |
| Lob | HMAC-SHA256 with timestamp |
| Linear | HMAC-SHA256 |
| Ramp | HMAC-SHA256 |
Invalid signatures result in a 401 rejection. The event is still stored with a rejected status for debugging purposes.
Step 3: Event Deduplicated
Section titled “Step 3: Event Deduplicated”Each event is assigned a provider-specific external ID (e.g., evt_xxx for Stripe). A unique database constraint on (provider_account_id, external_id) prevents duplicate storage.
When a provider retries a webhook that Transyt has already received, the duplicate is silently skipped — but Transyt still returns 200 OK to the provider so it stops retrying.
Step 4: Delivered to Your App
Section titled “Step 4: Delivered to Your App”If a delivery_url is configured, Transyt immediately POSTs the event to your application:
{ "event_id": "550e8400-e29b-41d4-a716-446655440000", "provider": "stripe", "account_slug": "my-app", "event_type": "charge.succeeded", "external_id": "evt_1234567890", "payload": { "...original webhook payload..." }}With headers X-Gateway-Signature and X-Gateway-Timestamp for verification.
A 2xx response from your app marks the delivery as successful.
Step 5: Retry on Failure
Section titled “Step 5: Retry on Failure”If your app returns a non-2xx status code or is unreachable, Transyt retries with exponential backoff:
| Attempt | Delay |
|---|---|
| 1 | ~10 seconds |
| 2 | ~20 seconds |
| 3 | ~40 seconds |
| 4 | ~80 seconds |
| 5 | ~2.5 minutes |
| 6 | ~5 minutes |
| 7 | ~10 minutes |
| 8 | ~20 minutes |
| 9 | ~40 minutes |
| 10 | ~1 hour 20 min |
Each attempt is logged with the response code, response body, and error message. After 10 attempts, the event is marked as failed.
Step 6: Alert on Failure
Section titled “Step 6: Alert on Failure”When delivery is exhausted, configured destinations are triggered. These can send notifications via:
- Email — via Amazon SES
- Slack — via incoming webhook
- Discord — via webhook
- Webhook — to any URL
Destinations support conditional routing, so you can alert only for specific event types or providers.
Step 7: Replay When Ready
Section titled “Step 7: Replay When Ready”Failed events can be replayed from the dashboard or via the API:
curl -X POST https://ingest.transyt.com/admin/events/{event_id}/replay \ -H "X-Admin-Token: YOUR_ADMIN_TOKEN"The replayed delivery uses the exact original payload, making it indistinguishable from a fresh delivery to your application.