Webhooks API
10 operations. Authentication, errors and pagination work as described in the REST API overview.
List your webhooks
GET/api/v1/webhooksToken required · scope read
Secrets are never returned after creation; secretHint shows the last four characters.
Responses: 200 OK400, 401, 403, 404, 429
Response fields
| Name | Type | Description |
|---|---|---|
itemsrequired | object[] |
curl 'https://incantory.ai/api/v1/webhooks' \
-H "Authorization: Bearer $INCANTORY_TOKEN"Create a webhook
POST/api/v1/webhooksToken required · scope write
The URL must be https and on the public internet. Returns the signing secret once. At most 20 webhooks per account. Deliveries are POSTs with Incantory-Event, Incantory-Delivery and Incantory-Signature: t=<unix>,v1=<hex HMAC-SHA256(secret, "<t>.<body>")> headers; see /docs/webhooks.
Request body
| Name | Type | Description |
|---|---|---|
urlrequired | string | The https endpoint that receives POSTs |
eventsrequired | ("prompt.version.created" | "prompt.label.moved" | "prompt.published" | "prompt.deleted" | "eval.run.completed" | "eval.run.failed" | "change_request.opened" | "change_request.merged" | "make.linked" | "make.approved" | "comment.created")[] | Events to deliver: prompt.version.created, prompt.label.moved, prompt.published, prompt.deleted, eval.run.completed, eval.run.failed, change_request.opened, change_request.merged, make.linked, make.approved, comment.created |
description | string | A note for yourself |
prompts | string[] | null | Only deliver events about these prompts (owner/slug). Omit or null for every prompt you own or watch. |
active | boolean | Default true |
Responses: 201 OK400, 401, 403, 404, 409, 422, 429
Response fields
| Name | Type | Description |
|---|---|---|
webhookrequired | object | |
secretrequired | string | The signing secret (whsec_…). Shown only in this response. |
curl -X POST 'https://incantory.ai/api/v1/webhooks' \
-H "Authorization: Bearer $INCANTORY_TOKEN" \
-H 'Content-Type: application/json' \
-d '{"url":"https://example.com/hook","events":["prompt.version.created"]}'Get a webhook
GET/api/v1/webhooks/{id}Token required · scope read
| Name | Type | Description |
|---|---|---|
id pathrequired | string | Webhook id |
Responses: 200 OK400, 401, 403, 404, 429
Response fields
| Name | Type | Description |
|---|---|---|
idrequired | string | |
urlrequired | string | |
descriptionrequired | string | |
eventsrequired | string[] | |
promptsrequired | object[] | null | |
activerequired | boolean | |
disabledAtrequired | string | null | Set when Incantory disabled the webhook after repeated failures |
failureCountrequired | integer (-9007199254740991–9007199254740991) | Consecutive failed delivery attempts |
lastDeliveryAtrequired | string | null | |
secretHintrequired | string | whsec_…abcd |
createdAtrequired | string | |
updatedAtrequired | string |
curl 'https://incantory.ai/api/v1/webhooks/{id}' \
-H "Authorization: Bearer $INCANTORY_TOKEN"Update a webhook (owner only)
PATCH/api/v1/webhooks/{id}Token required · scope write
active: true re-enables a webhook Incantory disabled after repeated failures (and resets the failure count). rotateSecret: true returns a new secret once; the old one stops working immediately.
| Name | Type | Description |
|---|---|---|
id pathrequired | string | Webhook id |
Request body
| Name | Type | Description |
|---|---|---|
url | string | |
events | ("prompt.version.created" | "prompt.label.moved" | "prompt.published" | "prompt.deleted" | "eval.run.completed" | "eval.run.failed" | "change_request.opened" | "change_request.merged" | "make.linked" | "make.approved" | "comment.created")[] | Events to deliver: prompt.version.created, prompt.label.moved, prompt.published, prompt.deleted, eval.run.completed, eval.run.failed, change_request.opened, change_request.merged, make.linked, make.approved, comment.created |
description | string | |
prompts | string[] | null | |
active | boolean | true also clears an automatic disable and the failure count |
rotateSecret | true | Generate a new signing secret; the response carries it once |
Responses: 200 OK400, 401, 403, 404, 409, 422, 429
Response fields
| Name | Type | Description |
|---|---|---|
webhookrequired | object | |
secret | string |
curl -X PATCH 'https://incantory.ai/api/v1/webhooks/{id}' \
-H "Authorization: Bearer $INCANTORY_TOKEN" \
-H 'Content-Type: application/json' \
-d '{}'Delete a webhook and its delivery log
DELETE/api/v1/webhooks/{id}Token required · scope write
| Name | Type | Description |
|---|---|---|
id pathrequired | string | Webhook id |
Responses: 204 OK400, 401, 403, 404, 429
curl -X DELETE 'https://incantory.ai/api/v1/webhooks/{id}' \
-H "Authorization: Bearer $INCANTORY_TOKEN"The delivery log (newest first)
GET/api/v1/webhooks/{id}/deliveriesToken required · scope read
Keyset-paginated with cursor; kept for 30 days.
| Name | Type | Description |
|---|---|---|
id pathrequired | string | Webhook id |
cursor query | string | |
limit query | integer (1–100) |
Responses: 200 OK400, 401, 403, 404, 429
Response fields
| Name | Type | Description |
|---|---|---|
itemsrequired | object[] | |
nextCursorrequired | string | null |
curl 'https://incantory.ai/api/v1/webhooks/{id}/deliveries' \
-H "Authorization: Bearer $INCANTORY_TOKEN"One delivery, with its payload
GET/api/v1/webhooks/{id}/deliveries/{deliveryId}Token required · scope read
| Name | Type | Description |
|---|---|---|
id pathrequired | string | Webhook id |
deliveryId pathrequired | string | Delivery id |
Responses: 200 OK400, 401, 403, 404, 429
Response fields
| Name | Type | Description |
|---|---|---|
idrequired | string | |
eventrequired | string | |
eventIdrequired | string | null | |
attemptrequired | integer (-9007199254740991–9007199254740991) | |
statusrequired | "pending" | "succeeded" | "failed" | |
responseCoderequired | integer (-9007199254740991–9007199254740991) | null | |
responseTimeMsrequired | integer (-9007199254740991–9007199254740991) | null | |
responseExcerptrequired | string | null | First 2 KB of the response body |
errorrequired | string | null | |
nextAttemptAtrequired | string | null | |
deliveredAtrequired | string | null | |
createdAtrequired | string | |
payload | any | The envelope that was (or will be) sent; single-delivery reads only |
curl 'https://incantory.ai/api/v1/webhooks/{id}/deliveries/{deliveryId}' \
-H "Authorization: Bearer $INCANTORY_TOKEN"Redeliver an event
POST/api/v1/webhooks/{id}/deliveries/{deliveryId}/redeliverToken required · scope write
Sends the same envelope (same event id) as a new delivery. 409 webhook_disabled while the webhook is disabled.
| Name | Type | Description |
|---|---|---|
id pathrequired | string | Webhook id |
deliveryId pathrequired | string | Delivery id |
Responses: 202 OK400, 401, 403, 404, 409, 429
Response fields
| Name | Type | Description |
|---|---|---|
deliveryIdrequired | string |
curl -X POST 'https://incantory.ai/api/v1/webhooks/{id}/deliveries/{deliveryId}/redeliver' \
-H "Authorization: Bearer $INCANTORY_TOKEN"Send a test (ping) delivery
POST/api/v1/webhooks/{id}/testToken required · scope write
Queued immediately; works on a disabled webhook, is never retried and does not count towards auto-disable. Rate-limited to 30 per hour.
| Name | Type | Description |
|---|---|---|
id pathrequired | string | Webhook id |
Responses: 202 OK400, 401, 403, 404, 429
Response fields
| Name | Type | Description |
|---|---|---|
deliveryIdrequired | string |
curl -X POST 'https://incantory.ai/api/v1/webhooks/{id}/test' \
-H "Authorization: Bearer $INCANTORY_TOKEN"The webhook event catalogue
GET/api/v1/webhooks/eventsPublic
Events: prompt.version.created, prompt.label.moved, prompt.published, prompt.deleted, eval.run.completed, eval.run.failed, change_request.opened, change_request.merged, make.linked, make.approved, comment.created. The test delivery sends ping.
Responses: 200 OK304, 400, 404, 429
Response fields
| Name | Type | Description |
|---|---|---|
itemsrequired | object[] |
curl 'https://incantory.ai/api/v1/webhooks/events'