Where events arrive
pre.dev posts each event toPOST /api/stripe/webhook on your app, at the live sandbox URL while you build and at the deployed URL once deployed. Mount your handler on exactly that path.
The request looks exactly like one from Stripe: a JSON event body and a Stripe-Signature header. Verify it with the Stripe SDK and STRIPE_WEBHOOK_SECRET, which is this project’s own secret.
Which events
Every event Stripe emits for your workspace’s account is relayed. Handle the ones you need and return2xx for the rest. Typical ones for subscriptions are checkout.session.completed, invoice.paid, invoice.payment_failed, and customer.subscription.updated or deleted.
Retries and pausing
A delivery that fails with a timeout or a5xx is retried with backoff for about 45 minutes. A 4xx other than 408 or 429 is not retried.
If your app answers 404 at the webhook path three times in a row, deliveries to that project pause. They resume the next time the app makes a Stripe call through pre.dev, so mounting the route and reloading is enough.
Do not register an endpoint
Callingstripe.webhookEndpoints.create through the built-in key returns a 400 that explains delivery is built in. Your own Stripe dashboard is not involved while in test mode.
Testing a flow end to end
- Start a Checkout session in your app and pay with
4242 4242 4242 4242. - Watch the server log for
checkout.session.completedarriving at/api/stripe/webhook. - Confirm your handler did its work, for example a row marked paid.

