.md

Webhooks API

Create webhooks, read their deliveries, and recover what a receiver missed. These endpoints are the /api/webhooks write plane of a self-hosted instance; the guide to receiving and verifying is Webhooks.

List webhooks

GET/api/webhooksSelf-hosted instances
Open .md

Every webhook on this instance, newest first, with status and last delivery times. Paged by offset.

Filters

_offsetinteger#

Rows to skip. Default 0.

Range and paging

_limitinteger#

Page size, 1 to 200. Default 50.

Returns

A cursor envelope. data holds Webhook summary objects.

  • 200One page of webhooks
  • 401This bind requires the instance token, and it was missing or wrong

Create a webhook

POST/api/webhooksSelf-hosted instances
Open .md

Takes triggers and starts at the chain tip, with no backfill. The response carries the signing secret. This is the only time it is returned, so store it now; rotate-secret issues a new one.

Body

namestringrequired#

Unique name on this instance.

urlstringrequired#

Delivery target, http:// or https://. Private addresses are refused at delivery time.

triggersarray of ChainTriggerrequired#

1 to 50 triggers. An event matching any of them is delivered.

formatenum#

Payload and signing format. standard-webhooks signs with the webhook's secret; the others shape the body for that receiver.

6 possible values
standard-webhooksinngesttriggercloudflarecloudeventsraw
authConfigobject#

Per-format receiver credentials: token / tokenEnc for trigger and cloudflare, headers or basicAuth for raw. Write-only — never returned; a read gets auth instead.

maxRetriesinteger · 0 to 100#

Attempts before an event moves to the dead-letter queue. Default 7.

timeoutMsinteger · 100 to 300000#

Per-attempt HTTP timeout in milliseconds. Default 10000.

concurrencyinteger · 1 to 100#

Deliveries in flight at once for this webhook. Default 4.

Returns

The Webhook with its signing secret object.

  • 201Created. The body carries the signing secret, once
  • 400A parameter, filter, cursor or body field was refused; code says which. A body carrying subgraphName, tableName or filter is answered with SUBGRAPH_WEBHOOKS_REMOVED: subgraph webhooks were removed
  • 401This bind requires the instance token, and it was missing or wrong
  • 409A webhook with that name already exists
  • 415Missing or non-JSON Content-Type (UNSUPPORTED_MEDIA_TYPE) — writes must send Content-Type: application/json
  • 500The webhook could not be stored (INTERNAL_ERROR)

Get a webhook

GET/api/webhooks/{id}Self-hosted instances
Open .md

Full config and delivery health for one webhook. Never includes the signing secret.

Path parameters

idstringrequired#

Webhook id (UUID), as returned by create or list.

Returns

The Webhook object.

  • 200The webhook
  • 401This bind requires the instance token, and it was missing or wrong
  • 404No webhook with this id

Update a webhook

PATCH/api/webhooks/{id}Self-hosted instances
Open .md

Change any subset of fields; at least one is required. triggers are fixed at create: to change them, create a new webhook.

Path parameters

idstringrequired#

Webhook id (UUID), as returned by create or list.

Body

namestring#

New unique name.

urlstring#

New delivery target, http:// or https://.

formatenum#

Payload and signing format. standard-webhooks signs with the webhook's secret; the others shape the body for that receiver.

6 possible values
standard-webhooksinngesttriggercloudflarecloudeventsraw
authConfigobject#

Per-format receiver credentials: token / tokenEnc for trigger and cloudflare, headers or basicAuth for raw. Write-only — never returned; a read gets auth instead.

maxRetriesinteger · 0 to 100#

Attempts before an event moves to the dead-letter queue. Default 7.

timeoutMsinteger · 100 to 300000#

Per-attempt HTTP timeout in milliseconds. Default 10000.

concurrencyinteger · 1 to 100#

Deliveries in flight at once for this webhook. Default 4.

Returns

The Webhook object.

  • 200The updated webhook
  • 400A parameter, filter, cursor or body field was refused; code says which. A body carrying subgraphName, tableName or filter is answered with SUBGRAPH_WEBHOOKS_REMOVED: subgraph webhooks were removed
  • 401This bind requires the instance token, and it was missing or wrong
  • 404No webhook with this id
  • 415Missing or non-JSON Content-Type (UNSUPPORTED_MEDIA_TYPE) — writes must send Content-Type: application/json

