Webhook endpoints API
Register HTTPS endpoints to receive HMAC-signed event POSTs whenever something interesting happens in the platform — sessions open, evidence is captured, audit chains anchor. Every delivery is retried with exponential backoff, signed with a per-endpoint secret, and replay-safe via a 5-minute timestamp window.
For the event catalog + payload shapes, see Webhooks overview. This page is the API surface to manage endpoints + inspect delivery attempts.
The Endpoint object
{
"id": "we-1f2a...",
"url": "https://hooks.acme.com/cvp",
"description": "Production claims pipeline",
"event_types": ["session.completed", "evidence.created"],
"active": true,
"created_at": "2026-04-12T09:00:00Z"
}
Note: the signing_secret field is returned exactly
once in the POST response — store it immediately, or rotate it
later via PATCH if you lose it.
List endpoints
GET /api/v1/public/webhook-endpoints — scope webhooks:read
curl https://app.nexbasira.com/api/v1/public/webhook-endpoints \
-H "Authorization: Bearer nb_sec_..." Create an endpoint
POST /api/v1/public/webhook-endpoints — scope webhooks:write
curl -X POST https://app.nexbasira.com/api/v1/public/webhook-endpoints \
-H "Authorization: Bearer nb_sec_..." \
-H "Content-Type: application/json" \
-d '{
"url": "https://hooks.acme.com/cvp",
"description": "Production claims pipeline",
"event_types": ["session.completed", "evidence.created"]
}' Body fields
| Field | Type | Required | Notes |
|---|---|---|---|
url | HTTPS URL | yes | Must be reachable + serve 2xx within 10 s. HTTP rejected. |
description | string | no | Free-text label. Helps when you have multiple endpoints per org. |
event_types | string[] | no | Subscribe only to a subset of event types. Omit / empty = subscribe to everything. |
{
"id": "we-1f2a...",
"url": "https://hooks.acme.com/cvp",
"description": "Production claims pipeline",
"event_types": ["session.completed", "evidence.created"],
"active": true,
"created_at": "2026-04-12T09:00:00Z",
"signing_secret": "whsec_4f9d2a8b3c1e..."
}
The signing_secret is the HMAC-SHA256 key the platform uses to
sign every POST. Verify the NB-Signature header on your
receiver — our SDKs ship a one-liner helper.
Retrieve / update / delete
GET / PATCH / DELETE /api/v1/public/webhook-endpoints/{endpoint_id}
GET needs webhooks:read; PATCH + DELETE need
webhooks:write. PATCH accepts the same body shape as POST —
every field optional. Use it to pause an endpoint
({"active": false}), narrow its subscription, or rotate
the signing secret.
Rotate the signing secret
curl -X PATCH https://app.nexbasira.com/api/v1/public/webhook-endpoints/we-1f2a... \
-H "Authorization: Bearer nb_sec_..." \
-H "Content-Type: application/json" \
-d '{"rotate_secret": true}' The new secret is returned exactly once in the response body, same shape as the create call. Both old + new secrets are valid for the next 24 h to give your receiver time to deploy — after that the old one is revoked.
Inspect delivery attempts
GET /api/v1/public/webhook-events — scope webhooks:read
Last 100 delivery attempts for the credential's org. Filter by
?endpoint={id} or
?status=pending|delivered|failed|dropped.
{
"data": [{
"id": "wev-9a01...",
"endpoint": "we-1f2a...",
"event_type": "session.completed",
"status": "delivered",
"response_status": 200,
"attempt_count": 1,
"created_at": "2026-05-23T10:32:00Z",
"delivered_at": "2026-05-23T10:32:01Z"
}],
"has_more": false,
"next_cursor": null
} Retry cadence
Failed deliveries retry on this schedule, then drop:
- +30 seconds
- +5 minutes
- +1 hour
- +6 hours
- +24 hours
- after that →
dropped(visible in the delivery log)
Common errors
| Status | Code | When |
|---|---|---|
| 400 | validation_error | Non-HTTPS URL, unknown event type, or unreachable endpoint at create time. |
| 403 | permission_denied | Credential lacks the scope. |
| 404 | not_found | Endpoint doesn't exist in the credential's org. |
| 409 | endpoint_paused | Trying to send a test-fire to an active=false endpoint. |