Webhook Endpoint

A Stripe webhook endpoint is the public HTTPS URL where Stripe delivers events to your server. Learn how to set one up and how to keep it healthy.

Updated October 1, 2026

A webhook endpoint is the URL on your server that receives a Stripe webhook. Stripe sends it a POST for each event, and your code turns the event into an action in your app. When someone says "our Stripe webhook is down," they usually mean this URL and the code behind it.

How to set up a Stripe webhook endpoint

In Stripe, a webhook endpoint is one kind of event destination. To create one in the Dashboard:

  1. Open the Webhooks tab in Workbench and choose to create an event destination.
  2. Pick whose events you want. Most accounts choose their own account. Stripe Connect platforms can also listen to connected accounts.
  3. Pick the API version and the event types, such as payment_intent.succeeded or charge.dispute.created.
  4. Choose Webhook endpoint as the destination type and enter your URL.
  5. Copy the signing secret that starts with whsec_. Your code needs it to verify deliveries.

You can do the same with the /v2/core/event_destinations API. For local development, the Stripe CLI forwards events to your machine with stripe listen --forward-to localhost:4242/webhook and prints its own signing secret.

What Stripe stores for each endpoint

  • The URL. It must be a publicly reachable HTTPS address, such as https://yourapp.com/stripe_webhooks. Stripe only connects over TLS 1.2 or 1.3.
  • The enabled events. The event types this endpoint receives.
  • An API version. Stripe renders snapshot events in this version. An event never changes shape after Stripe creates it.
  • A signing secret. A whsec_ value unique to the endpoint, used for signature verification. Test and live traffic to the same URL use different secrets.
  • A scope. Your own account, or connected accounts for Connect platforms.

An account can register up to 16 webhook endpoints. Some teams send everything to one. Others split billing events and disputes across two, so a bug in one handler doesn't hold up the other.

Why endpoint health matters to the business

A slow or failing endpoint does more damage than a noisy log.

  • Retries pile up. In live mode Stripe retries a failed delivery for up to three days with exponential backoff. When the endpoint recovers, it gets a burst of old events and has to process them without doing anything twice.
  • Invoices stall. If Stripe doesn't get a successful response to invoice.created, it delays finalizing invoices with automatic collection for up to 72 hours. Customers are charged late, so cash arrives late.
  • Missed events expire. You can resend an event from the Dashboard for up to 15 days after it was created, or with the Stripe CLI for up to 30 days. After that you rebuild state from the API.
  • The warning goes to one inbox. Stripe emails you when a webhook is failing. If that inbox belongs to a developer on holiday, nobody notices.

Load matters too. Stripe notes that the start of the month, when subscriptions renew, can bring a large spike in deliveries. A handler that does heavy work before responding can fail when the most money is moving.

Keeping an endpoint healthy

For engineering:

  1. Return 200 first, then process. Stripe's guidance is to respond before any complex logic, such as marking an invoice paid in your accounting system.
  2. Put events on a queue and process them at a rate your system can handle.
  3. Store processed event IDs and skip repeats. Don't assume events arrive in order.
  4. Exempt the route from CSRF protection if your framework adds it, and register the final URL, because Stripe treats redirects as failed deliveries.
  5. Roll the signing secret now and then. Stripe lets you keep the old secret active for up to 24 hours while you deploy the new one.

For founders, find out who receives Stripe's failing-webhook emails. After any deploy that touches billing code, ask for a look at the endpoint's Event deliveries tab in Workbench.

Do you need your own endpoint?

You need one if Stripe events drive product behavior, such as granting access after invoice.paid, fulfilling orders, or syncing records to your database. You don't need one only to know what's happening in your account.

ChargeBell connects through Stripe's read-only OAuth and receives events on its side, so there's no endpoint, secret, or retry logic for you to run. It posts plain-English Slack alerts, such as a failed payment with the decline reason or a new dispute with the amount and reason, to the channels you choose. The Free plan includes 50 real-time alerts a month, and Pro is $24 a month for unlimited alerts. The Stripe Slack integration page shows how it works.

Get alerted in Slack

Stripe events: invoice.created, invoice.paid, payment_intent.succeeded, charge.dispute.created

ChargeBell posts Stripe events to the Slack channel you pick, written in plain English.

Related terms