VantageKitVantageKit Docs

Webhook Reliability

Retry logic, dead-letter queue, health monitoring, and best practices for reliable webhook handling.

Delivery guarantees

VantageKit delivers webhooks with at-least-once semantics. Events may be delivered more than once during retries — your endpoint should be idempotent.

Retry schedule

If your endpoint returns a non-2xx status or times out, VantageKit retries with exponential backoff:

AttemptDelayTotal elapsed
1st retry1 second~1 second
2nd retry2 seconds~3 seconds
3rd retry4 seconds~7 seconds
4th retry8 seconds~15 seconds
5th retry16 seconds~31 seconds

After 5 failed attempts, the delivery is moved to the dead-letter queue.

What counts as a failure

ResponseResult
HTTP 2xxSuccess — delivery complete
HTTP 4xx (except 429)Permanent failure — no retry, moved to dead-letter
HTTP 429Retryable — follows the retry schedule
HTTP 5xxRetryable — follows the retry schedule
Timeout (>10 seconds)Retryable — your endpoint must respond within 10 seconds
Network errorRetryable — DNS failure, connection refused, etc.

Dead-letter queue

Deliveries that exhaust all retry attempts or receive a non-retryable error are moved to the dead-letter queue. You can view dead-lettered deliveries in Settings > Webhooks > [endpoint] > Delivery Log with status dead_letter.

Endpoint health status

VantageKit monitors your endpoint's health:

StatusMeaning
HealthyDeliveries are succeeding
Unhealthy5 consecutive delivery failures
DisabledEndpoint manually disabled

When an endpoint becomes unhealthy, deliveries continue to be attempted. A single successful delivery resets the status to healthy.

Delivery timeout

Your endpoint must return a response within 10 seconds. If you need to do heavy processing:

Respond first, process later
app.post('/webhooks/vantagekit', async (req, res) => {
  // Verify signature first (fast)
  if (!verifySignature(req)) {
    return res.status(401).send('Invalid signature')
  }

  // Acknowledge receipt immediately
  res.status(200).send('OK')

  // Process asynchronously (queue, background job, etc.)
  const event = JSON.parse(req.body.toString())
  await queue.add('process-webhook', event)
})

Response handling

  • VantageKit reads up to 16 KB of your response body
  • Up to 1,000 characters of the response are stored in the delivery log for debugging
  • Only the HTTP status code determines success (2xx) or failure — the body is for logging only

Stuck delivery protection

If a delivery stays in processing status for more than 5 minutes (e.g., due to a crash during processing), it's automatically reset to pending and retried.

Best practices

  • Return 200 quickly — Acknowledge receipt within 10 seconds, process asynchronously
  • Be idempotent — Use X-VantageKit-Delivery ID to deduplicate
  • Don't return 4xx for transient errors — Return 5xx or 429 so VantageKit retries
  • Monitor your endpoint — Check the delivery log in Settings for failures
  • Handle all event types gracefully — If you receive an event type you don't handle, return 200 (not 400)

On this page