Delete a webhook

DELETE/api/webhooks/{id}Self-hosted instances
Open .md

Removes the webhook. Nothing more is delivered to its URL. Cannot be undone.

Path parameters

idstringrequired#

Webhook id (UUID), as returned by create or list.

Returns

  • 200Deleted
  • 400A parameter, filter, cursor or body field was refused; code says which
  • 401This bind requires the instance token, and it was missing or wrong
  • 404No webhook with this id
  • 415Missing or non-JSON Content-Type (UNSUPPORTED_MEDIA_TYPE) — writes must send Content-Type: application/json

Pause a webhook

POST/api/webhooks/{id}/pauseSelf-hosted instances
Open .md

Sets status to paused. Matched events keep queueing and deliver on resume. Takes no body.

Path parameters

idstringrequired#

Webhook id (UUID), as returned by create or list.

Returns

The Webhook object.

  • 200The paused webhook
  • 400A parameter, filter, cursor or body field was refused; code says which
  • 401This bind requires the instance token, and it was missing or wrong
  • 404No webhook with this id
  • 415Missing or non-JSON Content-Type (UNSUPPORTED_MEDIA_TYPE) — writes must send Content-Type: application/json

Resume a webhook

POST/api/webhooks/{id}/resumeSelf-hosted instances
Open .md

Sets status to active and resets the circuit breaker (circuitFailures, circuitOpenedAt). Queued events start delivering. Takes no body.

Path parameters

idstringrequired#

Webhook id (UUID), as returned by create or list.

Returns

The Webhook object.

  • 200The resumed webhook
  • 400A parameter, filter, cursor or body field was refused; code says which
  • 401This bind requires the instance token, and it was missing or wrong
  • 404No webhook with this id
  • 415Missing or non-JSON Content-Type (UNSUPPORTED_MEDIA_TYPE) — writes must send Content-Type: application/json

Rotate the signing secret

POST/api/webhooks/{id}/rotate-secretSelf-hosted instances
Open .md

Issues a new signing secret and returns it, once. Deliveries signed with the old secret stop verifying immediately, so update your receiver right away. Takes no body.

Path parameters

idstringrequired#

Webhook id (UUID), as returned by create or list.

Returns

The Webhook with its signing secret object.

  • 200The webhook and its new signing secret
  • 400A parameter, filter, cursor or body field was refused; code says which
  • 401This bind requires the instance token, and it was missing or wrong
  • 404No webhook with this id
  • 415Missing or non-JSON Content-Type (UNSUPPORTED_MEDIA_TYPE) — writes must send Content-Type: application/json

Send a test delivery

POST/api/webhooks/{id}/testSelf-hosted instances
Open .md

Posts one sample event, built and signed in the webhook's format, to its URL through the SSRF guard, and logs it under deliveries. The body has data.test: true, so receivers can tell it from a live event. Works while paused. Takes no body.

Path parameters

idstringrequired#

Webhook id (UUID), as returned by create or list.

Returns

The Webhook test result object.

  • 200What the target answered. A failed delivery still returns 200; check ok
  • 400A parameter, filter, cursor or body field was refused; code says which
  • 401This bind requires the instance token, and it was missing or wrong
  • 404No webhook with this id
  • 415Missing or non-JSON Content-Type (UNSUPPORTED_MEDIA_TYPE) — writes must send Content-Type: application/json

List delivery attempts

GET/api/webhooks/{id}/deliveriesSelf-hosted instances
Open .md

The last 100 delivery attempts, newest first, including test deliveries. total counts every attempt ever logged for the webhook. With from and to, only attempts dispatched in that window; total counts the window.

Path parameters

idstringrequired#

Webhook id (UUID), as returned by create or list.

Query parameters

fromstring#

Window start, inclusive, ISO 8601. Needs to; at most 31 days before it.

tostring#

Window end, exclusive, ISO 8601. Needs from.

Returns

A cursor envelope. data holds Webhook delivery objects.

  • 200Recent delivery attempts
  • 401This bind requires the instance token, and it was missing or wrong
  • 404No webhook with this id

List dead-lettered events

GET/api/webhooks/{id}/deadSelf-hosted instances
Open .md

