Skip to main content
Darwin delivers each event at least once, retries for about three days and keeps every event for 30 days. This page covers what your receiver has to do and how to recover when it was down.

Answer quickly

  • Answer with any 2xx status within 10 seconds. Anything else counts as a failure: a 3xx (Darwin does not follow redirects), a 4xx, a 5xx, a timeout or a refused connection.
  • Answer first and do slow work (CRM calls, Slack posts) afterwards in a queue. A receiver that waits on another service is the most common cause of timeouts.
  • Darwin reads at most the first 64 KB of your answer and keeps the first 500 characters in the delivery log. Don’t return anything secret.

Handle duplicates and order

  • At least once. Darwin may deliver the same event more than once, for example when your server handled it but the answer was lost. webhook-id (the event id) is the same on every retry and redelivery. Record the ids you’ve processed and skip repeats.
  • No ordering. Events can arrive out of order, especially after retries. A meeting.rescheduled can arrive before its meeting.booked. Use created_at, or the object’s updated_at, to decide which is newer, or read the current object from the API.

Retries

If a delivery fails, Darwin tries again after: That is nine attempts over about three days. After the last one the delivery is marked Failed. You can still send it again by hand for 30 days.

Endpoints that keep failing are switched off

If an endpoint has failures and not one successful delivery for three days, and is still failing, Darwin switches it off and shows why under its address in Integrations → API: Deliveries have failed for three days without one success. Fix the receiver, then switch the endpoint back on. An endpoint that answers 410 Gone is switched off at once: that is how a receiver (Zapier, for one) says the subscription is over. Its badge turns from Failing to Off, and GET /webhook_endpoints/{id} shows "status": "disabled" with a disabled_reason. While an endpoint is off, Darwin does not queue new events for it. To recover:
  1. Fix your receiver and check it with Send test event.
  2. Open the endpoint’s ⋯ menu and select Switch on (or PATCH it with {"status": "enabled"}). Deliveries that were still retrying continue.
  3. Send the events you missed: use Send again in Deliveries, or read GET /events for the gap and redeliver them.
You can also select Switch off yourself, for example during maintenance. Events stay in the event log for 30 days.

Check deliveries and send again

Open the endpoint’s ⋯ menu and select Deliveries. Each row shows the event type, whether it was Delivered, is Retrying or Failed, the number of attempts, your server’s last HTTP status or error, and the next try. Send again puts that delivery back in the queue; it goes out within a few seconds. The endpoint row also summarises this week: how many were delivered, failed and are retrying. With the API:
The redeliver response says how many deliveries were queued. Only enabled endpoints subscribed to the event’s type receive it.

Catch up with the event log

Every event from the last 30 days is in GET /events (scope events:read), newest first. It is the pull twin of webhooks: use it after downtime, or instead of webhooks if you would rather poll.
Each item is the same event body a webhook sends.

Troubleshooting

Check that you verify the raw body, not parsed and re-serialised JSON, and that you base64-decode the secret after removing whsec_. Frameworks that parse JSON automatically need a raw-body route, like express.raw in Verify signatures.
Your URL answered with a 3xx. Use the final address, including https:// and the exact path, often with or without a trailing slash.
Answer 200 before doing the work. Check that your server is reachable from the public internet and not behind a login or firewall.
Preview chats in Darwin never send events. Use Send test event, or have someone use the chat on your live website.
Send handoffs to Slack → · Sync leads to a CRM →