Public Beta: Direct engineering support available. Join Discord →
Guides
How do I know if my webhook was delivered?

How do I know if my webhook was delivered?

A webhook was delivered when your endpoint answered the sender with a 2xx status, and the sender's delivery log records that answer for each event. That log proves only that something at your URL said yes. To know on your side, record every event's id the moment it arrives, before any processing, and compare those receipts with the sender's log: an event the sender marked delivered that you hold no receipt for was answered by something that never recorded it.

Compare the sender's log with your receipts

// Compare the sender's delivery log with the ids your endpoint recorded on arrival.
// senderLog: [{ id, status }] where status is the HTTP code the sender got back
// receivedIds: every event id your endpoint recorded before processing
export function compareDeliveries (senderLog, receivedIds) {
  const received = new Set(receivedIds)
  const report = { confirmed: [], answeredButNotRecorded: [], failedAtSender: [] }
  for (const { id, status } of senderLog) {
    if (status < 200 || status >= 300) report.failedAtSender.push(id)
    else if (received.has(id)) report.confirmed.push(id)
    else report.answeredButNotRecorded.push(id)
  }
  return report
}

What each list means

  • confirmed — the sender got a 2xx and your endpoint recorded the event. It arrived.
  • answeredButNotRecorded — the sender got a 2xx but nothing of yours recorded it: a different URL, an old deployment still answering, or a handler that replied before it wrote anything. Find which before trusting any other number.
  • failedAtSender — the sender got an error or no answer. It may retry; if it has stopped, the event is missing until the sender resends it or you replay it from a stored copy.

Delivered, and still nothing happened

Delivered only means your endpoint said yes. If the event arrived and your data did not change, the failure is after the receipt — see My webhook fired. Why is there no data in my database?

Letting a gateway keep the record

A gateway in front of your endpoint keeps both sides of this comparison for you. Slashbin stores every event's raw payload, its signature result and each delivery attempt with its response code, and the Console's delivery log shows them per event.

Need somewhere for the next project's webhooks to land? Slashbin's Free plan takes an account, not a card.

Start Free

(opens in a new tab)

Related