Events that used up maxRetries without a 2xx, newest failure first, up to 100. Requeue one to try it again.

Path parameters

idstringrequired#

Webhook id (UUID), as returned by create or list.

Returns

A cursor envelope. data holds Dead-lettered webhook event objects.

  • 200Dead-lettered events
  • 401This bind requires the instance token, and it was missing or wrong
  • 404No webhook with this id

Requeue a dead event

POST/api/webhooks/{id}/dead/{outbox_id}/requeueSelf-hosted instances
Open .md

Moves one dead event back to pending with its attempt count reset. It delivers at live priority, even if it came from a replay. Takes no body.

Path parameters

idstringrequired#

Webhook id (UUID), as returned by create or list.

outbox_idstringrequired#

Dead event id (UUID), the id from the dead-letter list.

Returns

  • 200Requeued
  • 400A parameter, filter, cursor or body field was refused; code says which
  • 401This bind requires the instance token, and it was missing or wrong
  • 404No webhook with this id, or no dead event with this id on it
  • 415Missing or non-JSON Content-Type (UNSUPPORTED_MEDIA_TYPE) — writes must send Content-Type: application/json

Replay a block range

POST/api/webhooks/{id}/replaySelf-hosted instances
Open .md

Queues historical events in a block range for redelivery, capped at 100,000 blocks. Replays are idempotent: the same range yields the same replayId and delivers nothing twice unless force is set. They drain through a 10% share of the outbox so live traffic keeps priority, and never move the live cursor. Replays deliver the normal chain.<type>.apply envelope. Watch one with GET /api/webhooks/{id}/replays/{replay_id}.

Path parameters

idstringrequired#

Webhook id (UUID), as returned by create or list.

Body

fromBlockintegerrequired#

First block, inclusive.

toBlockintegerrequired#

Last block, inclusive. At most 100,000 blocks after fromBlock.

forcestring#

Any string, up to 64 characters. Makes a new replayId, so an already-replayed range delivers again.

Returns

The Webhook replay object.

  • 202Replay queued
  • 400A parameter, filter, cursor or body field was refused; code says which. Also: fromBlock after toBlock, or a range over 100,000 blocks
  • 401This bind requires the instance token, and it was missing or wrong
  • 404No webhook with this id
  • 409A replay of this webhook is still scanning its range
  • 415Missing or non-JSON Content-Type (UNSUPPORTED_MEDIA_TYPE) — writes must send Content-Type: application/json
  • 500The replay could not be queued (INTERNAL_ERROR)

List recent replays across webhooks

GET/api/webhooks/replaysSelf-hosted instances
Open .md

Replays still scanning or delivering, plus any started in the last 24 hours, across every webhook on this instance. Newest first.

Range and paging

_limitinteger#

Page size, 1 to 50. Default 20.

Returns

A cursor envelope. data holds Webhook replay progress objects.

  • 200Recent replays with live progress
  • 401This bind requires the instance token, and it was missing or wrong

List a webhook's replays and replay ranges

GET/api/webhooks/{id}/replaysSelf-hosted instances
Open .md

The webhook's last 10 replays with live progress, newest first, and the block ranges a new replay can start from. Ranges count back from the last block the evaluator processed.

Path parameters

idstringrequired#

Webhook id (UUID), as returned by create or list.

Returns

A cursor envelope. data holds Webhook replay progress objects.

  • 200Replays and ranges for this webhook
  • 401This bind requires the instance token, and it was missing or wrong
  • 404No webhook with this id

Get a replay's progress

GET/api/webhooks/{id}/replays/{replay_id}Self-hosted instances
Open .md

Where one replay stands: how many events it queued, how many are done, and once nothing is left pending, how many delivered and how many gave up. Poll it while the replay drains.

Path parameters

idstringrequired#

Webhook id (UUID), as returned by create or list.

replay_idstringrequired#

Replay id, the replayId from the replay response (16 hex characters).

Returns

The Webhook replay progress object.

  • 200The replay's progress
  • 401This bind requires the instance token, and it was missing or wrong
  • 404No webhook with this id, or no replay with this id on it

Requeue dead events in bulk

POST/api/webhooks/{id}/dead/requeueSelf-hosted instances
Open .md

