Skip to content
Linq Copy agent prompt

Webhook Endpoints

Register where events are delivered, roll the signing secret without dropping a delivery, and see how the destination is behaving.

Register a webhook endpoint
POST/v1/webhook_endpoints
Delete a webhook endpoint
DELETE/v1/webhook_endpoints/{endpoint}
List webhook endpoints
GET/v1/webhook_endpoints
Get a webhook endpoint
GET/v1/webhook_endpoints/{endpoint}
Update a webhook endpoint
PATCH/v1/webhook_endpoints/{endpoint}
ModelsExpand Collapse
Endpoint object { id, created_at, disabled_at, 8 more }

A destination this brand’s events are delivered to.

id: string

The endpoint’s id.

created_at: string
formatdate-time
disabled_at: string

When this endpoint was last disabled. null while it is enabled.

formatdate-time
event_kinds: array of string

The event kinds delivered here, or null for every kind (including kinds added later).

health: EndpointHealth { consecutive_failures, last_failure_at, last_failure_reason, 2 more }

How a destination has been behaving, taken from the deliveries actually attempted against it. Worth reading before assuming an integration is healthy: a destination that has been refusing events shows up here well before anyone notices they are missing.

consecutive_failures: number

Failed attempts since the last success. Reset to 0 by any success.

formatint32
last_failure_at: string

When a delivery to this endpoint last failed. null if none ever has.

formatdate-time
last_failure_reason: string

A short reason for the last failure, written for a human reading it. The wording is not stable; do not branch on it.

last_failure_status: number

The HTTP status of that last failure. null when the attempt never reached a response at all — a name that did not resolve, a refused connection, a timeout, or an address we will not dial.

formatint32
last_success_at: string

When a delivery to this endpoint last succeeded. null if none ever has.

formatdate-time
status: string

enabled or disabled. A disabled endpoint receives nothing, and events are not queued for it — see the update operation. Values grow additively.

updated_at: string
formatdate-time
url: string

Where events are POSTed. https only.

maxLength2000
backlog_dropped: optional number

How many undelivered events were dropped by THIS request, present only on the response to a request that disabled or deleted the endpoint. Disabling is a cutoff: everything still queued for this endpoint is dropped then and there rather than waiting to be replayed later.

formatint32
backlog_resume_cursor: optional string

Where to pick the dropped events back up: pass it as the cursor query parameter to GET /v1/streams/events and the first event you receive is the first one dropped. Present alongside backlog_dropped and only then.

Keep it if you rely on webhooks alone. A webhook carries the event’s identity but not its position in the stream, so this response is the only place a push-only integration is handed the position of the gap it just created. Reconnecting without a cursor starts at the present moment and skips the gap entirely.

It stays valid while the events behind it are retained; past that the stream answers 410 cursor_expired rather than pretending.

description: optional string

Your own label for this endpoint.

maxLength200
EndpointCreated object { id, created_at, disabled_at, 10 more }

A newly registered endpoint, together with its signing secret. The secret appears in this response and never again.

id: string

The endpoint’s id.

created_at: string
formatdate-time
disabled_at: string

When this endpoint was last disabled. null while it is enabled.

formatdate-time
event_kinds: array of string

The event kinds delivered here, or null for every kind (including kinds added later).

health: EndpointHealth { consecutive_failures, last_failure_at, last_failure_reason, 2 more }

How a destination has been behaving, taken from the deliveries actually attempted against it. Worth reading before assuming an integration is healthy: a destination that has been refusing events shows up here well before anyone notices they are missing.

consecutive_failures: number

Failed attempts since the last success. Reset to 0 by any success.

formatint32
last_failure_at: string

When a delivery to this endpoint last failed. null if none ever has.

formatdate-time
last_failure_reason: string

A short reason for the last failure, written for a human reading it. The wording is not stable; do not branch on it.

last_failure_status: number

The HTTP status of that last failure. null when the attempt never reached a response at all — a name that did not resolve, a refused connection, a timeout, or an address we will not dial.

formatint32
last_success_at: string

When a delivery to this endpoint last succeeded. null if none ever has.

formatdate-time
secret: string

The signing secret, in the Standard Webhooks presentation form (whsec_ followed by base64). Shown exactly once, here. It is not recoverable from any later read — if you lose it, add a second secret and retire this one.

secret_id: string

The id of the secret above — the handle you retire it by.

status: string

enabled or disabled. A disabled endpoint receives nothing, and events are not queued for it — see the update operation. Values grow additively.

updated_at: string
formatdate-time
url: string

Where events are POSTed. https only.

maxLength2000
backlog_dropped: optional number

How many undelivered events were dropped by THIS request, present only on the response to a request that disabled or deleted the endpoint. Disabling is a cutoff: everything still queued for this endpoint is dropped then and there rather than waiting to be replayed later.

formatint32
backlog_resume_cursor: optional string

Where to pick the dropped events back up: pass it as the cursor query parameter to GET /v1/streams/events and the first event you receive is the first one dropped. Present alongside backlog_dropped and only then.

Keep it if you rely on webhooks alone. A webhook carries the event’s identity but not its position in the stream, so this response is the only place a push-only integration is handed the position of the gap it just created. Reconnecting without a cursor starts at the present moment and skips the gap entirely.

It stays valid while the events behind it are retained; past that the stream answers 410 cursor_expired rather than pretending.

description: optional string

Your own label for this endpoint.

maxLength200
EndpointHealth object { consecutive_failures, last_failure_at, last_failure_reason, 2 more }

How a destination has been behaving, taken from the deliveries actually attempted against it. Worth reading before assuming an integration is healthy: a destination that has been refusing events shows up here well before anyone notices they are missing.

