Webhook endpoints
Hear when something happens to your records.
The FolioWebhook object
Attributes
idrequired Type:stringurlrequired Type:stringeventsrequired Type:string[]created_atrequired Type:string
List folio's webhook endpoints
GET /folio/webhooks
Needs folio:settings:manage: Retention classes, reason settings, protected folders, webhooks
folio's endpoints only; Nib's are listed by GET /nib/webhooks.
Returns
200Type:FolioWebhookListThe endpoints400Type:Probleminvalid_request,invalid_version,idempotency_key_requiredorinvalid_signature401Type:Problemunauthorized403Type:Problempermission_denied,org_suspended, oraddress_not_allowed(your organisation only accepts requests from the addresses it has listed)404Type:Problemnot_found421Type:Problemwrong_region429Type:Problemrate_limitedorquota_exceededdefaultType:Probleminternal
curl "https://api.unforged.sh/folio/webhooks" \
-H "Authorization: Bearer $UNFORGED_KEY" \
-H "Unforged-Version: 2026-10-14" import requests
r = requests.get(
"https://api.unforged.sh/folio/webhooks",
headers={"Authorization": f"Bearer {UNFORGED_KEY}", "Unforged-Version": "2026-10-14"},
)
print(r.json()) const res = await fetch('https://api.unforged.sh/folio/webhooks', {
method: 'GET',
headers: { Authorization: `Bearer ${process.env.UNFORGED_KEY}`, 'Unforged-Version': '2026-10-14' },
});
console.log(await res.json()); Create a folio webhook endpoint
POST /folio/webhooks
Needs folio:settings:manage: Retention classes, reason settings, protected folders, webhooks
Like POST /nib/webhooks (the same signing, retries, delivery log and connection test), for folio's events: folio.record.filed, folio.hold.applied, folio.hold.released, folio.record.disposed, folio.integrity.alert, folio.export.ready, folio.restore.ready. The secret is shown once. No Idempotency-Key: a retry creates another endpoint.
Request body
urlrequired Type:stringeventsrequired Type:"folio.record.filed""folio.hold.applied""folio.hold.released""folio.record.disposed""folio.integrity.alert""folio.export.ready""folio.restore.ready"[]
Returns
201Type:FolioWebhookCreatedCreated400Type:Probleminvalid_request,invalid_version,idempotency_key_requiredorinvalid_signature401Type:Problemunauthorized403Type:Problempermission_denied,org_suspended, oraddress_not_allowed(your organisation only accepts requests from the addresses it has listed)404Type:Problemnot_found409Type:Problemconflict,idempotency_conflict,idempotency_in_progressoridempotency_not_replayable421Type:Problemwrong_region429Type:Problemrate_limitedorquota_exceededdefaultType:Probleminternal
curl -X POST "https://api.unforged.sh/folio/webhooks" \
-H "Authorization: Bearer $UNFORGED_KEY" \
-H "Unforged-Version: 2026-10-14" \
-H "Content-Type: application/json" \
-d '{
"url": "https://hooks.example.com/folio",
"events": [
"folio.record.filed"
]
}' import requests
r = requests.post(
"https://api.unforged.sh/folio/webhooks",
headers={"Authorization": f"Bearer {UNFORGED_KEY}", "Unforged-Version": "2026-10-14"},
json={
"url": "https://hooks.example.com/folio",
"events": [
"folio.record.filed"
]
},
)
print(r.json()) const res = await fetch('https://api.unforged.sh/folio/webhooks', {
method: 'POST',
headers: { Authorization: `Bearer ${process.env.UNFORGED_KEY}`, 'Unforged-Version': '2026-10-14', 'Content-Type': 'application/json' },
body: JSON.stringify({
"url": "https://hooks.example.com/folio",
"events": [
"folio.record.filed"
]
}),
});
console.log(await res.json()); Delete a folio webhook endpoint
DELETE /folio/webhooks/{webhook_id}
Needs folio:settings:manage: Retention classes, reason settings, protected folders, webhooks
404 for an unknown endpoint and for a Nib endpoint.
Parameters
webhook_idpathrequired Type:string
Returns
204Deleted400Type:Probleminvalid_request,invalid_version,idempotency_key_requiredorinvalid_signature401Type:Problemunauthorized403Type:Problempermission_denied,org_suspended, oraddress_not_allowed(your organisation only accepts requests from the addresses it has listed)404Type:Problemnot_found421Type:Problemwrong_region429Type:Problemrate_limitedorquota_exceededdefaultType:Probleminternal
curl -X DELETE "https://api.unforged.sh/folio/webhooks/{webhook_id}" \
-H "Authorization: Bearer $UNFORGED_KEY" \
-H "Unforged-Version: 2026-10-14" import requests
r = requests.delete(
"https://api.unforged.sh/folio/webhooks/{webhook_id}",
headers={"Authorization": f"Bearer {UNFORGED_KEY}", "Unforged-Version": "2026-10-14"},
)
print(r.json()) const res = await fetch('https://api.unforged.sh/folio/webhooks/{webhook_id}', {
method: 'DELETE',
headers: { Authorization: `Bearer ${process.env.UNFORGED_KEY}`, 'Unforged-Version': '2026-10-14' },
});
console.log(await res.json());