Moves dead events back to pending with their attempt counts reset, at live priority. With no body it requeues every dead event of the webhook; replayId narrows it to one replay and since to events that failed at or after that time. A replay that gets events back returns to running, so its progress tracks the retry.

Path parameters

idstringrequired#

Webhook id (UUID), as returned by create or list.

Body

replayIdstring#

Only dead events created by this replay.

sincestring · date-time#

Only dead events that failed at or after this time.

Returns

  • 200Events requeued
  • 400A parameter, filter, cursor or body field was refused; code says which
  • 401This bind requires the instance token, and it was missing or wrong
  • 404No webhook with this id
  • 415Missing or non-JSON Content-Type (UNSUPPORTED_MEDIA_TYPE) — writes must send Content-Type: application/json

List insights

GET/api/insightsSelf-hosted instances
Open .md

Ranked findings about this instance's webhooks and subgraphs: losing events first, then about to fail, then costing money, then recently recovered. Dismissed and expected insights are left out.

Query parameters

resourcestring#

Only one resource, as <kind>:<id>, such as webhook:<id> or subgraph:<name>.

Returns

  • 200Insights in rank order
  • 400resource is not <kind>:<id> (VALIDATION_ERROR)
  • 401This bind requires the instance token, and it was missing or wrong

Dismiss an insight

POST/api/insights/{id}/dismissSelf-hosted instances
Open .md

Hides this incident. If the same rule fires again after it clears, the new incident shows. Takes no body.

Path parameters

idstringrequired#

Insight id (UUID), as returned by the insights list.

Returns

  • 200Dismissed
  • 400A parameter, filter, cursor or body field was refused; code says which
  • 401This bind requires the instance token, and it was missing or wrong
  • 404No insight with this id
  • 415Missing or non-JSON Content-Type (UNSUPPORTED_MEDIA_TYPE) — writes must send Content-Type: application/json

Undo dismissing an insight

DELETE/api/insights/{id}/dismissSelf-hosted instances
Open .md

Shows a dismissed insight again.

Path parameters

idstringrequired#

Insight id (UUID), as returned by the insights list.

Returns

  • 200Shown again
  • 400A parameter, filter, cursor or body field was refused; code says which
  • 401This bind requires the instance token, and it was missing or wrong
  • 404No insight with this id
  • 415Missing or non-JSON Content-Type (UNSUPPORTED_MEDIA_TYPE) — writes must send Content-Type: application/json

Snooze an insight until a time

POST/api/insights/{id}/snoozeSelf-hosted instances
Open .md

Hides this insight until the time you give, at most 7 days ahead. It shows again then, or earlier if you remove the snooze.

Path parameters

idstringrequired#

Insight id (UUID), as returned by the insights list.

Body

untilstring · date-timerequired#

When it shows again. Must be in the next 7 days.

Returns

  • 200Snoozed
  • 400until is not a time in the next 7 days (VALIDATION_ERROR)
  • 401This bind requires the instance token, and it was missing or wrong
  • 404No insight with this id
  • 415Missing or non-JSON Content-Type (UNSUPPORTED_MEDIA_TYPE) — writes must send Content-Type: application/json

Remove an insight's snooze

DELETE/api/insights/{id}/snoozeSelf-hosted instances
Open .md

Shows a snoozed insight again now.

Path parameters

idstringrequired#

Insight id (UUID), as returned by the insights list.

Returns

  • 200Shown again
  • 400A parameter, filter, cursor or body field was refused; code says which
  • 401This bind requires the instance token, and it was missing or wrong
  • 404No insight with this id
  • 415Missing or non-JSON Content-Type (UNSUPPORTED_MEDIA_TYPE) — writes must send Content-Type: application/json

Mark an insight expected

POST/api/insights/{id}/expectedSelf-hosted instances
Open .md

Mutes this rule for this resource, including future incidents, until you remove the mute. Takes no body.

Path parameters

idstringrequired#

Insight id (UUID), as returned by the insights list.

Returns

  • 200Muted
  • 400A parameter, filter, cursor or body field was refused; code says which
  • 401This bind requires the instance token, and it was missing or wrong
  • 404No insight with this id
  • 415Missing or non-JSON Content-Type (UNSUPPORTED_MEDIA_TYPE) — writes must send Content-Type: application/json

Unmark an insight as expected

