POST to when something happens in your account. Registering one takes a minute in the dashboard. Writing a handler that stays correct under retries takes a little more care, and this page covers both.
Registering a webhook endpoint
1
Open Webhooks
In the dashboard, go to Developers and open the Webhooks section, or run
flexprice open webhooks from the CLI.2
Add the endpoint
Click Add Endpoint and enter your URL. It must be HTTPS and reachable from the public internet. For local development, use a tunnel or Svix Play as described in Test webhooks locally.
3
Choose events
Subscribe to the events your handler acts on rather than everything. A billing integration usually starts with:
invoice.update.finalizedinvoice.update.paymentpayment.successandpayment.failedsubscription.created,subscription.updated, andsubscription.cancelledwallet.credit_balance.dropped
4
Copy the signing secret
Open the endpoint and copy its signing secret (it starts with
whsec_). Store it with your other secrets. Your handler uses it to verify every delivery; see Signature verification.The webhook delivery contract
A finalized invoice looks like this:
Writing the webhook handler
A handler has four jobs, in this order:- Verify the signature on the raw body before parsing anything.
- Acknowledge fast. Return
200and do the real work on a queue. Anything slower than 5 seconds counts as a failure and is retried. - Dedupe. Store the delivery ID (the
svix-idheader) and skip a delivery you have already processed. Retries and redeliveries mean you will see duplicates. Do not key on the object ID plusevent_typealone: twosubscription.updatedmessages for the same subscription would collapse into one. If you key on the object, include itsupdated_at. See Retries and ordering. - Return
200for events you do not handle. Otherwise Flexprice keeps retrying them.
event_type and the typed payload. Parsing webhook payloads with the SDK shows the typed models in Go, Python, and TypeScript.

