Delivery & retries
This page describes what happens after an external service POSTs to your webhook URL: the responses Alfe returns, how duplicates are handled, and how events reach an agent that isn’t currently online.
Response codes
Section titled “Response codes”Alfe replies to the sending service as soon as it has accepted (or rejected) the delivery:
| Status | Meaning |
|---|---|
200 OK |
The event was accepted. The body includes a deliveryId. |
401 Unauthorized |
The X-Alfe-Signature-256 header was missing or the signature didn’t match. |
404 Not Found |
No active webhook exists at that URL (unknown or deactivated). |
502 Bad Gateway |
The event was authentic but couldn’t be accepted for delivery; the sender should retry. |
A successful response looks like:
{ "received": true, "deliveryId": "whd_01J9Z…" }Because most providers treat any 2xx as success and retry on 5xx, these
codes line up with how GitHub, Stripe, Svix and similar services already behave.
Real-time delivery vs. offline queueing
Section titled “Real-time delivery vs. offline queueing”When an event is accepted:
- If your agent is online, the event is delivered to it immediately.
- If your agent is offline, the event is stored and delivered when the agent reconnects — so a brief restart or network blip doesn’t lose events. You can review these in the webhook’s delivery history.
Either way, the sending service gets its 200 OK promptly; it doesn’t wait for
your agent to finish processing.
There is one deliberate exception: if an event is authentic but Alfe cannot
store it for a currently-offline agent, it returns 502 instead of a 200.
Returning an error here means the sending service will retry, rather than Alfe
silently accepting an event it couldn’t hold — which would look like success to
the sender while the agent never sees it.
Duplicate deliveries and idempotency
Section titled “Duplicate deliveries and idempotency”Webhook providers deliver at least once, which means the same event can
arrive more than once — a provider retries because it didn’t see your 200 in
time, or you replay a delivery from its dashboard. Alfe deduplicates these when
the provider stamps a stable delivery identifier on the request.
Alfe recognizes the common identifier headers, including:
X-GitHub-Delivery(GitHub)Stripe-Signature(Stripe — its per-event value)Svix-Id(Svix and Svix-based providers)Idempotency-KeyX-Slack-Request-Id(Slack)- Twilio, Amazon SNS, CloudEvents (
ce-id), and other common headers
When a repeat of an already-seen identifier arrives, Alfe short-circuits it and responds with a duplicate acknowledgement instead of delivering the event to your agent a second time:
{ "received": true, "duplicate": true, "externalDeliveryId": "…" }If a provider sends no recognizable delivery identifier, Alfe can’t tell a retry apart from a genuinely new event, so it passes it through. In that case, design your agent’s handling to be idempotent — safe to run twice for the same logical event. A good practice is to key your own processing on a stable field inside the payload (an event id, an object id, a version number).
Building a reliable receiver
Section titled “Building a reliable receiver”Whether your agent handles events directly or you run your own receiver in front of it, a few habits keep delivery robust:
- Respond fast, work later. Acknowledge quickly and do slow work asynchronously. Providers have short timeouts and will retry if you’re slow — which produces duplicates.
- Make handling idempotent. Assume any event can arrive more than once and make repeated processing harmless.
- Verify before you trust. If you run your own receiver, check the signature first — see Verifying signatures.
- Expect retries on errors. If you return a
5xx, expect the provider to send the event again later.
What’s next
Section titled “What’s next”- Overview — what agent webhooks are and how they’re addressed and secured.
- Creating & managing webhooks — create, rotate, and delete from the dashboard or the agent.
- Verifying signatures — the public HMAC verification contract.