DELETE/api/insights/{id}/expectedSelf-hosted instances
Open .md

Removes the mute for this rule and resource, so it shows again whenever it fires.

Path parameters

idstringrequired#

Insight id (UUID), as returned by the insights list.

Returns

  • 200Unmuted
  • 400A parameter, filter, cursor or body field was refused; code says which
  • 401This bind requires the instance token, and it was missing or wrong
  • 404No insight with this id
  • 415Missing or non-JSON Content-Type (UNSUPPORTED_MEDIA_TYPE) — writes must send Content-Type: application/json
Open .md

A webhook as it appears in the list.

Returned by List webhooks

Attributes

idstring · uuidrequired#

Webhook id.

namestringrequired#

Unique name on this instance.

statusenumrequired#

active delivers. paused holds new events in the outbox until resumed; the circuit breaker also pauses a webhook after 20 straight failures. error is reserved; nothing sets it today.

3 possible values
activepausederror
kindenumrequired#

Always chain: webhooks fire on raw chain events matched by triggers.

1 possible values
chain
formatenumrequired#

Payload and signing format. standard-webhooks signs with the webhook's secret; the others shape the body for that receiver.

6 possible values
standard-webhooksinngesttriggercloudflarecloudeventsraw
urlstringrequired#

Delivery target.

lastDeliveryAtstring · date-time · nullablerequired#

Last delivery attempt, successful or not.

lastSuccessAtstring · date-time · nullablerequired#

Last delivery the target answered with a 2xx.

circuitOpenedAtstring · date-time · nullablerequired#

When the circuit breaker paused this webhook. Cleared on resume.

circuitFailuresintegerrequired#

Consecutive failed deliveries; a success resets it. The circuit opens at 20; resume resets it.

managedBystring · nullablerequired#

Product that owns this webhook's name, derived from a reserved name prefix (for example sentinel: is Sentinel). When set, renaming returns 409 WEBHOOK_NAME_MANAGED. null for ordinary webhooks.

createdAtstring · date-timerequired#

When the webhook was created.

updatedAtstring · date-timerequired#

Last config or status change.

Returned by create and rotate-secret only. The one place the signing secret appears.

Returned by Create a webhook, Rotate the signing secret

Attributes

webhookWebhookrequired#
signingSecretstringrequired#

Plaintext signing secret, 64 hex characters. Shown once; store it server-side to verify deliveries.

Open .md

A webhook's full config and delivery health. Never includes the signing secret.

Returned by Get a webhook, Update a webhook, Pause a webhook, Resume a webhook

Attributes

idstring · uuidrequired#

Webhook id.

namestringrequired#

Unique name on this instance.

statusenumrequired#

active delivers. paused holds new events in the outbox until resumed; the circuit breaker also pauses a webhook after 20 straight failures. error is reserved; nothing sets it today.

3 possible values
activepausederror
kindenumrequired#

Always chain: webhooks fire on raw chain events matched by triggers.

1 possible values
chain
formatenumrequired#

Payload and signing format. standard-webhooks signs with the webhook's secret; the others shape the body for that receiver.

6 possible values
standard-webhooksinngesttriggercloudflarecloudeventsraw
urlstringrequired#

Delivery target.

lastDeliveryAtstring · date-time · nullablerequired#

Last delivery attempt, successful or not.

lastSuccessAtstring · date-time · nullablerequired#

Last delivery the target answered with a 2xx.

circuitOpenedAtstring · date-time · nullablerequired#

When the circuit breaker paused this webhook. Cleared on resume.

circuitFailuresintegerrequired#

Consecutive failed deliveries; a success resets it. The circuit opens at 20; resume resets it.

managedBystring · nullablerequired#

Product that owns this webhook's name, derived from a reserved name prefix (for example sentinel: is Sentinel). When set, renaming returns 409 WEBHOOK_NAME_MANAGED. null for ordinary webhooks.

createdAtstring · date-timerequired#

When the webhook was created.

updatedAtstring · date-timerequired#

Last config or status change.

triggersarray of ChainTriggerrequired#

Chain triggers.

authobjectrequired#

Receiver credentials, redacted — set with authConfig on create or update, but never returned. authConfig is write-only.

maxRetriesinteger · 0 to 100required#

