Update a webhook subscription
const url = 'https://api.aerandil.com/v1/webhook-subscriptions/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0';const options = { method: 'PATCH', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"filter":{"object_types":["example"]},"status":"active","url":"https://example.com"}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request PATCH \ --url https://api.aerandil.com/v1/webhook-subscriptions/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0 \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "filter": { "object_types": [ "example" ] }, "status": "active", "url": "https://example.com" }'Patch the receiver url, filter, or status. Omitted fields stay as-is. Setting status to active is the reset path for a subscription that the worker pushed into dead_letter (the customer typically also advances last_delivered_seq out-of-band past the poison batch).
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Path Parameters
Section titled “Path Parameters”Subscription id.
Request Bodyrequired
Section titled “Request Bodyrequired”All fields optional — only the supplied ones change. Setting status to active is the reset path for a dead_letter subscription.
object
Filter narrowing what the worker delivers. Empty / absent means “every event in the tenant”.
object
Narrow to events whose object_type matches one of the listed api_names. For link events, either endpoint type matching counts — a filter of ["hospitality.reservation"] includes reservation_for_guest events.
Lifecycle of a webhook subscription. dead_letter is sticky — the worker stops attempting further deliveries until the customer PATCHes status back to active (and typically advances last_delivered_seq past the poison batch).
Responses
Section titled “Responses”Updated subscription state.
Subscription state without the signing key. The *_key_fingerprint fields are the first 8 hex chars of sha256(key) — enough to confirm a rotation worked without exposing the secret.
object
Resets to 0 on the first 2xx after any failure. Transitioning to dead_letter happens at 12 consecutive failures (~3-day retry window).
Filter narrowing what the worker delivers. Empty / absent means “every event in the tenant”.
object
Narrow to events whose object_type matches one of the listed api_names. For link events, either endpoint type matching counts — a filter of ["hospitality.reservation"] includes reservation_for_guest events.
Cursor into the event log. Advances to the highest seq read on every successful delivery — filtered-out events are still cursored past so the worker stays bounded under a narrow filter.
Earliest moment the worker will retry. Unset when the subscription is caught up; set in the future when an exponential-backoff retry is scheduled.
First 8 hex chars of sha256(primary_signing_key) — 16 chars in total. Exposed instead of the secret on every read.
Present during a key-rotation window. Cleared on promote-key.
Lifecycle of a webhook subscription. dead_letter is sticky — the worker stops attempting further deliveries until the customer PATCHes status back to active (and typically advances last_delivered_seq past the poison batch).
Receiver URL. HTTPS-only (except loopback in dev).
Example
{ "status": "active"}No subscription with that id for this tenant.
Structured error wrapper. Every non-2xx response from any Aerandil endpoint serialises to this shape; the HTTP status carries the failure class (4xx/5xx), the body adds a stable code for programmatic dispatch plus a human-readable message.
object
object
Stable, programmatic error code (e.g. unauthorized, forbidden, not_found, invalid_body, invalid_url, precondition_failed, no_secondary_key). Clients dispatch on code, not on the message (which may be localised or contextualised in future versions).
Request-id correlation handle echoed on the request-id response header — support teams correlate without scraping logs.
Human-readable explanation of the failure.
Per-error structured detail. The shape varies by code (e.g. forbidden_action carries {"action": "..."}; precondition_failed carries {"current_version": N}).
Examplegenerated
{ "error": { "code": "example", "instance_id": "example", "message": "example", "parameters": "example" }}Validation error — invalid_url or unknown fields.
Structured error wrapper. Every non-2xx response from any Aerandil endpoint serialises to this shape; the HTTP status carries the failure class (4xx/5xx), the body adds a stable code for programmatic dispatch plus a human-readable message.
object
object
Stable, programmatic error code (e.g. unauthorized, forbidden, not_found, invalid_body, invalid_url, precondition_failed, no_secondary_key). Clients dispatch on code, not on the message (which may be localised or contextualised in future versions).
Request-id correlation handle echoed on the request-id response header — support teams correlate without scraping logs.
Human-readable explanation of the failure.
Per-error structured detail. The shape varies by code (e.g. forbidden_action carries {"action": "..."}; precondition_failed carries {"current_version": N}).
Examplegenerated
{ "error": { "code": "example", "instance_id": "example", "message": "example", "parameters": "example" }}