A webhook is a URL on your server that we call whenever something happens in your account - a plan change, a payment failure, a new family member, and so on. Instead of you polling our API to ask "has anything changed?", we push the change to you the moment it happens.
You only need to host a small endpoint that accepts a POST with JSON.
Add an endpoint
In Settings -> Webhooks, click + Add endpoint and paste the public URL where we should send events. It must be HTTPS in production.
Pick which events you want. You can always change the list later from the same page.
When you create the endpoint, we show your signing secret
once
. Copy it immediately and store it in a password manager or environment variable. If you lose it, delete the endpoint and create a new one.
Verify the signature
Every request we send carries three headers:
X-Webhook-Event - the event name
X-Webhook-Timestamp - unix seconds when we sent it
X-Webhook-Signature - HMAC-SHA256(timestamp + "." + raw_body) using your secret
Always verify the signature before trusting the payload.
What a payload looks like
Every event has the same envelope - event, event_id, occurred_at, and a data object specific to the event. If you receive several deliveries with the same event_id, that is a fanout - the same event going to multiple endpoints. Use it to deduplicate if your endpoint is registered more than once.
Test before you trust it
Use Send test on any endpoint to fire a synthetic webhook.test event right away. Open Deliveries to confirm your server replied with a 2xx.
For local development, use a tunnel like ngrok or cloudflared so we can reach http://localhost. You can also point at https://webhook.site while you wire things up.
Retries and observability
If your endpoint returns anything other than 2xx, we retry with exponential backoff up to 5 attempts. After that we stop and mark the delivery as failed - hit Retry manually from the deliveries list to try again. Click any delivery to see every attempt: timing, request headers we sent, and the full response your server returned. Bodies are captured up to 64 KB.