If your receiver sits behind an API gateway that checks a key before routing anything through, you can now register that key with the endpoint instead of allow-listing our IP addresses.
POST /v1/webhooks
{
"url": "https://gateway.example.com/biklo/webhooks",
"headers": [
{ "name": "X-Api-Key", "value": "the value your gateway expects" }
]
}
Up to five per endpoint. Values are stored encrypted, never returned and never written
to a delivery record — GET /v1/webhooks shows the name and the first four characters
so you can tell two credentials apart.
Rotating one no longer costs you your signing secret#
PUT /v1/webhooks/{id} is new. It edits an endpoint in place:
PUT /v1/webhooks/42
{ "headers": [ { "name": "X-Api-Key", "value": "the rotated value" } ] }
It also takes events, so narrowing or widening a subscription no longer means
deleting and re-registering. Neither touches the signing secret, which was the real
cost of the old approach: rotating a gateway credential meant a new endpoint, a new
secret, and a deploy of your verification code for a change that had nothing to do
with signing.
headers replaces the whole set rather than merging — we cannot show you what is
stored, so there is nothing sensible to merge into. An empty list clears them.
It is not authentication#
A fixed header value says nothing about the body it arrived with. It gets our request
past your gateway; X-Biklo-Signature is what tells you the payload is ours and
unmodified. Verify it either way.
Also fixed#
The reference for POST /v1/webhooks said an empty events list "subscribes to
nothing, so the endpoint is registered and silent". It has always meant the opposite —
an empty list subscribes to every event, including ones added later, and that is
what the page says now. Nothing about the behaviour changed.
