Webhook Delivery Problems
Webhooks are managed on Settings → Webhooks: click your name in the top right of the dashboard, then Webhooks under Developer. It is a main-account page, and webhooks need a paid plan.
Symptom: Webhook not receiving events
- Confirm the webhook has the right Type: Order Item (Recipient) Status Update, Order Status Update, Order Item (Recipient) Delivered, or QR Code Scan Notification. Each webhook has one type; add one webhook per type you need.
- Confirm the endpoint URL is publicly accessible - webhooks cannot reach
localhostor internal network addresses. - Use Send Test in the webhook's menu to send a test event to your endpoint. The dashboard confirms the test as sent even if your endpoint rejects it, so check your endpoint's logs to see that it arrived.
- Check the webhook's Mailing List and Subaccount fields. A webhook with a mailing list chosen only fires for orders sent to that list, and one with a subaccount chosen only fires for that subaccount's orders. Set either to None to widen it.
Symptom: Receiving duplicate events
thanks.io delivers at-least-once. Return a 2xx response as quickly as possible, and make your consumer idempotent - store the event ID and skip processing if you've already handled it.
Symptom: Payload missing expected fields
- Review the full payload structure for each event type at docs.thanks.io.
- Log the raw incoming payload and compare to the documented schema.
- Use Send Test in the webhook's menu to capture a sample payload.
Symptom: Endpoint returning 4xx/5xx and events not retrying
- Fix the underlying error in your endpoint. Check your server logs.
400 Bad Requestusually means a parser mismatch - verify your endpoint parsesapplication/json.401/403means your endpoint is enforcing auth - remove it for the webhook path.- Once your endpoint is healthy, send a test event to confirm delivery is restored.
Symptom: Wrong account events being received
All webhooks belong to the main account. A webhook with Subaccount set to None receives events from the main account and every subaccount; each payload's order.sub_account_id says which one it came from. To send one subaccount's events to its own endpoint, edit the webhook (or add another) and choose that subaccount in Subaccount.
Symptom: Birthday or thank-you campaign webhook not firing
- Confirm the campaign is actively sending. Open Campaigns, click the campaign, and check that the action reads Running.
- Confirm the correct webhook type is set up: Order Item (Recipient) Status Update (fires as each piece's status changes) or Order Item (Recipient) Delivered (fires on delivery). Birthday/holiday campaigns create orders just like any other campaign, so the same webhook events fire.
- If the campaign belongs to a subaccount, confirm the webhook's Subaccount is None or that subaccount, and that its Mailing List (if set) is the campaign's list.
- Check your webhook endpoint with Send Test to confirm it receives events.
- If the campaign has never fired at all, check Campaign Not Triggering first.