Skip to content
FolioSign inStart your trial

API reference

Webhook endpoints

Register https endpoints, rotate their signing secret, send a test event and read deliveries.

GET/v1/webhook-endpoints

List webhook endpoints#

Lists the church's webhook endpoints with their health: status, consecutive failures and delivery counts over the last 30 days. An endpoint disabled after 20 failures in a row shows status disabled and a disabled_reason.

Auth. A church API key. Needs the webhooks:read scope, or a wildcard that includes it (machine:read, machine:*, * on a partner key). A partner key can call it for a customer church by sending X-Folio-Church.

Limits. Responses carry RateLimit-Limit and RateLimit-Remaining; a 429 carries Retry-After.

Auth
Church API key
Scope
webhooks:read
Operation id
machineListWebhookEndpoints

Parameters

Parameters
NameInDescription
limitqueryItems per page. (integer)
cursorqueryOpaque cursor from meta.next_cursor of the previous page. (string)
X-Folio-ChurchheaderPartner keys only: run this call as one of your customer churches (its org_ id or slug). The church must be one of yours, the key must be allowed to act for it, and plan checks run against that church. (string, e.g. org_0192f7a8-3b1c-7d2e-9a40-5c6d7e8f9012)

Responses

200 Success. List webhook endpoints.
200 example
{
  "status": true,
  "message": "webhook_endpoints",
  "data": [
    {
      "id": "whe_0192f7a8-3b1c-7d2e-9a40-5c6d7e8f9012",
      "object": "webhook_endpoint",
      "name": "Sunday pipeline",
      "url": "https://hooks.example.org/folio",
      "event_types": [
        "teaching.ready",
        "note.published"
      ],
      "mode": "live",
      "status": "active",
      "api_version": "2026-12-01",
      "child_scope": "none",
      "church_ids": [],
      "consecutive_failures": 0,
      "last_success_at": "2026-11-01T12:31:04Z",
      "last_failure_at": null,
      "created_at": "2026-10-20T09:00:00Z",
      "stats": {
        "delivered": 42,
        "failed": 1,
        "pending": 0,
        "window_days": 30,
        "last_delivery_at": "2026-11-01T12:31:04Z"
      }
    }
  ],
  "meta": {
    "request_id": "req_b337770ecebe03b03a88a8998b59263d",
    "has_next": false,
    "has_prev": false
  }
}
400 The request could not be read.
400 example
{
  "status": false,
  "message": "the page cursor is not valid",
  "error": {
    "code": "invalid_argument",
    "status": 400,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
401 The key or session is missing, invalid or expired.
401 example
{
  "status": false,
  "message": "That API key is not valid or has expired.",
  "error": {
    "code": "unauthenticated",
    "status": 401,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
403 The credential lacks the scope, the church is suspended, the feature is not in the plan, or the address is not allowed.
403 example
{
  "status": false,
  "message": "That API key does not have the required scope.",
  "error": {
    "code": "permission_denied",
    "status": 403,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
404 The resource is not in this church.
404 example
{
  "status": false,
  "message": "That item is not in this church.",
  "error": {
    "code": "not_found",
    "status": 404,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
409 Conflict, including a duplicate Idempotency-Key still being processed.
409 example
{
  "status": false,
  "message": "A request with this Idempotency-Key is still running.",
  "error": {
    "code": "conflict",
    "status": 409,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
422 A field failed validation, or an Idempotency-Key was reused with a different body.
422 example
{
  "status": false,
  "message": "A field is not valid.",
  "error": {
    "code": "validation",
    "status": 422,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
429 Rate limited. Wait Retry-After seconds.
429 example
{
  "status": false,
  "message": "Too many requests. Wait before trying again.",
  "error": {
    "code": "rate_limited",
    "status": 429,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
500 Something went wrong. Quote error.request_id.
500 example
{
  "status": false,
  "message": "Something went wrong. Quote the request id to support.",
  "error": {
    "code": "internal",
    "status": 500,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}

Code samples

curl -X GET "$FOLIO_API_URL/v1/webhook-endpoints" \
  -H "Authorization: Bearer $FOLIO_API_KEY"

POST/v1/webhook-endpoints

Create a webhook endpoint#

Registers a public https URL to receive events. event_types takes types from the event catalogue, or * for every event including ones added later. The response carries the signing secret (whsec_…) once; store it, you cannot read it again. Use it to verify the webhook-signature header.

mode is live or test. Partner keys can set child_scope to also receive customer churches' events (all) or only some (selected with church_ids).

Use POST /v1/webhook-endpoints/{endpoint}/test right after to check your receiver.

Auth. A church API key. Needs the webhooks:write scope, or a wildcard that includes it (machine:*, * on a partner key). A partner key can call it for a customer church by sending X-Folio-Church.

Plan. Needs the API feature. Sandbox churches cannot receive outbound webhooks.

Limits. Responses carry RateLimit-Limit and RateLimit-Remaining; a 429 carries Retry-After.

Auth
Church API key
Scope
webhooks:write
Plan
Needs the API feature. Sandbox churches cannot receive outbound webhooks.
Operation id
machineCreateWebhookEndpoint

Parameters

Parameters
NameInDescription
Idempotency-KeyheaderMakes a retry safe. The same key with the same body replays the first response for 24 hours; the same key with a different body returns 422; a duplicate that is still running returns 409 with Retry-After. Responses that carry a one-time secret are not replayed. (string, e.g. sunday-2026-11-01-upload)
X-Folio-ChurchheaderPartner keys only: run this call as one of your customer churches (its org_ id or slug). The church must be one of yours, the key must be allowed to act for it, and plan checks run against that church. (string, e.g. org_0192f7a8-3b1c-7d2e-9a40-5c6d7e8f9012)

Request body

Request body fields
FieldTypeDescription
child_scopeenum: none | all | selectedPartner keys: also receive customer churches' events.
church_idsstring[]The customer churches this applies to.
event_typesstring[]Event types from GET /v1/webhook-event-types, or * for every event.
modeenum: live | testlive or test.
namestringThe name.
urlstringA public https URL.
Example request body
{
  "name": "Sunday pipeline",
  "url": "https://hooks.example.org/folio",
  "event_types": [
    "teaching.ready",
    "note.published"
  ],
  "mode": "live"
}

Responses

Response data fields
FieldTypeDescription
endpointobject
api_versionstringThe payload version this endpoint receives.
child_scopeenum: none | all | selectedPartner endpoints: none receives this church's own events, all also receives every customer church's events, selected only the churches in church_ids.
church_idsstring[]The customer churches this applies to.
consecutive_failuresinteger (int32)Deliveries that failed in a row. At 20 the endpoint is disabled.
created_atstringWhen it was created, in RFC 3339 UTC.
disabled_reasonstringWhy the endpoint was disabled, when it was.
event_typesstring[]The event types, or * for all.
idstringThe id, with a type prefix such as tch_ or note_.
last_failure_atstringWhen a delivery last failed.
last_success_atstringWhen a delivery last succeeded.
modestringlive or test.
namestringThe name.
objectstringThe object type.
statsobject
deliveredinteger (int64)Whether your receiver answered 2xx.
failedinteger (int64)How many deliveries failed.
last_delivery_atstringWhen the last delivery was attempted.
pendinginteger (int64)How many deliveries are waiting.
window_daysinteger (int64)The number of days the counts cover.
statusstringThe current status.
urlstringThe URL.
secretstringThe signing secret. Shown once.
200 Success. Create a webhook endpoint.
200 example
{
  "status": true,
  "message": "webhook_endpoint",
  "data": {
    "endpoint": {
      "id": "whe_0192f7a8-3b1c-7d2e-9a40-5c6d7e8f9012",
      "object": "webhook_endpoint",
      "name": "Sunday pipeline",
      "url": "https://hooks.example.org/folio",
      "event_types": [
        "teaching.ready",
        "note.published"
      ],
      "mode": "live",
      "status": "active",
      "api_version": "2026-12-01",
      "child_scope": "none",
      "church_ids": [],
      "consecutive_failures": 0,
      "last_success_at": "2026-11-01T12:31:04Z",
      "last_failure_at": null,
      "created_at": "2026-10-20T09:00:00Z",
      "stats": {
        "delivered": 42,
        "failed": 1,
        "pending": 0,
        "window_days": 30,
        "last_delivery_at": "2026-11-01T12:31:04Z"
      }
    },
    "secret": "whsec_3f9d1c7a0b2e4f68a5d4c3b2a1908f7e"
  }
}
400 The URL is not a public https endpoint, or an event type is not recognised.
400 example
{
  "status": false,
  "message": "That URL must be a public https endpoint.",
  "error": {
    "code": "invalid_argument",
    "status": 400,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
401 The key or session is missing, invalid or expired.
401 example
{
  "status": false,
  "message": "That API key is not valid or has expired.",
  "error": {
    "code": "unauthenticated",
    "status": 401,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
403 The credential lacks the scope, the church is suspended, the feature is not in the plan, or the address is not allowed.
403 example
{
  "status": false,
  "message": "That API key does not have the required scope.",
  "error": {
    "code": "permission_denied",
    "status": 403,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
404 The resource is not in this church.
404 example
{
  "status": false,
  "message": "That item is not in this church.",
  "error": {
    "code": "not_found",
    "status": 404,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
409 Conflict, including a duplicate Idempotency-Key still being processed.
409 example
{
  "status": false,
  "message": "A request with this Idempotency-Key is still running.",
  "error": {
    "code": "conflict",
    "status": 409,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
422 A field failed validation, or an Idempotency-Key was reused with a different body.
422 example
{
  "status": false,
  "message": "A field is not valid.",
  "error": {
    "code": "validation",
    "status": 422,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
429 Rate limited. Wait Retry-After seconds.
429 example
{
  "status": false,
  "message": "Too many requests. Wait before trying again.",
  "error": {
    "code": "rate_limited",
    "status": 429,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
500 Something went wrong. Quote error.request_id.
500 example
{
  "status": false,
  "message": "Something went wrong. Quote the request id to support.",
  "error": {
    "code": "internal",
    "status": 500,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}

Code samples

curl -X POST "$FOLIO_API_URL/v1/webhook-endpoints" \
  -H "Authorization: Bearer $FOLIO_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: endpoint-sunday-pipeline" \
  -d '{
  "name": "Sunday pipeline",
  "url": "https://hooks.example.org/folio",
  "event_types": [
    "teaching.ready",
    "note.published"
  ],
  "mode": "live"
}'

PATCH/v1/webhook-endpoints/{endpoint}

Update a webhook endpoint#

Changes an endpoint's name, URL, events, mode or church scope. The URL is checked again. The signing secret does not change unless you rotate it. Sending a full body is the safest: fields you leave out are cleared to their defaults.

Auth. A church API key. Needs the webhooks:write scope, or a wildcard that includes it (machine:*, * on a partner key). A partner key can call it for a customer church by sending X-Folio-Church.

Limits. Responses carry RateLimit-Limit and RateLimit-Remaining; a 429 carries Retry-After.

Auth
Church API key
Scope
webhooks:write
Operation id
machineUpdateWebhookEndpoint

Parameters

Parameters
NameInDescription
endpoint requiredpathThe webhook endpoint id, such as whe_0192f7a8-3b1c-7d2e-9a40-5c6d7e8f9012. (string, e.g. whe_0192f7a8-3b1c-7d2e-9a40-5c6d7e8f9012)
Idempotency-KeyheaderMakes a retry safe. The same key with the same body replays the first response for 24 hours; the same key with a different body returns 422; a duplicate that is still running returns 409 with Retry-After. Responses that carry a one-time secret are not replayed. (string, e.g. sunday-2026-11-01-upload)
X-Folio-ChurchheaderPartner keys only: run this call as one of your customer churches (its org_ id or slug). The church must be one of yours, the key must be allowed to act for it, and plan checks run against that church. (string, e.g. org_0192f7a8-3b1c-7d2e-9a40-5c6d7e8f9012)

Request body

Request body fields
FieldTypeDescription
child_scopeenum: none | all | selectednone, all or selected: whether a partner endpoint also receives customer churches' events.
church_idsstring[]The customer churches this applies to.
dedupeobjectDeduplication settings.
event_typesstring[]The event types, or * for all.
filterobjectFilter settings.
modeenum: live | testlive or test.
namestringThe name.
shapeobjectPayload shaping settings.
urlstringThe URL.
Example request body
{
  "name": "Sunday pipeline",
  "url": "https://hooks.example.org/folio",
  "event_types": [
    "teaching.ready",
    "teaching.failed",
    "note.published"
  ],
  "filter": {},
  "shape": {},
  "dedupe": {},
  "mode": "live"
}

Responses

Response data fields
FieldTypeDescription
api_versionstringThe payload version this endpoint receives.
child_scopeenum: none | all | selectedPartner endpoints: none receives this church's own events, all also receives every customer church's events, selected only the churches in church_ids.
church_idsstring[]The customer churches this applies to.
consecutive_failuresinteger (int32)Deliveries that failed in a row. At 20 the endpoint is disabled.
created_atstringWhen it was created, in RFC 3339 UTC.
disabled_reasonstringWhy the endpoint was disabled, when it was.
event_typesstring[]The event types, or * for all.
idstringThe id, with a type prefix such as tch_ or note_.
last_failure_atstringWhen a delivery last failed.
last_success_atstringWhen a delivery last succeeded.
modestringlive or test.
namestringThe name.
objectstringThe object type.
statsobject
deliveredinteger (int64)Whether your receiver answered 2xx.
failedinteger (int64)How many deliveries failed.
last_delivery_atstringWhen the last delivery was attempted.
pendinginteger (int64)How many deliveries are waiting.
window_daysinteger (int64)The number of days the counts cover.
statusstringThe current status.
urlstringThe URL.
200 Success. Update a webhook endpoint.
200 example
{
  "status": true,
  "message": "webhook_endpoint",
  "data": {
    "id": "whe_0192f7a8-3b1c-7d2e-9a40-5c6d7e8f9012",
    "object": "webhook_endpoint",
    "name": "Sunday pipeline",
    "url": "https://hooks.example.org/folio",
    "event_types": [
      "teaching.ready",
      "note.published"
    ],
    "mode": "live",
    "status": "active",
    "api_version": "2026-12-01",
    "child_scope": "none",
    "church_ids": [],
    "consecutive_failures": 0,
    "last_success_at": "2026-11-01T12:31:04Z",
    "last_failure_at": null,
    "created_at": "2026-10-20T09:00:00Z",
    "stats": {
      "delivered": 42,
      "failed": 1,
      "pending": 0,
      "window_days": 30,
      "last_delivery_at": "2026-11-01T12:31:04Z"
    }
  }
}
400 The request could not be read.
400 example
{
  "status": false,
  "message": "the page cursor is not valid",
  "error": {
    "code": "invalid_argument",
    "status": 400,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
401 The key or session is missing, invalid or expired.
401 example
{
  "status": false,
  "message": "That API key is not valid or has expired.",
  "error": {
    "code": "unauthenticated",
    "status": 401,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
403 The credential lacks the scope, the church is suspended, the feature is not in the plan, or the address is not allowed.
403 example
{
  "status": false,
  "message": "That API key does not have the required scope.",
  "error": {
    "code": "permission_denied",
    "status": 403,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
404 The resource is not in this church.
404 example
{
  "status": false,
  "message": "That item is not in this church.",
  "error": {
    "code": "not_found",
    "status": 404,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
409 Conflict, including a duplicate Idempotency-Key still being processed.
409 example
{
  "status": false,
  "message": "A request with this Idempotency-Key is still running.",
  "error": {
    "code": "conflict",
    "status": 409,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
422 A field failed validation, or an Idempotency-Key was reused with a different body.
422 example
{
  "status": false,
  "message": "A field is not valid.",
  "error": {
    "code": "validation",
    "status": 422,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
429 Rate limited. Wait Retry-After seconds.
429 example
{
  "status": false,
  "message": "Too many requests. Wait before trying again.",
  "error": {
    "code": "rate_limited",
    "status": 429,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
500 Something went wrong. Quote error.request_id.
500 example
{
  "status": false,
  "message": "Something went wrong. Quote the request id to support.",
  "error": {
    "code": "internal",
    "status": 500,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}

Code samples

curl -X PATCH "$FOLIO_API_URL/v1/webhook-endpoints/whe_0192f7a8-3b1c-7d2e-9a40-5c6d7e8f9012" \
  -H "Authorization: Bearer $FOLIO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Sunday pipeline",
  "url": "https://hooks.example.org/folio",
  "event_types": [
    "teaching.ready",
    "teaching.failed",
    "note.published"
  ],
  "filter": {},
  "shape": {},
  "dedupe": {},
  "mode": "live"
}'

DELETE/v1/webhook-endpoints/{endpoint}

Delete a webhook endpoint#

Deletes an endpoint. Deliveries already queued for it are dropped. This cannot be undone; to pause an endpoint, update its events instead.

Auth. A church API key. Needs the webhooks:write scope, or a wildcard that includes it (machine:*, * on a partner key). A partner key can call it for a customer church by sending X-Folio-Church.

Limits. Responses carry RateLimit-Limit and RateLimit-Remaining; a 429 carries Retry-After.

Auth
Church API key
Scope
webhooks:write
Operation id
machineDeleteWebhookEndpoint

Parameters

Parameters
NameInDescription
endpoint requiredpathThe webhook endpoint id, such as whe_0192f7a8-3b1c-7d2e-9a40-5c6d7e8f9012. (string, e.g. whe_0192f7a8-3b1c-7d2e-9a40-5c6d7e8f9012)
Idempotency-KeyheaderMakes a retry safe. The same key with the same body replays the first response for 24 hours; the same key with a different body returns 422; a duplicate that is still running returns 409 with Retry-After. Responses that carry a one-time secret are not replayed. (string, e.g. sunday-2026-11-01-upload)
X-Folio-ChurchheaderPartner keys only: run this call as one of your customer churches (its org_ id or slug). The church must be one of yours, the key must be allowed to act for it, and plan checks run against that church. (string, e.g. org_0192f7a8-3b1c-7d2e-9a40-5c6d7e8f9012)

Responses

Response data fields
FieldTypeDescription
deletedbooleanWhether it was deleted.
idstringThe id, with a type prefix such as tch_ or note_.
200 Success. Delete a webhook endpoint.
200 example
{
  "status": true,
  "message": "webhook_endpoint",
  "data": {
    "id": "whe_0192f7a8-3b1c-7d2e-9a40-5c6d7e8f9012",
    "deleted": true
  }
}
400 The request could not be read.
400 example
{
  "status": false,
  "message": "the page cursor is not valid",
  "error": {
    "code": "invalid_argument",
    "status": 400,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
401 The key or session is missing, invalid or expired.
401 example
{
  "status": false,
  "message": "That API key is not valid or has expired.",
  "error": {
    "code": "unauthenticated",
    "status": 401,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
403 The credential lacks the scope, the church is suspended, the feature is not in the plan, or the address is not allowed.
403 example
{
  "status": false,
  "message": "That API key does not have the required scope.",
  "error": {
    "code": "permission_denied",
    "status": 403,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
404 The resource is not in this church.
404 example
{
  "status": false,
  "message": "That item is not in this church.",
  "error": {
    "code": "not_found",
    "status": 404,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
409 Conflict, including a duplicate Idempotency-Key still being processed.
409 example
{
  "status": false,
  "message": "A request with this Idempotency-Key is still running.",
  "error": {
    "code": "conflict",
    "status": 409,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
422 A field failed validation, or an Idempotency-Key was reused with a different body.
422 example
{
  "status": false,
  "message": "A field is not valid.",
  "error": {
    "code": "validation",
    "status": 422,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
429 Rate limited. Wait Retry-After seconds.
429 example
{
  "status": false,
  "message": "Too many requests. Wait before trying again.",
  "error": {
    "code": "rate_limited",
    "status": 429,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
500 Something went wrong. Quote error.request_id.
500 example
{
  "status": false,
  "message": "Something went wrong. Quote the request id to support.",
  "error": {
    "code": "internal",
    "status": 500,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}

Code samples

curl -X DELETE "$FOLIO_API_URL/v1/webhook-endpoints/whe_0192f7a8-3b1c-7d2e-9a40-5c6d7e8f9012" \
  -H "Authorization: Bearer $FOLIO_API_KEY"

GET/v1/webhook-endpoints/{endpoint}/deliveries

List recent deliveries#

Lists deliveries to an endpoint, newest first. Filter by status (pending, delivered, failed, skipped), by event type, or by customer church for partner endpoints. A failed delivery shows its last_error and, while retries remain, next_attempt_at.

Auth. A church API key. Needs the webhooks:read scope, or a wildcard that includes it (machine:read, machine:*, * on a partner key). A partner key can call it for a customer church by sending X-Folio-Church.

Limits. Responses carry RateLimit-Limit and RateLimit-Remaining; a 429 carries Retry-After.

Auth
Church API key
Scope
webhooks:read
Operation id
machineListWebhookDeliveries

Parameters

Parameters
NameInDescription
endpoint requiredpathThe webhook endpoint id, such as whe_0192f7a8-3b1c-7d2e-9a40-5c6d7e8f9012. (string, e.g. whe_0192f7a8-3b1c-7d2e-9a40-5c6d7e8f9012)
statusqueryOnly deliveries in this status: pending, delivered, failed or skipped. (string, e.g. failed)
eventqueryOnly deliveries of this event type, such as note.published. (string)
churchqueryThe church slug, such as grace-chapel. For partner routes, the customer church id (org_) or slug. (string)
limitqueryHow many items to return, from 1 to 100. (integer)
cursorqueryThe opaque meta.next_cursor from the previous page. (string)
X-Folio-ChurchheaderPartner keys only: run this call as one of your customer churches (its org_ id or slug). The church must be one of yours, the key must be allowed to act for it, and plan checks run against that church. (string, e.g. org_0192f7a8-3b1c-7d2e-9a40-5c6d7e8f9012)

Responses

200 Success. List recent deliveries.
200 example
{
  "status": true,
  "message": "webhook_deliveries",
  "data": [
    {
      "id": "whd_0192f7a8-3b1c-7d2e-9a40-5c6d7e8f9012",
      "object": "webhook_delivery",
      "event_id": "0192f7a8-3b1c-7d2e-9a40-5c6d7e8f9012",
      "event_type": "note.published",
      "status": "failed",
      "attempts": 3,
      "origin": "live",
      "last_error": "HTTP 500",
      "created_at": "2026-11-01T12:31:00Z",
      "next_attempt_at": "2026-11-01T13:31:00Z",
      "delivered_at": null
    }
  ],
  "meta": {
    "request_id": "req_b337770ecebe03b03a88a8998b59263d",
    "has_next": false,
    "has_prev": false
  }
}
400 The request could not be read.
400 example
{
  "status": false,
  "message": "the page cursor is not valid",
  "error": {
    "code": "invalid_argument",
    "status": 400,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
401 The key or session is missing, invalid or expired.
401 example
{
  "status": false,
  "message": "That API key is not valid or has expired.",
  "error": {
    "code": "unauthenticated",
    "status": 401,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
403 The credential lacks the scope, the church is suspended, the feature is not in the plan, or the address is not allowed.
403 example
{
  "status": false,
  "message": "That API key does not have the required scope.",
  "error": {
    "code": "permission_denied",
    "status": 403,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
404 The resource is not in this church.
404 example
{
  "status": false,
  "message": "That item is not in this church.",
  "error": {
    "code": "not_found",
    "status": 404,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
409 Conflict, including a duplicate Idempotency-Key still being processed.
409 example
{
  "status": false,
  "message": "A request with this Idempotency-Key is still running.",
  "error": {
    "code": "conflict",
    "status": 409,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
422 A field failed validation, or an Idempotency-Key was reused with a different body.
422 example
{
  "status": false,
  "message": "A field is not valid.",
  "error": {
    "code": "validation",
    "status": 422,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
429 Rate limited. Wait Retry-After seconds.
429 example
{
  "status": false,
  "message": "Too many requests. Wait before trying again.",
  "error": {
    "code": "rate_limited",
    "status": 429,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
500 Something went wrong. Quote error.request_id.
500 example
{
  "status": false,
  "message": "Something went wrong. Quote the request id to support.",
  "error": {
    "code": "internal",
    "status": 500,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}

Code samples

curl -X GET "$FOLIO_API_URL/v1/webhook-endpoints/whe_0192f7a8-3b1c-7d2e-9a40-5c6d7e8f9012/deliveries?status=failed" \
  -H "Authorization: Bearer $FOLIO_API_KEY"

GET/v1/webhook-endpoints/{endpoint}/deliveries/{delivery}/attempts

Read what was sent and what came back#

Lists every attempt for a delivery: the exact request (headers with the signature shortened, and the body for 30 days), your receiver's status, latency and the first 2 KB of its answer. Use it to debug a failing receiver.

Auth. A church API key. Needs the webhooks:read scope, or a wildcard that includes it (machine:read, machine:*, * on a partner key). A partner key can call it for a customer church by sending X-Folio-Church.

Limits. Responses carry RateLimit-Limit and RateLimit-Remaining; a 429 carries Retry-After.

Auth
Church API key
Scope
webhooks:read
Operation id
machineListWebhookAttempts

Parameters

Parameters
NameInDescription
endpoint requiredpathThe webhook endpoint id, such as whe_0192f7a8-3b1c-7d2e-9a40-5c6d7e8f9012. (string, e.g. whe_0192f7a8-3b1c-7d2e-9a40-5c6d7e8f9012)
delivery requiredpathThe delivery id, such as whd_0192f7a8-3b1c-7d2e-9a40-5c6d7e8f9012. (string, e.g. whd_0192f7a8-3b1c-7d2e-9a40-5c6d7e8f9012)
X-Folio-ChurchheaderPartner keys only: run this call as one of your customer churches (its org_ id or slug). The church must be one of yours, the key must be allowed to act for it, and plan checks run against that church. (string, e.g. org_0192f7a8-3b1c-7d2e-9a40-5c6d7e8f9012)

Responses

200 Success. Read what was sent and what came back.
200 example
{
  "status": true,
  "message": "webhook_attempts",
  "data": [
    {
      "id": "wha_0192f7a8-3b1c-7d2e-9a40-5c6d7e8f9012",
      "object": "webhook_attempt",
      "attempt_number": 1,
      "trigger": "auto",
      "response_code": 500,
      "response_body": "internal error",
      "duration_ms": 212,
      "error_code": "",
      "error_message": "",
      "request_headers": {
        "webhook-id": "msg_01JC8M2X9R5V0K4T7E3Q6B1ZDN",
        "webhook-signature": "v1,K5oZ…"
      },
      "request_body": {
        "type": "note.published"
      },
      "signed_at": "2026-11-01T12:31:00Z",
      "created_at": "2026-11-01T12:31:00Z"
    }
  ],
  "meta": {
    "request_id": "req_b337770ecebe03b03a88a8998b59263d",
    "has_next": false,
    "has_prev": false
  }
}
400 The request could not be read.
400 example
{
  "status": false,
  "message": "the page cursor is not valid",
  "error": {
    "code": "invalid_argument",
    "status": 400,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
401 The key or session is missing, invalid or expired.
401 example
{
  "status": false,
  "message": "That API key is not valid or has expired.",
  "error": {
    "code": "unauthenticated",
    "status": 401,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
403 The credential lacks the scope, the church is suspended, the feature is not in the plan, or the address is not allowed.
403 example
{
  "status": false,
  "message": "That API key does not have the required scope.",
  "error": {
    "code": "permission_denied",
    "status": 403,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
404 The resource is not in this church.
404 example
{
  "status": false,
  "message": "That item is not in this church.",
  "error": {
    "code": "not_found",
    "status": 404,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
409 Conflict, including a duplicate Idempotency-Key still being processed.
409 example
{
  "status": false,
  "message": "A request with this Idempotency-Key is still running.",
  "error": {
    "code": "conflict",
    "status": 409,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
422 A field failed validation, or an Idempotency-Key was reused with a different body.
422 example
{
  "status": false,
  "message": "A field is not valid.",
  "error": {
    "code": "validation",
    "status": 422,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
429 Rate limited. Wait Retry-After seconds.
429 example
{
  "status": false,
  "message": "Too many requests. Wait before trying again.",
  "error": {
    "code": "rate_limited",
    "status": 429,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
500 Something went wrong. Quote error.request_id.
500 example
{
  "status": false,
  "message": "Something went wrong. Quote the request id to support.",
  "error": {
    "code": "internal",
    "status": 500,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}

Code samples

curl -X GET "$FOLIO_API_URL/v1/webhook-endpoints/whe_0192f7a8-3b1c-7d2e-9a40-5c6d7e8f9012/deliveries/whd_0192f7a8-3b1c-7d2e-9a40-5c6d7e8f9012/attempts" \
  -H "Authorization: Bearer $FOLIO_API_KEY"

POST/v1/webhook-endpoints/{endpoint}/deliveries/{delivery}/replay

Send a delivery again#

Sends the event again as a new delivery with the same payload. Use it after you fix a receiver. The replay has a new webhook-id, so a receiver that deduplicates on it will process it again.

Auth. A church API key. Needs the webhooks:write scope, or a wildcard that includes it (machine:*, * on a partner key). A partner key can call it for a customer church by sending X-Folio-Church.

Limits. Responses carry RateLimit-Limit and RateLimit-Remaining; a 429 carries Retry-After.

Auth
Church API key
Scope
webhooks:write
Operation id
machineReplayWebhookDelivery

Parameters

Parameters
NameInDescription
endpoint requiredpathThe webhook endpoint id, such as whe_0192f7a8-3b1c-7d2e-9a40-5c6d7e8f9012. (string, e.g. whe_0192f7a8-3b1c-7d2e-9a40-5c6d7e8f9012)
delivery requiredpathThe delivery id, such as whd_0192f7a8-3b1c-7d2e-9a40-5c6d7e8f9012. (string, e.g. whd_0192f7a8-3b1c-7d2e-9a40-5c6d7e8f9012)
Idempotency-KeyheaderMakes a retry safe. The same key with the same body replays the first response for 24 hours; the same key with a different body returns 422; a duplicate that is still running returns 409 with Retry-After. Responses that carry a one-time secret are not replayed. (string, e.g. sunday-2026-11-01-upload)
X-Folio-ChurchheaderPartner keys only: run this call as one of your customer churches (its org_ id or slug). The church must be one of yours, the key must be allowed to act for it, and plan checks run against that church. (string, e.g. org_0192f7a8-3b1c-7d2e-9a40-5c6d7e8f9012)

Responses

200 Success. Send a delivery again.
200 example
{
  "status": true,
  "message": "webhook_delivery",
  "data": {
    "id": "whd_0192f7a8-3b1c-7d2e-9a40-5c6d7e8f9012",
    "status": "pending"
  }
}
400 The request could not be read.
400 example
{
  "status": false,
  "message": "the page cursor is not valid",
  "error": {
    "code": "invalid_argument",
    "status": 400,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
401 The key or session is missing, invalid or expired.
401 example
{
  "status": false,
  "message": "That API key is not valid or has expired.",
  "error": {
    "code": "unauthenticated",
    "status": 401,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
403 The credential lacks the scope, the church is suspended, the feature is not in the plan, or the address is not allowed.
403 example
{
  "status": false,
  "message": "That API key does not have the required scope.",
  "error": {
    "code": "permission_denied",
    "status": 403,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
404 The resource is not in this church.
404 example
{
  "status": false,
  "message": "That item is not in this church.",
  "error": {
    "code": "not_found",
    "status": 404,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
409 Conflict, including a duplicate Idempotency-Key still being processed.
409 example
{
  "status": false,
  "message": "A request with this Idempotency-Key is still running.",
  "error": {
    "code": "conflict",
    "status": 409,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
422 A field failed validation, or an Idempotency-Key was reused with a different body.
422 example
{
  "status": false,
  "message": "A field is not valid.",
  "error": {
    "code": "validation",
    "status": 422,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
429 Rate limited. Wait Retry-After seconds.
429 example
{
  "status": false,
  "message": "Too many requests. Wait before trying again.",
  "error": {
    "code": "rate_limited",
    "status": 429,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
500 Something went wrong. Quote error.request_id.
500 example
{
  "status": false,
  "message": "Something went wrong. Quote the request id to support.",
  "error": {
    "code": "internal",
    "status": 500,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}

Code samples

curl -X POST "$FOLIO_API_URL/v1/webhook-endpoints/whe_0192f7a8-3b1c-7d2e-9a40-5c6d7e8f9012/deliveries/whd_0192f7a8-3b1c-7d2e-9a40-5c6d7e8f9012/replay" \
  -H "Authorization: Bearer $FOLIO_API_KEY"

POST/v1/webhook-endpoints/{endpoint}/rotate

Rotate the signing secret#

Issues a new signing secret, returned once. Both secrets sign each message for prev_expires_in_hours (24), so deploy the new secret to your receiver and nothing is dropped. Verify with either during the overlap.

Auth. A church API key. Needs the webhooks:write scope, or a wildcard that includes it (machine:*, * on a partner key). A partner key can call it for a customer church by sending X-Folio-Church.

Limits. Responses carry RateLimit-Limit and RateLimit-Remaining; a 429 carries Retry-After.

Auth
Church API key
Scope
webhooks:write
Operation id
machineRotateWebhookEndpoint

Parameters

Parameters
NameInDescription
endpoint requiredpathThe webhook endpoint id, such as whe_0192f7a8-3b1c-7d2e-9a40-5c6d7e8f9012. (string, e.g. whe_0192f7a8-3b1c-7d2e-9a40-5c6d7e8f9012)
Idempotency-KeyheaderMakes a retry safe. The same key with the same body replays the first response for 24 hours; the same key with a different body returns 422; a duplicate that is still running returns 409 with Retry-After. Responses that carry a one-time secret are not replayed. (string, e.g. sunday-2026-11-01-upload)
X-Folio-ChurchheaderPartner keys only: run this call as one of your customer churches (its org_ id or slug). The church must be one of yours, the key must be allowed to act for it, and plan checks run against that church. (string, e.g. org_0192f7a8-3b1c-7d2e-9a40-5c6d7e8f9012)

Responses

Response data fields
FieldTypeDescription
idstringThe id, with a type prefix such as tch_ or note_.
prev_expires_in_hoursinteger (int64)The previous secret keeps signing alongside the new one for this long.
secretstringThe new signing secret. Shown once.
200 Success. Rotate the signing secret.
200 example
{
  "status": true,
  "message": "webhook_endpoint",
  "data": {
    "id": "whe_0192f7a8-3b1c-7d2e-9a40-5c6d7e8f9012",
    "secret": "whsec_9a8b7c6d5e4f30211203f4e5d6c7b8a9",
    "prev_expires_in_hours": 24
  }
}
400 The request could not be read.
400 example
{
  "status": false,
  "message": "the page cursor is not valid",
  "error": {
    "code": "invalid_argument",
    "status": 400,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
401 The key or session is missing, invalid or expired.
401 example
{
  "status": false,
  "message": "That API key is not valid or has expired.",
  "error": {
    "code": "unauthenticated",
    "status": 401,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
403 The credential lacks the scope, the church is suspended, the feature is not in the plan, or the address is not allowed.
403 example
{
  "status": false,
  "message": "That API key does not have the required scope.",
  "error": {
    "code": "permission_denied",
    "status": 403,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
404 The resource is not in this church.
404 example
{
  "status": false,
  "message": "That item is not in this church.",
  "error": {
    "code": "not_found",
    "status": 404,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
409 Conflict, including a duplicate Idempotency-Key still being processed.
409 example
{
  "status": false,
  "message": "A request with this Idempotency-Key is still running.",
  "error": {
    "code": "conflict",
    "status": 409,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
422 A field failed validation, or an Idempotency-Key was reused with a different body.
422 example
{
  "status": false,
  "message": "A field is not valid.",
  "error": {
    "code": "validation",
    "status": 422,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
429 Rate limited. Wait Retry-After seconds.
429 example
{
  "status": false,
  "message": "Too many requests. Wait before trying again.",
  "error": {
    "code": "rate_limited",
    "status": 429,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
500 Something went wrong. Quote error.request_id.
500 example
{
  "status": false,
  "message": "Something went wrong. Quote the request id to support.",
  "error": {
    "code": "internal",
    "status": 500,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}

Code samples

curl -X POST "$FOLIO_API_URL/v1/webhook-endpoints/whe_0192f7a8-3b1c-7d2e-9a40-5c6d7e8f9012/rotate" \
  -H "Authorization: Bearer $FOLIO_API_KEY" \
  -H "Idempotency-Key: rotate-2026-11"

POST/v1/webhook-endpoints/{endpoint}/test

Send a signed test event#

Sends a real, signed test delivery to the endpoint and reports what your receiver answered. The delivery carries the header Folio-Test: true. Pass event_type to test a specific event's payload; the default is a generic test event.

Auth. A church API key. Needs the webhooks:write scope, or a wildcard that includes it (machine:*, * on a partner key). A partner key can call it for a customer church by sending X-Folio-Church.

Limits. Responses carry RateLimit-Limit and RateLimit-Remaining; a 429 carries Retry-After.

Auth
Church API key
Scope
webhooks:write
Operation id
machineTestWebhookEndpoint

Parameters

Parameters
NameInDescription
endpoint requiredpathThe webhook endpoint id, such as whe_0192f7a8-3b1c-7d2e-9a40-5c6d7e8f9012. (string, e.g. whe_0192f7a8-3b1c-7d2e-9a40-5c6d7e8f9012)
Idempotency-KeyheaderMakes a retry safe. The same key with the same body replays the first response for 24 hours; the same key with a different body returns 422; a duplicate that is still running returns 409 with Retry-After. Responses that carry a one-time secret are not replayed. (string, e.g. sunday-2026-11-01-upload)
X-Folio-ChurchheaderPartner keys only: run this call as one of your customer churches (its org_ id or slug). The church must be one of yours, the key must be allowed to act for it, and plan checks run against that church. (string, e.g. org_0192f7a8-3b1c-7d2e-9a40-5c6d7e8f9012)

Request body

Request body fields
FieldTypeDescription
event_typestringSend this event type's example. Leave empty for a generic test.
Example request body
{
  "event_type": "note.published"
}

Responses

Response data fields
FieldTypeDescription
deliveredbooleanWhether your receiver answered 2xx.
deliverystringThe id of the test delivery.
statusinteger (int64)HTTP status your endpoint answered with.
testbooleanAlways true for a test delivery.
200 Success. Send a signed test event.
200 example
{
  "status": true,
  "message": "webhook_delivery",
  "data": {
    "delivery": "whd_0192f7a8-3b1c-7d2e-9a40-5c6d7e8f9012",
    "delivered": true,
    "status": 200,
    "test": true
  }
}
400 The request could not be read.
400 example
{
  "status": false,
  "message": "the page cursor is not valid",
  "error": {
    "code": "invalid_argument",
    "status": 400,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
401 The key or session is missing, invalid or expired.
401 example
{
  "status": false,
  "message": "That API key is not valid or has expired.",
  "error": {
    "code": "unauthenticated",
    "status": 401,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
403 The credential lacks the scope, the church is suspended, the feature is not in the plan, or the address is not allowed.
403 example
{
  "status": false,
  "message": "That API key does not have the required scope.",
  "error": {
    "code": "permission_denied",
    "status": 403,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
404 The resource is not in this church.
404 example
{
  "status": false,
  "message": "That item is not in this church.",
  "error": {
    "code": "not_found",
    "status": 404,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
409 Conflict, including a duplicate Idempotency-Key still being processed.
409 example
{
  "status": false,
  "message": "A request with this Idempotency-Key is still running.",
  "error": {
    "code": "conflict",
    "status": 409,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
422 A field failed validation, or an Idempotency-Key was reused with a different body.
422 example
{
  "status": false,
  "message": "A field is not valid.",
  "error": {
    "code": "validation",
    "status": 422,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
429 Rate limited. Wait Retry-After seconds.
429 example
{
  "status": false,
  "message": "Too many requests. Wait before trying again.",
  "error": {
    "code": "rate_limited",
    "status": 429,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
500 Something went wrong. Quote error.request_id.
500 example
{
  "status": false,
  "message": "Something went wrong. Quote the request id to support.",
  "error": {
    "code": "internal",
    "status": 500,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}

Code samples

curl -X POST "$FOLIO_API_URL/v1/webhook-endpoints/whe_0192f7a8-3b1c-7d2e-9a40-5c6d7e8f9012/test" \
  -H "Authorization: Bearer $FOLIO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "event_type": "note.published"
}'

GET/v1/webhook-event-types

Read the event catalogue#

Lists every event type Folio can send, grouped by area, with a description, the fields it carries and an example payload. The catalogue is generated from the code that sends events, so it is always current. The same catalogue is readable without a key at GET /v1/public/webhook-events.

Auth. A church API key. Needs the webhooks:read scope, or a wildcard that includes it (machine:read, machine:*, * on a partner key). A partner key can call it for a customer church by sending X-Folio-Church.

Limits. Responses carry RateLimit-Limit and RateLimit-Remaining; a 429 carries Retry-After.

Auth
Church API key
Scope
webhooks:read
Operation id
machineWebhookEventCatalogue

Parameters

Parameters
NameInDescription
X-Folio-ChurchheaderPartner keys only: run this call as one of your customer churches (its org_ id or slug). The church must be one of yours, the key must be allowed to act for it, and plan checks run against that church. (string, e.g. org_0192f7a8-3b1c-7d2e-9a40-5c6d7e8f9012)

Responses

Response data fields
FieldTypeDescription
allstringSubscribe to this value to receive every event.
api_versionstringThe event schema version these definitions describe.
envelopeobject
exampleobjectA complete sample body.
schemaobjectJSON Schema 2020-12 of the body Folio POSTs to your endpoint.
groupsobject[]The groups of events.
schemasobjectShared object schemas that event schemas reference as #/schemas/<name>.
totalinteger (int64)The total number of items.
200 Success. Read the event catalogue.
200 example
{
  "status": true,
  "message": "webhook_event_catalogue",
  "data": {
    "groups": [
      {
        "key": "note",
        "label": "Notes",
        "events": [
          {
            "object": "webhook_event_type",
            "type": "note.published",
            "group": "note",
            "group_label": "Notes",
            "description": "A note was published to its share page.",
            "source": "notes",
            "fields": [
              {
                "name": "teaching_id",
                "type": "string",
                "required": true,
                "description": "The teaching this note belongs to."
              }
            ],
            "example": {
              "type": "note.published"
            }
          }
        ]
      }
    ],
    "total": 1,
    "all": "*"
  }
}
400 The request could not be read.
400 example
{
  "status": false,
  "message": "the page cursor is not valid",
  "error": {
    "code": "invalid_argument",
    "status": 400,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
401 The key or session is missing, invalid or expired.
401 example
{
  "status": false,
  "message": "That API key is not valid or has expired.",
  "error": {
    "code": "unauthenticated",
    "status": 401,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
403 The credential lacks the scope, the church is suspended, the feature is not in the plan, or the address is not allowed.
403 example
{
  "status": false,
  "message": "That API key does not have the required scope.",
  "error": {
    "code": "permission_denied",
    "status": 403,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
404 The resource is not in this church.
404 example
{
  "status": false,
  "message": "That item is not in this church.",
  "error": {
    "code": "not_found",
    "status": 404,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
409 Conflict, including a duplicate Idempotency-Key still being processed.
409 example
{
  "status": false,
  "message": "A request with this Idempotency-Key is still running.",
  "error": {
    "code": "conflict",
    "status": 409,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
422 A field failed validation, or an Idempotency-Key was reused with a different body.
422 example
{
  "status": false,
  "message": "A field is not valid.",
  "error": {
    "code": "validation",
    "status": 422,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
429 Rate limited. Wait Retry-After seconds.
429 example
{
  "status": false,
  "message": "Too many requests. Wait before trying again.",
  "error": {
    "code": "rate_limited",
    "status": 429,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
500 Something went wrong. Quote error.request_id.
500 example
{
  "status": false,
  "message": "Something went wrong. Quote the request id to support.",
  "error": {
    "code": "internal",
    "status": 500,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}

Code samples

curl -X GET "$FOLIO_API_URL/v1/webhook-event-types" \
  -H "Authorization: Bearer $FOLIO_API_KEY"

Verified against API version 0.0.0-dev. Generated from the live OpenAPI document.