Webhooks
Events that arrive, signed, or tell you loudly that they did not.
Register an HTTPS endpoint, subscribe to the event types you care about, verify the signature on arrival and replay anything your receiver missed.
Subscribe
Create an endpoint with the event types you want. The signing secret is returned once — store it wherever your other secrets live.
curl -X POST https://api.flintwake.com/v2/webhooks/endpoints \
-H "Authorization: Bearer $FLINTWAKE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://hooks.acme.dev/flintwake",
"events": ["wake.error", "slo.burn"]
}'A redirect is indistinguishable from a hijack at delivery time, so we treat one as a failed attempt. Register the final URL.
Event types
wake.error— A captured request returned a 5xx status.wake.slow— A captured request exceeded the endpoint's latency objective.replay.finished— A replay completed. The payload carries the response diff.consumer.quota.warning— A consumer crossed 80% or 95% of its allowance.slo.burn— An availability or latency objective is burning error budget too fast.key.rotated— A key was issued as a replacement for another key.key.revoked— A key was revoked, manually or on schedule.webhook.disabled— An endpoint was disabled after seven days of 410 responses.
Subscribe to ["*"] if you would rather filter on your side. New event types are additive and never sent to an endpoint that did not ask for them.
Verify the signature
Every delivery carries x-flintwake-signature: a timestamp and an HMAC over the raw body. Verify before you parse, and reject anything older than five minutes.
x-flintwake-signature: t=1789012458,v1=4f20a91c7b3e8d2a6c05f1b9e3d7a4c8b2e6f0d9import { verifySignature } from "flintwake/webhooks";
app.post("/flintwake", express.raw({ type: "application/json" }), (req, res) => {
try {
const event = verifySignature({
payload: req.body,
header: req.header("x-flintwake-signature"),
secret: process.env.FLINTWAKE_WEBHOOK_SECRET,
toleranceSeconds: 300,
});
handle(event);
res.status(202).end();
} catch {
res.status(400).end();
}
});Retries and replay
- Any response outside 2xx is a failure, as is a timeout after ten seconds.
- We retry up to eight times with exponential backoff, spread over roughly eighteen hours.
- After the eighth attempt the delivery is dead-lettered and kept for the retention window.
- An endpoint returning 410 for seven consecutive days is disabled, and the account owner is told.
Replay is manual and deliberate. Once your receiver is healthy again, replay the dead-lettered deliveries from the console or the API — replays are marked as such so they are never confused with retries.
curl -X POST https://api.flintwake.com/v2/webhooks/deliveries/dlv_9f41d0/replay \
-H "Authorization: Bearer $FLINTWAKE_API_KEY"The delivery stream
Every attempt, its response code, its duration and its payload. Filter by status and replay anything that failed — this is the same component that ships on the console page.
- Endpoint
- hooks.northbank.dev/flintwake
- Event type
- payment.settled
- Attempt
- 1 of 8
- Response
- 200
- Duration
- 184ms
{
"id": "evt_9f41a2",
"type": "payment.settled",
"created": 1789012458,
"data": { "payment_id": "pi_3QkL2xB", "amount": 24900 }
}Delivered on attempt 1. Signature verified by the receiver against the endpoint secret.