Technical overview

How Transyt works

From the moment a webhook arrives to the moment you replay it six months later. Every step logged, every payload stored, every failure explained.

1

Webhook arrives

Your provider sends a webhook to your Transyt endpoint. We accept the request immediately and return 200 OK to the provider.

The webhook is written to PostgreSQL before we respond. If we accepted it, it's stored. No race conditions, no lost events.

POST https://ingest.transyt.com/stripe/acme-prod
Content-Type: application/json
Stripe-Signature: t=1704067200,v1=5257a...

{"id": "evt_1234", "type": "invoice.paid", ...}
2

Signature verified

We validate the webhook signature using the provider's specific algorithm. Stripe uses HMAC-SHA256. Twilio uses request signing. Each provider is different.

Invalid signatures are rejected with 401 and logged. Valid webhooks proceed to delivery. You can optionally skip verification for providers that don't sign.

# Stripe: HMAC-SHA256 with timestamp
expected = HMAC-SHA256(webhook_secret, timestamp + "." + payload)
# Twilio: Request URL signing
# AWS SNS: Certificate validation
# Mailgun: HMAC-SHA256 with timestamp
3

Event deduplicated

Before processing, we check if we've seen this event before. Providers sometimes send duplicates — during retries, infrastructure issues, or edge cases.

Deduplication is enforced at the database level with a unique constraint on (account, provider_event_id). If we've seen it, we skip delivery but still return 200 to the provider.

-- PostgreSQL unique constraint
CREATE UNIQUE INDEX idx_events_dedup
ON events (account_id, provider_event_id);

-- Duplicate insert → no-op, not error
4

Delivered to your app

We POST the verified payload to your configured endpoint. Your app processes it and returns a response. 2xx means success. Anything else triggers retry.

We forward the original payload with additional headers: X-Transyt-Event-Id (our ID), X-Transyt-Signature (our signature), and X-Transyt-Delivery-Attempt (attempt number).

POST https://your-app.com/webhooks/stripe
Content-Type: application/json
X-Transyt-Event-Id: evt_01HQXK7Y2Z...
X-Transyt-Signature: t=1704067201,v1=8f3a2...
X-Transyt-Delivery-Attempt: 1

{"id": "evt_1234", "type": "invoice.paid", ...}
5

Retry on failure

If delivery fails (timeout, 5xx, network error), we retry with exponential backoff. 10 attempts over roughly 4 hours before we mark it as failed.

Retry schedule: 10s, 30s, 1m, 5m, 15m, 30m, 1h, 2h, 4h, 4h. Each attempt is logged with response code, timing, and any error message.

Attempt 1:  immediate     → 503 Service Unavailable
Attempt 2:  +10 seconds  → 503 Service Unavailable
Attempt 3:  +30 seconds  → 503 Service Unavailable
Attempt 4:  +1 minute    → 200 OK ✓

Total time: 1m 40s
Delivery status: DELIVERED
6

Alert on failure

After a configurable number of failed attempts (default: 3), we notify you via email or Slack. You'll know something is wrong before it becomes a crisis.

Alerts include the event ID, provider, error message, and a direct link to the event in your dashboard. Daily digests summarize all failures from the past 24 hours.

🚨 Webhook delivery failing

Event: evt_01HQXK7Y2Z...
Provider: Stripe
Type: invoice.paid
Attempts: 3/10
Last error: Connection timeout

View event: https://app.transyt.com/events/evt_01HQXK7Y2Z
7

Replay when ready

Once you've fixed the issue, replay the event with one click. We'll re-deliver the exact payload that was originally received. No data loss, no guessing.

Replay uses the stored payload — headers, body, everything. It's indistinguishable from a fresh delivery except for the X-Transyt-Delivery-Attempt header.

# Original delivery failed at 2024-01-15 09:23:17
# You deployed a fix at 2024-01-15 10:45:00
# One-click replay at 2024-01-15 10:46:12

POST https://your-app.com/webhooks/stripe
X-Transyt-Event-Id: evt_01HQXK7Y2Z...
X-Transyt-Delivery-Attempt: 11  # indicates replay

→ 200 OK ✓

The result

Zero lost webhooks

Stored before forwarded. Even if your app is down for hours, every event is waiting when you come back online.

Complete audit trail

Every payload, header, and delivery attempt logged. Query by time, provider, status, or event type. Export anytime.

Clear accountability

When something fails, you'll know exactly what, when, and why. No more "the webhook never arrived" debates.

See it in action

Set up in 5 minutes. Point your provider at Transyt, we'll handle the rest.

Start free