consecutive_failures: number

Failed attempts since the last success. Reset to 0 by any success.

formatint32
last_failure_at: string

When a delivery to this endpoint last failed. null if none ever has.

formatdate-time
last_failure_reason: string

A short reason for the last failure, written for a human reading it. The wording is not stable; do not branch on it.

last_failure_status: number

The HTTP status of that last failure. null when the attempt never reached a response at all — a name that did not resolve, a refused connection, a timeout, or an address we will not dial.

formatint32
last_success_at: string

When a delivery to this endpoint last succeeded. null if none ever has.

formatdate-time
EndpointList object { data }

The endpoints registered for this key’s brand.

data: array of Endpoint { id, created_at, disabled_at, 8 more }
id: string

The endpoint’s id.

created_at: string
formatdate-time
disabled_at: string

When this endpoint was last disabled. null while it is enabled.

formatdate-time
event_kinds: array of string

The event kinds delivered here, or null for every kind (including kinds added later).

health: EndpointHealth { consecutive_failures, last_failure_at, last_failure_reason, 2 more }

How a destination has been behaving, taken from the deliveries actually attempted against it. Worth reading before assuming an integration is healthy: a destination that has been refusing events shows up here well before anyone notices they are missing.

consecutive_failures: number

Failed attempts since the last success. Reset to 0 by any success.

formatint32
last_failure_at: string

When a delivery to this endpoint last failed. null if none ever has.

formatdate-time
last_failure_reason: string

A short reason for the last failure, written for a human reading it. The wording is not stable; do not branch on it.

last_failure_status: number

The HTTP status of that last failure. null when the attempt never reached a response at all — a name that did not resolve, a refused connection, a timeout, or an address we will not dial.

formatint32
last_success_at: string

When a delivery to this endpoint last succeeded. null if none ever has.

formatdate-time
status: string

enabled or disabled. A disabled endpoint receives nothing, and events are not queued for it — see the update operation. Values grow additively.

updated_at: string
formatdate-time
url: string

Where events are POSTed. https only.

maxLength2000
backlog_dropped: optional number

How many undelivered events were dropped by THIS request, present only on the response to a request that disabled or deleted the endpoint. Disabling is a cutoff: everything still queued for this endpoint is dropped then and there rather than waiting to be replayed later.

formatint32
backlog_resume_cursor: optional string

Where to pick the dropped events back up: pass it as the cursor query parameter to GET /v1/streams/events and the first event you receive is the first one dropped. Present alongside backlog_dropped and only then.

Keep it if you rely on webhooks alone. A webhook carries the event’s identity but not its position in the stream, so this response is the only place a push-only integration is handed the position of the gap it just created. Reconnecting without a cursor starts at the present moment and skips the gap entirely.

It stays valid while the events behind it are retained; past that the stream answers 410 cursor_expired rather than pretending.

description: optional string

Your own label for this endpoint.

maxLength200

Webhook EndpointsReplays

Register where events are delivered, roll the signing secret without dropping a delivery, and see how the destination is behaving.

Replay retained webhook events
POST/v1/webhook_endpoints/{endpoint}/replays
Get webhook replay status
GET/v1/webhook_endpoints/{endpoint}/replays/{replay}
ModelsExpand Collapse
Replay object { id, after_cursor, created_at, 12 more }
id: string
after_cursor: string
created_at: string
formatdate-time
delivered: number
formatint32
delivering: number
formatint32
exhausted: number
formatint32
failure_reason: string
materialized: number
formatint32
pending: number
formatint32
selected: number
formatint32
started_at: string
formatdate-time
state: "pending" or "running" or "completed" or "failed"
One of the following:
"pending"
"running"
"completed"
"failed"
terminal_at: string
formatdate-time
through_cursor: string
unmaterialized: number
formatint32
ReplayAcceptance object { id, after_cursor, created_at, 3 more }
id: string
after_cursor: string
created_at: string
formatdate-time
selected: number
formatint32
state: "pending"
through_cursor: string

Webhook EndpointsSecrets

Register where events are delivered, roll the signing secret without dropping a delivery, and see how the destination is behaving.

Add a signing secret
POST/v1/webhook_endpoints/{endpoint}/secrets
Retire a signing secret
DELETE/v1/webhook_endpoints/{endpoint}/secrets/{secret}
List signing secrets
GET/v1/webhook_endpoints/{endpoint}/secrets
ModelsExpand Collapse
SigningSecret object { id, created_at, retired_at, status }

One signing secret. Every ACTIVE secret signs every event, and all of the signatures ride the one webhook-signature header — which is what makes a rotation lossless.

id: string

The secret’s id. Safe to log: it is a handle, not key material.

created_at: string
formatdate-time
retired_at: string

When this secret stopped signing. null while it is active.

formatdate-time
status: string

active or retired. Values grow additively.

SigningSecretCreated object { id, created_at, retired_at, 2 more }

A newly added signing secret, with its value — shown exactly once.

id: string

The secret’s id. Safe to log: it is a handle, not key material.

created_at: string
formatdate-time
retired_at: string

When this secret stopped signing. null while it is active.

formatdate-time
secret: string

The signing secret in presentation form (whsec_ + base64). Shown exactly once, here.

status: string

active or retired. Values grow additively.

SigningSecretList object { data }

An endpoint’s signing secrets, oldest first — the order they sign in.

data: array of SigningSecret { id, created_at, retired_at, status }
id: string

The secret’s id. Safe to log: it is a handle, not key material.

created_at: string
formatdate-time
retired_at: string

When this secret stopped signing. null while it is active.

formatdate-time
status: string

active or retired. Values grow additively.