Attempts before an event moves to the dead-letter queue. Default 7.

timeoutMsinteger · 100 to 300000required#

Per-attempt HTTP timeout in milliseconds. Default 10000.

concurrencyinteger · 1 to 100required#

Deliveries in flight at once for this webhook. Default 4.

lastErrorstring · nullablerequired#

Error from the last failed delivery.

receiverCertExpiresAtstring · date-time · nullablerequired#

When the receiver's TLS certificate expires, from a periodic probe. null for http receivers, unreachable hosts, and webhooks not probed yet.

warningstring · nullablerequired#

Set when this instance's chain-trigger evaluator isn't running (SUBGRAPH_SOURCE != streams-index) — the webhook will never fire until that's fixed. null otherwise.

Open .md

Outcome of one test delivery.

Returned by Send a test delivery

Attributes

okbooleanrequired#

true when the target answered 2xx.

statusCodeinteger · nullablerequired#

HTTP status. null when no response came back.

errorstring · nullablerequired#

Why the delivery failed. null on success.

durationMsintegerrequired#

Round trip in milliseconds.

deliveryIdstring · uuidrequired#

The logged attempt, as it appears under deliveries.

Open .md

One HTTP attempt to deliver an event.

Returned by List delivery attempts

Attributes

idstring · uuidrequired#

Attempt id.

seqintegerrequired#

Position in the webhook's lifetime log. The newest attempt equals total.

attemptintegerrequired#

Which try this was for its event, from 1.

statusCodeinteger · nullablerequired#

HTTP status. null when no response came back.

blockHeightinteger · nullablerequired#

Block of the delivered event. null for test deliveries and for events already compacted out of the outbox.

blockTimestring · date-time · nullablerequired#

When the delivered event's block was produced. null for test deliveries, events already compacted out of the outbox, and rows written before this column existed.

errorMessagestring · nullablerequired#

Why the attempt failed. null on success.

durationMsinteger · nullablerequired#

Round trip in milliseconds.

responseBodystring · nullablerequired#

Start of the target's response body.

dispatchedAtstring · date-timerequired#

When the attempt was sent.

Open .md

An event that used up its retries without a 2xx.

Returned by List dead-lettered events

Attributes

idstring · uuidrequired#

Outbox id. Pass it as outbox_id to requeue.

eventTypestringrequired#

Delivered type, e.g. chain.ft_transfer.apply.

attemptintegerrequired#

Attempts made before it was dead-lettered.

blockHeightintegerrequired#

Block the event came from.

txIdstring · nullablerequired#

Transaction behind the event, when there is one.

payloadobjectrequired#

The event body that failed to deliver.

failedAtstring · date-time · nullablerequired#

When the last attempt failed.

createdAtstring · date-timerequired#

When the event was queued.

Open .md

What a replay queued.

Returned by Replay a block range

Attributes

replayIdstringrequired#

16 hex characters, derived from webhook, range and force. The same inputs give the same id.

enqueuedCountintegerrequired#

Events queued. Lower than matches when part of the range was replayed before.

scannedCountintegerrequired#

Rows or events examined in the range.

Open .md

Live state of one replay. While it runs, delivered and gaveUp are null; they are set once no event is left pending.

Returned by List recent replays across webhooks, List a webhook's replays and replay ranges, Get a replay's progress

Attributes

replayIdstringrequired#

16 hex characters.

webhookIdstringrequired#

Webhook id (UUID).

statusenumrequired#

scanning while the range is read, running while events deliver, done when none are pending, failed if the scan broke.

4 possible values
scanningrunningdonefailed
fromBlockintegerrequired#

First block, inclusive.

toBlockintegerrequired#

Last block, inclusive.

totalintegerrequired#

Events the replay queued.

processedintegerrequired#

Events delivered or given up on: total minus pending.

pendingintegerrequired#

Events still waiting to be delivered or retried.

deliveredinteger · nullablerequired#

Events delivered. null until the replay is done.

gaveUpinteger · nullablerequired#

Events that used up their retries. null until the replay is done.

startedAtstringrequired#

ISO 8601 time it started.

finishedAtstring · nullablerequired#

ISO 8601 time it finished. null while it runs.

errorstring · nullablerequired#

Why the scan failed. null otherwise.

Edit on GitHub