Stripe setup guide
How to put Webhook Inbox between Stripe and your existing webhook handler. ~5 minutes. No handler code changes.
What you'll have at the end
- Stripe sends webhooks to
https://inbox.sidelabs.dev/ingest/stripe/<source_id>. - We verify the signature, store the raw event, then forward it to your existing handler.
- If your handler fails, the event sits in the inbox until auto retry succeeds or you replay it manually.
- Your handler code does not change.
Before you start
You need:
- Your Stripe webhook signing secret (
whsec_...) — Stripe Dashboard → Developers → Webhooks → your endpoint → "Signing secret". - Your existing webhook handler URL (the one Stripe currently sends to).
- An admin token for Webhook Inbox — we hand this out per pilot. Email support@sidelabs.dev.
1. Create your source
A "source" pairs a Stripe signing secret with the destination URL we will forward to.
curl -X POST https://inbox.sidelabs.dev/api/sources \
-H "Authorization: Bearer $INBOX_ADMIN_TOKEN" \
-H "Content-Type: application/json" \
--data '{
"id": "src_acme_stripe",
"signing_secret": "whsec_replace_me",
"destination_url": "https://api.acme.com/stripe-webhook",
"timeout_ms": 10000
}'
The id is your choice (snake_case, alphanumerics + underscores). Pick something stable — the ingest URL will use it.
The signing secret is stored in Postgres on the SideLabs server and never logged.
2. Point Stripe at the inbox
In the Stripe Dashboard:
- Go to Developers → Webhooks.
- If you have an existing endpoint pointing at your handler, edit it. Otherwise add a new one.
- Set the URL to
https://inbox.sidelabs.dev/ingest/stripe/src_acme_stripe. - Select the events you care about (or "Send all events" — Webhook Inbox forwards everything we receive).
- Save. Stripe shows a fresh signing secret. If it differs from the one in step 1, repeat the
POST /api/sourcescall with the new secret.
3. Verify the round trip
Send a test event from Stripe (Developers → Webhooks → your endpoint → "Send test webhook"), then open the dashboard:
https://inbox.sidelabs.dev/app/
You should see one event with delivery_status: delivered (assuming your handler returned 2xx). If it's failed, the detail panel shows the response body and timing — and the Replay button forwards the same body and headers to your destination again.
4. Confirm verification works
To prove the signature check is real, push a malformed payload to the ingest URL:
curl -X POST https://inbox.sidelabs.dev/ingest/stripe/src_acme_stripe \
-H "Stripe-Signature: t=1,v1=bad" \
-H "Content-Type: application/json" \
--data '{"id":"evt_fake","type":"charge.succeeded"}'
Expected: 400 Bad Request. The dashboard will show the request as verification_status: failed, delivery_status: failed, and your destination is not called for unverified payloads. We keep these rows so you can prove tamper attempts in audit.
What gets forwarded
| Field | Behavior |
|---|---|
| Body | Forwarded byte-for-byte (no re-serialization). |
| Stripe-Signature | Forwarded unchanged. |
| Content-Type | Forwarded unchanged. |
| X-Inbox-Event-Id | Added by us. Stable id you can use for idempotency. |
| X-Inbox-Source-Id | Added by us. Equal to the source id from step 1. |
| Cookies, auth headers | Stripped. Stripe never sets them; we do not relay. |
Auto retry
When the destination returns non-2xx, times out, or the network errors:
- The event is marked
failed. - A background worker retries on backoff: 1m, 5m, 15m, 1h, 4h (5 attempts).
- Each retry writes a new row to the delivery-attempts timeline. The original event is never mutated.
Pause auto retry for a single event:
curl -X PATCH https://inbox.sidelabs.dev/api/events/<event_id>/retry \
-H "Authorization: Bearer $INBOX_ADMIN_TOKEN" \
-H "Content-Type: application/json" \
--data '{"enabled":false}'
Pause for the entire source (e.g. during a planned outage):
curl -X PATCH https://inbox.sidelabs.dev/api/sources/src_acme_stripe/retry \
-H "Authorization: Bearer $INBOX_ADMIN_TOKEN" \
-H "Content-Type: application/json" \
--data '{"enabled":false}'
Resume with {"enabled":true}.
Manual replay
curl -X POST https://inbox.sidelabs.dev/api/events/<event_id>/replay \
-H "Authorization: Bearer $INBOX_ADMIN_TOKEN"
Or click Replay on the event detail panel in the dashboard. The stored body and headers are forwarded again; a new delivery attempt is appended.
What it does not do (yet)
- Outbound webhooks (sending events from your app to customers).
- Workflow / transformation engine.
- Provider transforms. Stripe and Shopify are accepted as raw, verified inbound events; your handler keeps its existing parsing logic.
- Multi-tenant SaaS auth — single workspace per deployment for now.
Common questions
Does this introduce a single point of failure?
Yes. If Webhook Inbox is down, Stripe will retry on its own schedule for up to 3 days. Our SLO target is 99.95%; we'll publish the live numbers once we have 30 days of production data.
What if I want to roll back?
Change the Stripe endpoint URL back to your handler. The signing secret on your side hasn't changed, so it works immediately.
Where does data live?
On the SideLabs server hosting inbox.sidelabs.dev (Frankfurt). For self-hosted, see the self-hosted tier on the pricing page.