Webhooks
Endpoints, every delivery attempt, and how to replay one.
The Webhooks view has three tabs: the events your account produced, the deliveries made from them, and the endpoints they were sent to. Events have their own page; this one is about the other two.
Webhook deliveries
| Method | Endpoint | Status | Duration | Attempt |
|---|---|---|---|---|
| POST | /webhooks/wajub | 500 | 10021 ms | 1 |
| POST | /webhooks/wajub | 500 | 240 ms | 2 |
| POST | /webhooks/wajub | 200 | 142 ms | 3 |
Deliveries
One row per attempt, not per event. A delivery retried three times is three rows sharing one delivery id.
| Column | Note |
|---|---|
| Status | success, retrying or failed |
| Response code | What your endpoint answered, empty on a network error |
| Duration | How long your endpoint took. A row at 10,000 ms is a timeout |
| Attempt | 1 for the first try, then one more for each retry and each replay |
| Endpoint | Which URL, when you have several |
Filters: search over the event, status, endpoint, and a date range in whole days. Fifty per page.
The detail panel carries the payload that was sent and the body your endpoint returned, which is
how you find out that your 500 came with a stack trace you can read from here.
Replaying
Two ways, on every plan, with no monthly allowance.
| Action | Scope |
|---|---|
| Resend | One delivery |
| Retry failed deliveries | Up to 100 failed deliveries at once, within a window, optionally for one endpoint |
Retry failed deliveries only picks up deliveries whose status is failed, inside the window you choose, which
defaults to the last 24 hours. Filter the list on failed to see the button: with rows ticked it
retries those, with none it asks for the window.
A delivery whose endpoint has since accepted the event is not sent again: a single resend says so, and a batch skips it. An event that failed several times goes out once.
The same event goes again to the same endpoint at most once every 5 minutes, whether you resend it
from here, from the event page or with POST /events/{id}/resend. Inside that delay, Resend
says how many minutes are left. Retry failed deliveries skips those deliveries and counts them
in its message, or, when every delivery it finds is inside the delay, says when you can retry them.
Fix the endpoint before you replay
A replay repeats the same payload against the same URL. If the handler still throws, you have only reproduced the failure, and that event cannot go to that endpoint again for 5 minutes. Deploy the fix, replay one delivery, check it went green, then bulk replay the rest.
Endpoints
Creating one takes a URL and a list of event types.
| Field | Rule |
|---|---|
| URL | A valid URL, up to 2,048 characters, and not a private or internal address |
| Events | At least one, each from the list Konsole offers |
| Description | Free text, worth using when you have several |
Check event names sent through the API
The picker only offers valid types. With POST /webhooks, check each name against the
event catalogue: a misspelled type never matches.
Private and internal addresses are refused on purpose: an endpoint pointing at localhost or at a
private range would let webhooks reach private networks. For local
development, use wajub listen.
The secret
Each endpoint has its own signing secret, shown once at creation. Afterwards, Reveal shows it again, behind a security verification code, and the action is recorded.
To rotate it, use Rotate next to the secret on the endpoint's page, behind the same security
verification, or POST /webhooks/{id}/rotate-secret from the API. The new secret replaces the old
one at once and is shown once. Every attempt sent from then on is signed with it, retries of
events sent before the rotation included: until your handler knows it, it rejects them. Have the
handler accept both secrets before you rotate, add the new one as soon as it is shown, then drop the
old one. A delivery refused in between is retried, signed with the new secret. The overview's "Signing secret older than 6 months" card counts from the
last rotation.
Moving an endpoint to live
Sandbox and live endpoints are separate. To receive live events, switch the Dashboard to live and create the endpoint again with the same URL and event list. It gets a new secret.
Update your live environment variable
The live endpoint's secret is not the sandbox one. A server still holding the old value will reject every live delivery with a signature error.
The page of a sandbox endpoint carries a Promote to Live button that does this copy in one
action: it creates the live endpoint with the same URL and events, switches the Dashboard to live
and shows the new live secret once. It refuses when a live endpoint already has that URL, or when
the URL is not https://.
Send test sends a real delivery, with test data
Send test posts one delivery to the endpoint, shaped key for key like a real one and signed with
the endpoint's real secret. It proves the URL is reachable, that your signature check passes, and
that your handler accepts the envelope. Only its content is made up: the event is webhook.test
and data is a placeholder, so it does not exercise the code behind a real event type.
It carries the X-Wajub-Delivery-Id header like any delivery, livemode follows the environment the
Dashboard is in, and the attempt is recorded in the endpoint's deliveries as success or failed,
from your answer. It is not retried, and it is not an event: GET /events does not list it.
Answer it with a 2xx
A handler that switches on event should treat an unknown type, webhook.test included, by
answering 200 and doing nothing. To exercise the code behind a real type, use
wajub trigger, which produces real events.