Webhook endpoints API
Register webhook endpoints, choose their events, rotate signing secrets, send test deliveries and read delivery results from your own servers.
Call these operations from your own servers with an sk_ server API key that carries the read:webhooks scope (reads) or the write:webhooks scope (changes). Every call is scoped to your
organisation, and the endpoints you manage here are the ones the Backoffice shows (Integrations & API, Webhooks): one list.
Scopes. read:webhooks covers every read: GET /v1/webhooks, GET /v1/webhooks/{webhookId}, GET /v1/webhooks/{webhookId}/deliveries and GET /v1/webhooks/event-types. write:webhooks covers every change: creating, updating and deleting an endpoint, rotating its signing secret and sending a test delivery. write:webhooks does not include reading, so a key that manages endpoints needs both. A call without the scope answers 403 with API key does not have read:webhooks scope (or write:webhooks): the message names the missing scope. A key keeps its scopes until a tenant administrator changes them in the Backoffice (API Configuration, Edit scopes on the key: the key id and the secret stay the same and nothing has to be redeployed; an added scope reaches the API within about a minute, a removed scope stops working at once); the other way is to create a new key with the scopes ticked.
The events themselves, their payloads and the delivery rules (headers, signature, retries, deduplication) are described with the API each event belongs to: identity verification (KYC, KYB, KYM),
device intelligence (risk scoring, accounts) and the Pulse tenant API. A test delivery with POST /v1/webhooks/{webhookId}/test sends a sample of any of them.
| Environment | Base URL |
|---|---|
| Production | https://collect.noxtica.com |
Credential: ApiKeyAuth. See Authentication.
Webhook Endpoints
9 operations
- GET /v1/webhooks/event-types List the events you can subscribe to
- GET /v1/webhooks List your webhook endpoints
- POST /v1/webhooks Register a webhook endpoint
- GET /v1/webhooks/{webhookId} Read a webhook endpoint
- PUT /v1/webhooks/{webhookId} Change a webhook endpoint
- DELETE /v1/webhooks/{webhookId} Delete a webhook endpoint
- POST /v1/webhooks/{webhookId}/rotate-secret Rotate the signing secret of an endpoint
- POST /v1/webhooks/{webhookId}/test Send a test delivery to an endpoint
- GET /v1/webhooks/{webhookId}/deliveries List recent deliveries of an endpoint
List the events you can subscribe to
GET /v1/webhooks/event-types
Server-to-server. Returns every event type an endpoint can subscribe to, grouped by product (kyc, kyb, kym, risk, account, pulse), in display order, with the
name of the data schema each carries. Use it to build a subscription from the live catalog instead of copying event names. identity is true for the events that are delivered
only to an endpoint whose signing secret is sealed at rest (every KYC, KYB and KYM session and review event): rotate the secret of an older endpoint once before subscribing it to them.
The payload of every event is documented in the webhooks section of the identity verification API (KYC, KYB, KYM), the device intelligence API (risk and account) and the
Pulse tenant API; dataType names the schema.
Authentication: Bearer token (ApiKeyAuth), scope read:webhooks.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
product | query | string | No | Return only the events of one product. Allowed values: kyc, kyb, kym, risk, account, pulse. |
Responses
| Status | Meaning | Error codes | Content |
|---|---|---|---|
200 | The event catalog. | application/json WebhookEventTypesResponse | |
400 | invalid_query_parameters (an unknown query parameter) or invalid_product. | invalid_product, invalid_query_parameters | application/json WebhookApiError |
401 | The Authorization: Bearer sk_... header is missing or malformed, or the key is unknown, revoked, or belongs to a suspended or deleted organisation. The body is deliberately identical for every cause. | invalid_api_key | application/json InvalidApiKeyError |
403 | The API key is valid but does not carry the scope this operation requires; error names the missing scope. | API key does not have read:device scope | application/json ScopeForbiddenError |
404 | The byte-identical “V1 endpoint not found” response returned when the route’s module is not enabled for your organisation, and also for a path that does not exist — indistinguishable by design (anti-enumeration), so do not treat it as proof the path is wrong. | V1 endpoint not found | application/json |
429 | rate_limit_exceeded: too many requests. Wait Retry-After seconds (also retryAfter in the body) before retrying. The test delivery has a tighter limit than the other operations. | rate_limit_exceeded | application/json WebhookApiError |
503 | Noxtica could not read the key’s record. This is a temporary fault on Noxtica’s side and says nothing about your key. Retry after the Retry-After delay; do not treat it as a revoked key. | api_key_auth_unavailable | application/json |
Response headers
| Status | Header | Type | Description |
|---|---|---|---|
429 | Retry-After | integer | Seconds until the bucket allows another request. |
503 | Retry-After | integer | Seconds to wait before retrying. |
Response fields (200, application/json)
| Field | Type | Always returned | Description |
|---|---|---|---|
ok | boolean | Yes | Allowed values: true. |
products | array of string | Yes | |
eventTypes | array of WebhookEventTypeEntry | Yes | |
eventTypes[] | object (WebhookEventTypeEntry) | No | |
eventTypes[].type | string | Yes | A webhook event type, exactly as it appears in the envelope type, the X-Noxtica-Event header and an endpoint’s events. Allowed values: kyc.session.created, kyc.session.opened, kyc.session.verifying, kyc.session.review_pending, kyc.session.completed, kyc.session.unverified, kyc.session.error, kyc.session.expired, kyc.session.cancelled, kyc.review.decided, kyc.verification.completed, kyc.erasure.completed, kyc.document.expiry_warning, kyc.reverification.due, kyb.session.created, kyb.session.opened, kyb.session.submitted, kyb.session.under_review, kyb.session.completed, kyb.session.expired, kyb.session.abandoned, kyb.entity.created, kyb.entity.under_review, kyb.entity.closed, kym.session.created, kym.session.opened, kym.session.submitted, kym.session.under_review, kym.session.completed, kym.session.expired, kym.session.abandoned, kym.case.status_changed, kym.alert.created, submission.scored, risk.flagged, risk.high, risk.cluster_flagged, account.agent_linked, pulse.detection.v1, pulse.enrolment.linked.v1, and 1 more. |
eventTypes[].product | string | Yes | Allowed values: kyc, kyb, kym, risk, account, pulse. |
eventTypes[].group | string | Yes | What the event is about inside its product: session, verification, review, erasure, monitoring, entity, case, alert, scoring, agent, detection, link or response. |
eventTypes[].label | string | Yes | A short English name. |
eventTypes[].description | string | Yes | One sentence saying when the event fires. |
eventTypes[].schemaVersion | string | Yes | The version of the data member. Allowed values: 1. |
eventTypes[].dataType | string | Yes | The name of the schema of the data member. |
eventTypes[].identity | boolean | Yes | true when the event is delivered only to an endpoint with a sealed signing secret. |
requestId | string | No |
Response example (200)
{
"ok": true,
"products": [
"kyc",
"kyb",
"kym",
"risk",
"account",
"pulse"
],
"eventTypes": [
{
"type": "kyc.session.created",
"product": "kyc",
"group": "session",
"label": "Session created",
"description": "A hosted KYC session (invitation) was minted.",
"schemaVersion": "1",
"dataType": "KycSessionLifecycleData",
"identity": true
},
{
"type": "kyc.session.completed",
"product": "kyc",
"group": "session",
"label": "Session finished",
"description": "A hosted KYC session reached a terminal outcome: completed, unverified or error.",
"schemaVersion": "1",
"dataType": "KycSessionCompletedData",
"identity": true
}
],
"requestId": "req-test"
}
Example request
curl
curl "https://collect.noxtica.com/v1/webhooks/event-types" \
-H "Authorization: Bearer $NOXTICA_API_KEY"
Node.js (global fetch, Node 18 or later)
const response = await fetch('https://collect.noxtica.com/v1/webhooks/event-types', {
method: 'GET',
headers: {
Authorization: `Bearer ${process.env.NOXTICA_API_KEY}`,
},
});
console.log(response.status, await response.text());
Python (standard library)
import os
import urllib.request
request = urllib.request.Request(
"https://collect.noxtica.com/v1/webhooks/event-types",
headers={
"Authorization": f"Bearer {os.environ['NOXTICA_API_KEY']}",
},
method="GET",
)
with urllib.request.urlopen(request) as response:
print(response.status, response.read().decode())
List your webhook endpoints
GET /v1/webhooks
Server-to-server. Returns every webhook endpoint of your organisation, the ones registered in the Backoffice and the ones created through this API (one store). The signing secret is
never returned. limit is the most endpoints an organisation can register (25).
Authentication: Bearer token (ApiKeyAuth), scope read:webhooks.
Responses
| Status | Meaning | Error codes | Content |
|---|---|---|---|
200 | The endpoints. | application/json WebhookEndpointList | |
401 | The Authorization: Bearer sk_... header is missing or malformed, or the key is unknown, revoked, or belongs to a suspended or deleted organisation. The body is deliberately identical for every cause. | invalid_api_key | application/json InvalidApiKeyError |
403 | The API key is valid but does not carry the scope this operation requires; error names the missing scope. | API key does not have read:device scope | application/json ScopeForbiddenError |
404 | The byte-identical “V1 endpoint not found” response returned when the route’s module is not enabled for your organisation, and also for a path that does not exist — indistinguishable by design (anti-enumeration), so do not treat it as proof the path is wrong. | V1 endpoint not found | application/json |
429 | rate_limit_exceeded: too many requests. Wait Retry-After seconds (also retryAfter in the body) before retrying. The test delivery has a tighter limit than the other operations. | rate_limit_exceeded | application/json WebhookApiError |
503 | webhooks_unavailable: a temporary fault, or webhook_secret_kek_required: encryption of webhook secrets is not available for your organisation, so nothing was written. Retry with backoff. | webhooks_unavailable | application/json WebhookApiError |
503 | Noxtica could not read the key’s record. This is a temporary fault on Noxtica’s side and says nothing about your key. Retry after the Retry-After delay; do not treat it as a revoked key. | api_key_auth_unavailable | application/json |
Response headers
| Status | Header | Type | Description |
|---|---|---|---|
429 | Retry-After | integer | Seconds until the bucket allows another request. |
503 | Retry-After | integer | Seconds to wait before retrying. |
Response fields (200, application/json)
| Field | Type | Always returned | Description |
|---|---|---|---|
ok | boolean | Yes | Allowed values: true. |
webhooks | array of WebhookEndpoint | Yes | |
webhooks[] | object (WebhookEndpoint) | No | One webhook endpoint. The signing secret is never part of it. |
webhooks[].id | string | Yes | |
webhooks[].url | string (uri) | Yes | The HTTPS endpoint Noxtica POSTs to. |
webhooks[].events | array of string | Yes | The event types the endpoint receives. Exact match, no wildcard. |
webhooks[].description | string, nullable | Yes | At most 200 characters. |
webhooks[].enabled | boolean | Yes | A disabled endpoint is kept but receives nothing. |
webhooks[].secretSealed | boolean | Yes | true when the signing secret is stored encrypted, which the session and review events (identity events) require. false for an endpoint created before encrypted storage; rotate its secret once. |
webhooks[].createdAt | integer (int64) | Yes | Unix ms. |
webhooks[].updatedAt | integer (int64) | Yes | Unix ms. |
webhooks[].lastDeliveryAt | integer (int64), nullable | Yes | Unix ms of the last delivery attempt |
webhooks[].lastStatus | string, nullable | Yes | The result of the last attempt: ok, http_<status>, blocked (the URL was refused), error, secret_plaintext_ineligible; null before the first attempt. |
limit | integer | Yes | The most endpoints an organisation can register. |
requestId | string | No |
Response example (200)
{
"ok": true,
"webhooks": [
{
"id": "7f3a2c10-5b8e-4d2a-9c61-0e4a7b9d1f35",
"url": "https://hooks.example.com/noxtica",
"events": [
"kyc.session.created",
"kyc.session.completed",
"kyc.review.decided"
],
"description": "Onboarding backend",
"enabled": true,
"secretSealed": true,
"createdAt": 1790760000000,
"updatedAt": 1790760000000,
"lastDeliveryAt": 1790762445000,
"lastStatus": "ok"
}
],
"limit": 25,
"requestId": "req-test"
}
Example request
curl
curl "https://collect.noxtica.com/v1/webhooks" \
-H "Authorization: Bearer $NOXTICA_API_KEY"
Node.js (global fetch, Node 18 or later)
const response = await fetch('https://collect.noxtica.com/v1/webhooks', {
method: 'GET',
headers: {
Authorization: `Bearer ${process.env.NOXTICA_API_KEY}`,
},
});
console.log(response.status, await response.text());
Python (standard library)
import os
import urllib.request
request = urllib.request.Request(
"https://collect.noxtica.com/v1/webhooks",
headers={
"Authorization": f"Bearer {os.environ['NOXTICA_API_KEY']}",
},
method="GET",
)
with urllib.request.urlopen(request) as response:
print(response.status, response.read().decode())
Register a webhook endpoint
POST /v1/webhooks
Server-to-server. Registers an HTTPS endpoint and the events it receives. The signing secret is returned once, in this response, and never again: store it now. Use rotate-secret
to replace it later.
url must be https, without embedded credentials, and must not point at a private, loopback or internal address; the same URL cannot be registered twice. events is the exact list
of event types the endpoint receives (see GET /v1/webhooks/event-types): there is no wildcard, no default subscription and an empty list is refused, so list every event you want, and
an event type added later is not delivered to an endpoint that did not select it. At most 25 endpoints per organisation. The new endpoint is enabled. The secret is stored encrypted; when
encryption is not available for your organisation the call is refused (503 webhook_secret_kek_required) and nothing is written.
Every create, update, delete and rotation is recorded in the organisation’s audit log with your API key as the actor. The endpoints you create here appear in the Backoffice and the other way round.
Authentication: Bearer token (ApiKeyAuth), scope write:webhooks.
Request body
Content type application/json, required.
| Field | Type | Required | Description |
|---|---|---|---|
url | string (uri) | Yes | HTTPS, no embedded credentials, not a private, loopback or internal address; not already registered. Pattern ^https://. |
events | array of string | Yes | The event types to receive. Duplicates are ignored; the order you send is kept. At least 1 item. |
description | string, nullable | No | A label for you. At most 200 characters. |
Responses
| Status | Meaning | Error codes | Content |
|---|---|---|---|
201 | Endpoint registered. secret is shown only here. | application/json WebhookEndpointWithSecret | |
400 | invalid_json, unknown_field (a key other than url, events, description), invalid_url, invalid_events (not an array, an unknown event type, or empty; message says which), invalid_description (more than 200 characters) or webhook_limit_reached (25 endpoints already). | invalid_description, invalid_events, invalid_json, invalid_url, unknown_field, webhook_limit_reached | application/json WebhookApiError |
401 | The Authorization: Bearer sk_... header is missing or malformed, or the key is unknown, revoked, or belongs to a suspended or deleted organisation. The body is deliberately identical for every cause. | invalid_api_key | application/json InvalidApiKeyError |
403 | The API key is valid but does not carry the scope this operation requires; error names the missing scope. | API key does not have read:device scope | application/json ScopeForbiddenError |
404 | The byte-identical “V1 endpoint not found” response returned when the route’s module is not enabled for your organisation, and also for a path that does not exist — indistinguishable by design (anti-enumeration), so do not treat it as proof the path is wrong. | V1 endpoint not found | application/json |
409 | url_already_registered: this URL is already one of your endpoints. | url_already_registered | application/json WebhookApiError |
413 | The request body exceeded this route’s byte cap. | body_too_large | application/json ErrorEnvelope |
415 | unsupported_media_type: the body is not Content-Type: application/json. | unsupported_media_type | application/json WebhookApiError |
429 | rate_limit_exceeded: too many requests. Wait Retry-After seconds (also retryAfter in the body) before retrying. The test delivery has a tighter limit than the other operations. | rate_limit_exceeded | application/json WebhookApiError |
500 | webhook_secret_encryption_failed: sealing the secret failed; nothing was written. Retry. | webhook_secret_encryption_failed | application/json WebhookApiError |
503 | webhooks_unavailable: a temporary fault, or webhook_secret_kek_required: encryption of webhook secrets is not available for your organisation, so nothing was written. Retry with backoff. | webhook_secret_kek_required, webhooks_unavailable | application/json WebhookApiError |
503 | Noxtica could not read the key’s record. This is a temporary fault on Noxtica’s side and says nothing about your key. Retry after the Retry-After delay; do not treat it as a revoked key. | api_key_auth_unavailable | application/json |
Response headers
| Status | Header | Type | Description |
|---|---|---|---|
429 | Retry-After | integer | Seconds until the bucket allows another request. |
503 | Retry-After | integer | Seconds to wait before retrying. |
Response fields (201, application/json)
| Field | Type | Always returned | Description |
|---|---|---|---|
ok | boolean | Yes | Allowed values: true. |
webhook | object (WebhookEndpoint) | Yes | One webhook endpoint. The signing secret is never part of it. |
webhook.id | string | Yes | |
webhook.url | string (uri) | Yes | The HTTPS endpoint Noxtica POSTs to. |
webhook.events | array of string | Yes | The event types the endpoint receives. Exact match, no wildcard. |
webhook.description | string, nullable | Yes | At most 200 characters. |
webhook.enabled | boolean | Yes | A disabled endpoint is kept but receives nothing. |
webhook.secretSealed | boolean | Yes | true when the signing secret is stored encrypted, which the session and review events (identity events) require. false for an endpoint created before encrypted storage; rotate its secret once. |
webhook.createdAt | integer (int64) | Yes | Unix ms. |
webhook.updatedAt | integer (int64) | Yes | Unix ms. |
webhook.lastDeliveryAt | integer (int64), nullable | Yes | Unix ms of the last delivery attempt |
webhook.lastStatus | string, nullable | Yes | The result of the last attempt: ok, http_<status>, blocked (the URL was refused), error, secret_plaintext_ineligible; null before the first attempt. |
secret | string | Yes | The signing secret. Shown once; store it now. The HMAC key is its UTF-8 bytes. |
requestId | string | No |
Response example (201)
{
"ok": true,
"webhook": {
"id": "7f3a2c10-5b8e-4d2a-9c61-0e4a7b9d1f35",
"url": "https://hooks.example.com/noxtica",
"events": [
"kyc.session.created",
"kyc.session.opened",
"kyc.session.completed",
"kyc.review.decided"
],
"description": "Onboarding backend",
"enabled": true,
"secretSealed": true,
"createdAt": 1790760000000,
"updatedAt": 1790760000000,
"lastDeliveryAt": null,
"lastStatus": null
},
"secret": "whsec_example_do_not_use_0123456789abcdef",
"requestId": "req-test"
}
Example request
curl
curl -X POST "https://collect.noxtica.com/v1/webhooks" \
-H "Authorization: Bearer $NOXTICA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://hooks.example.com/noxtica",
"events": [
"kyc.session.created",
"kyc.session.opened",
"kyc.session.completed",
"kyc.review.decided"
],
"description": "Onboarding backend"
}'
Node.js (global fetch, Node 18 or later)
const response = await fetch('https://collect.noxtica.com/v1/webhooks', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.NOXTICA_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
url: 'https://hooks.example.com/noxtica',
events: [
'kyc.session.created',
'kyc.session.opened',
'kyc.session.completed',
'kyc.review.decided',
],
description: 'Onboarding backend',
}),
});
console.log(response.status, await response.text());
Python (standard library)
import json
import os
import urllib.request
request = urllib.request.Request(
"https://collect.noxtica.com/v1/webhooks",
data=json.dumps({
"url": "https://hooks.example.com/noxtica",
"events": [
"kyc.session.created",
"kyc.session.opened",
"kyc.session.completed",
"kyc.review.decided",
],
"description": "Onboarding backend",
}).encode(),
headers={
"Authorization": f"Bearer {os.environ['NOXTICA_API_KEY']}",
"Content-Type": "application/json",
},
method="POST",
)
with urllib.request.urlopen(request) as response:
print(response.status, response.read().decode())
Read a webhook endpoint
GET /v1/webhooks/{webhookId}
Server-to-server. Returns one endpoint of your organisation. The signing secret is never returned. An id of another organisation is indistinguishable from an unknown id (404 webhook_not_found).
Authentication: Bearer token (ApiKeyAuth), scope read:webhooks.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
webhookId | path | string | Yes | The id of one of your webhook endpoints (id of the endpoint object). Pattern ^[A-Za-z0-9._:-]{1,128}$. |
Responses
| Status | Meaning | Error codes | Content |
|---|---|---|---|
200 | The endpoint. | application/json WebhookEndpointEnvelope | |
401 | The Authorization: Bearer sk_... header is missing or malformed, or the key is unknown, revoked, or belongs to a suspended or deleted organisation. The body is deliberately identical for every cause. | invalid_api_key | application/json InvalidApiKeyError |
403 | The API key is valid but does not carry the scope this operation requires; error names the missing scope. | API key does not have read:device scope | application/json ScopeForbiddenError |
404 | webhook_not_found: no endpoint with this id exists in your organisation (an id of another organisation gets the same answer). | webhook_not_found | application/json WebhookApiError |
429 | rate_limit_exceeded: too many requests. Wait Retry-After seconds (also retryAfter in the body) before retrying. The test delivery has a tighter limit than the other operations. | rate_limit_exceeded | application/json WebhookApiError |
503 | webhooks_unavailable: a temporary fault, or webhook_secret_kek_required: encryption of webhook secrets is not available for your organisation, so nothing was written. Retry with backoff. | webhooks_unavailable | application/json WebhookApiError |
503 | Noxtica could not read the key’s record. This is a temporary fault on Noxtica’s side and says nothing about your key. Retry after the Retry-After delay; do not treat it as a revoked key. | api_key_auth_unavailable | application/json |
Response headers
| Status | Header | Type | Description |
|---|---|---|---|
429 | Retry-After | integer | Seconds until the bucket allows another request. |
503 | Retry-After | integer | Seconds to wait before retrying. |
Response fields (200, application/json)
| Field | Type | Always returned | Description |
|---|---|---|---|
ok | boolean | Yes | Allowed values: true. |
webhook | object (WebhookEndpoint) | Yes | One webhook endpoint. The signing secret is never part of it. |
webhook.id | string | Yes | |
webhook.url | string (uri) | Yes | The HTTPS endpoint Noxtica POSTs to. |
webhook.events | array of string | Yes | The event types the endpoint receives. Exact match, no wildcard. |
webhook.description | string, nullable | Yes | At most 200 characters. |
webhook.enabled | boolean | Yes | A disabled endpoint is kept but receives nothing. |
webhook.secretSealed | boolean | Yes | true when the signing secret is stored encrypted, which the session and review events (identity events) require. false for an endpoint created before encrypted storage; rotate its secret once. |
webhook.createdAt | integer (int64) | Yes | Unix ms. |
webhook.updatedAt | integer (int64) | Yes | Unix ms. |
webhook.lastDeliveryAt | integer (int64), nullable | Yes | Unix ms of the last delivery attempt |
webhook.lastStatus | string, nullable | Yes | The result of the last attempt: ok, http_<status>, blocked (the URL was refused), error, secret_plaintext_ineligible; null before the first attempt. |
requestId | string | No |
Response example (200)
{
"ok": true,
"webhook": {
"id": "7f3a2c10-5b8e-4d2a-9c61-0e4a7b9d1f35",
"url": "https://hooks.example.com/noxtica",
"events": [
"kyc.session.created",
"kyc.session.completed"
],
"description": null,
"enabled": true,
"secretSealed": true,
"createdAt": 1790760000000,
"updatedAt": 1790760000000,
"lastDeliveryAt": 1790762445000,
"lastStatus": "ok"
},
"requestId": "req-test"
}
Example request
curl
curl "https://collect.noxtica.com/v1/webhooks/example-webhookId" \
-H "Authorization: Bearer $NOXTICA_API_KEY"
Node.js (global fetch, Node 18 or later)
const response = await fetch('https://collect.noxtica.com/v1/webhooks/example-webhookId', {
method: 'GET',
headers: {
Authorization: `Bearer ${process.env.NOXTICA_API_KEY}`,
},
});
console.log(response.status, await response.text());
Python (standard library)
import os
import urllib.request
request = urllib.request.Request(
"https://collect.noxtica.com/v1/webhooks/example-webhookId",
headers={
"Authorization": f"Bearer {os.environ['NOXTICA_API_KEY']}",
},
method="GET",
)
with urllib.request.urlopen(request) as response:
print(response.status, response.read().decode())
Change a webhook endpoint
PUT /v1/webhooks/{webhookId}
Server-to-server. Partial update: send only the members you change (url, events, description, enabled); at least one is required. events replaces the whole list. Set enabled
to false to pause deliveries without losing the endpoint; events that occur while it is disabled are not queued for it. The signing secret is not changed (see rotate-secret).
Authentication: Bearer token (ApiKeyAuth), scope write:webhooks.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
webhookId | path | string | Yes | The id of one of your webhook endpoints (id of the endpoint object). Pattern ^[A-Za-z0-9._:-]{1,128}$. |
Request body
Content type application/json, required.
| Field | Type | Required | Description |
|---|---|---|---|
url | string (uri) | No | Pattern ^https://. |
events | array of string | No | Replaces the whole list. At least 1 item. |
description | string, nullable | No | At most 200 characters. |
enabled | boolean | No |
Responses
| Status | Meaning | Error codes | Content |
|---|---|---|---|
200 | The updated endpoint. | application/json WebhookEndpointEnvelope | |
400 | invalid_json, unknown_field, empty_update (no member sent), invalid_url, invalid_events, invalid_description or invalid_enabled (not a boolean). | empty_update, invalid_description, invalid_enabled, invalid_events, invalid_json, invalid_url, unknown_field | application/json WebhookApiError |
401 | The Authorization: Bearer sk_... header is missing or malformed, or the key is unknown, revoked, or belongs to a suspended or deleted organisation. The body is deliberately identical for every cause. | invalid_api_key | application/json InvalidApiKeyError |
403 | The API key is valid but does not carry the scope this operation requires; error names the missing scope. | API key does not have read:device scope | application/json ScopeForbiddenError |
404 | webhook_not_found: no endpoint with this id exists in your organisation (an id of another organisation gets the same answer). | webhook_not_found | application/json WebhookApiError |
409 | url_already_registered: another of your endpoints already uses this URL. | url_already_registered | application/json WebhookApiError |
413 | The request body exceeded this route’s byte cap. | body_too_large | application/json ErrorEnvelope |
415 | unsupported_media_type: the body is not Content-Type: application/json. | unsupported_media_type | application/json WebhookApiError |
429 | rate_limit_exceeded: too many requests. Wait Retry-After seconds (also retryAfter in the body) before retrying. The test delivery has a tighter limit than the other operations. | rate_limit_exceeded | application/json WebhookApiError |
503 | webhooks_unavailable: a temporary fault, or webhook_secret_kek_required: encryption of webhook secrets is not available for your organisation, so nothing was written. Retry with backoff. | webhooks_unavailable | application/json WebhookApiError |
503 | Noxtica could not read the key’s record. This is a temporary fault on Noxtica’s side and says nothing about your key. Retry after the Retry-After delay; do not treat it as a revoked key. | api_key_auth_unavailable | application/json |
Response headers
| Status | Header | Type | Description |
|---|---|---|---|
429 | Retry-After | integer | Seconds until the bucket allows another request. |
503 | Retry-After | integer | Seconds to wait before retrying. |
Response fields (200, application/json)
| Field | Type | Always returned | Description |
|---|---|---|---|
ok | boolean | Yes | Allowed values: true. |
webhook | object (WebhookEndpoint) | Yes | One webhook endpoint. The signing secret is never part of it. |
webhook.id | string | Yes | |
webhook.url | string (uri) | Yes | The HTTPS endpoint Noxtica POSTs to. |
webhook.events | array of string | Yes | The event types the endpoint receives. Exact match, no wildcard. |
webhook.description | string, nullable | Yes | At most 200 characters. |
webhook.enabled | boolean | Yes | A disabled endpoint is kept but receives nothing. |
webhook.secretSealed | boolean | Yes | true when the signing secret is stored encrypted, which the session and review events (identity events) require. false for an endpoint created before encrypted storage; rotate its secret once. |
webhook.createdAt | integer (int64) | Yes | Unix ms. |
webhook.updatedAt | integer (int64) | Yes | Unix ms. |
webhook.lastDeliveryAt | integer (int64), nullable | Yes | Unix ms of the last delivery attempt |
webhook.lastStatus | string, nullable | Yes | The result of the last attempt: ok, http_<status>, blocked (the URL was refused), error, secret_plaintext_ineligible; null before the first attempt. |
requestId | string | No |
Response example (200)
{
"ok": true,
"webhook": {
"id": "7f3a2c10-5b8e-4d2a-9c61-0e4a7b9d1f35",
"url": "https://hooks.example.com/noxtica",
"events": [
"kyc.session.created",
"kyc.session.completed",
"kyb.session.completed"
],
"description": "Onboarding backend",
"enabled": true,
"secretSealed": true,
"createdAt": 1790760000000,
"updatedAt": 1790763000000,
"lastDeliveryAt": 1790762445000,
"lastStatus": "ok"
},
"requestId": "req-test"
}
Example request
curl
curl -X PUT "https://collect.noxtica.com/v1/webhooks/example-webhookId" \
-H "Authorization: Bearer $NOXTICA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"events": [
"kyc.session.created",
"kyc.session.completed",
"kyb.session.completed"
],
"enabled": true
}'
Node.js (global fetch, Node 18 or later)
const response = await fetch('https://collect.noxtica.com/v1/webhooks/example-webhookId', {
method: 'PUT',
headers: {
Authorization: `Bearer ${process.env.NOXTICA_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
events: [
'kyc.session.created',
'kyc.session.completed',
'kyb.session.completed',
],
enabled: true,
}),
});
console.log(response.status, await response.text());
Python (standard library)
import json
import os
import urllib.request
request = urllib.request.Request(
"https://collect.noxtica.com/v1/webhooks/example-webhookId",
data=json.dumps({
"events": [
"kyc.session.created",
"kyc.session.completed",
"kyb.session.completed",
],
"enabled": True,
}).encode(),
headers={
"Authorization": f"Bearer {os.environ['NOXTICA_API_KEY']}",
"Content-Type": "application/json",
},
method="PUT",
)
with urllib.request.urlopen(request) as response:
print(response.status, response.read().decode())
Delete a webhook endpoint
DELETE /v1/webhooks/{webhookId}
Server-to-server. Deletes the endpoint. Deliveries still waiting for it are dropped.
Authentication: Bearer token (ApiKeyAuth), scope write:webhooks.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
webhookId | path | string | Yes | The id of one of your webhook endpoints (id of the endpoint object). Pattern ^[A-Za-z0-9._:-]{1,128}$. |
Responses
| Status | Meaning | Error codes | Content |
|---|---|---|---|
200 | The endpoint was deleted. | application/json WebhookEndpointDeleted | |
401 | The Authorization: Bearer sk_... header is missing or malformed, or the key is unknown, revoked, or belongs to a suspended or deleted organisation. The body is deliberately identical for every cause. | invalid_api_key | application/json InvalidApiKeyError |
403 | The API key is valid but does not carry the scope this operation requires; error names the missing scope. | API key does not have read:device scope | application/json ScopeForbiddenError |
404 | webhook_not_found: no endpoint with this id exists in your organisation (an id of another organisation gets the same answer). | webhook_not_found | application/json WebhookApiError |
429 | rate_limit_exceeded: too many requests. Wait Retry-After seconds (also retryAfter in the body) before retrying. The test delivery has a tighter limit than the other operations. | rate_limit_exceeded | application/json WebhookApiError |
503 | webhooks_unavailable: a temporary fault, or webhook_secret_kek_required: encryption of webhook secrets is not available for your organisation, so nothing was written. Retry with backoff. | webhooks_unavailable | application/json WebhookApiError |
503 | Noxtica could not read the key’s record. This is a temporary fault on Noxtica’s side and says nothing about your key. Retry after the Retry-After delay; do not treat it as a revoked key. | api_key_auth_unavailable | application/json |
Response headers
| Status | Header | Type | Description |
|---|---|---|---|
429 | Retry-After | integer | Seconds until the bucket allows another request. |
503 | Retry-After | integer | Seconds to wait before retrying. |
Response fields (200, application/json)
| Field | Type | Always returned | Description |
|---|---|---|---|
ok | boolean | Yes | Allowed values: true. |
id | string | Yes | |
removed | boolean | Yes | Allowed values: true. |
requestId | string | No |
Response example (200)
{
"ok": true,
"id": "7f3a2c10-5b8e-4d2a-9c61-0e4a7b9d1f35",
"removed": true,
"requestId": "req-test"
}
Example request
curl
curl -X DELETE "https://collect.noxtica.com/v1/webhooks/example-webhookId" \
-H "Authorization: Bearer $NOXTICA_API_KEY"
Node.js (global fetch, Node 18 or later)
const response = await fetch('https://collect.noxtica.com/v1/webhooks/example-webhookId', {
method: 'DELETE',
headers: {
Authorization: `Bearer ${process.env.NOXTICA_API_KEY}`,
},
});
console.log(response.status, await response.text());
Python (standard library)
import os
import urllib.request
request = urllib.request.Request(
"https://collect.noxtica.com/v1/webhooks/example-webhookId",
headers={
"Authorization": f"Bearer {os.environ['NOXTICA_API_KEY']}",
},
method="DELETE",
)
with urllib.request.urlopen(request) as response:
print(response.status, response.read().decode())
Rotate the signing secret of an endpoint
POST /v1/webhooks/{webhookId}/rotate-secret
Server-to-server. Mints a new signing secret, returns it once, and stops the previous secret from verifying at once: deliveries sent after this call are signed with the new secret, so
update your receiver first or accept both for a moment. The secret is stored encrypted, which is what the session and review events require: rotate an endpoint that was created before
encrypted storage once before you subscribe it to them (secretSealed is false until you do). The call has no body.
Authentication: Bearer token (ApiKeyAuth), scope write:webhooks.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
webhookId | path | string | Yes | The id of one of your webhook endpoints (id of the endpoint object). Pattern ^[A-Za-z0-9._:-]{1,128}$. |
Responses
| Status | Meaning | Error codes | Content |
|---|---|---|---|
200 | The endpoint and its new secret. secret is shown only here. | application/json WebhookEndpointWithSecret | |
401 | The Authorization: Bearer sk_... header is missing or malformed, or the key is unknown, revoked, or belongs to a suspended or deleted organisation. The body is deliberately identical for every cause. | invalid_api_key | application/json InvalidApiKeyError |
403 | The API key is valid but does not carry the scope this operation requires; error names the missing scope. | API key does not have read:device scope | application/json ScopeForbiddenError |
404 | webhook_not_found: no endpoint with this id exists in your organisation (an id of another organisation gets the same answer). | webhook_not_found | application/json WebhookApiError |
429 | rate_limit_exceeded: too many requests. Wait Retry-After seconds (also retryAfter in the body) before retrying. The test delivery has a tighter limit than the other operations. | rate_limit_exceeded | application/json WebhookApiError |
500 | webhook_secret_encryption_failed: sealing the new secret failed; the existing secret is unchanged. Retry. | webhook_secret_encryption_failed | application/json WebhookApiError |
503 | webhooks_unavailable: a temporary fault, or webhook_secret_kek_required: encryption of webhook secrets is not available for your organisation, so nothing was written. Retry with backoff. | webhooks_unavailable | application/json WebhookApiError |
503 | Noxtica could not read the key’s record. This is a temporary fault on Noxtica’s side and says nothing about your key. Retry after the Retry-After delay; do not treat it as a revoked key. | api_key_auth_unavailable | application/json |
Response headers
| Status | Header | Type | Description |
|---|---|---|---|
429 | Retry-After | integer | Seconds until the bucket allows another request. |
503 | Retry-After | integer | Seconds to wait before retrying. |
Response fields (200, application/json)
| Field | Type | Always returned | Description |
|---|---|---|---|
ok | boolean | Yes | Allowed values: true. |
webhook | object (WebhookEndpoint) | Yes | One webhook endpoint. The signing secret is never part of it. |
webhook.id | string | Yes | |
webhook.url | string (uri) | Yes | The HTTPS endpoint Noxtica POSTs to. |
webhook.events | array of string | Yes | The event types the endpoint receives. Exact match, no wildcard. |
webhook.description | string, nullable | Yes | At most 200 characters. |
webhook.enabled | boolean | Yes | A disabled endpoint is kept but receives nothing. |
webhook.secretSealed | boolean | Yes | true when the signing secret is stored encrypted, which the session and review events (identity events) require. false for an endpoint created before encrypted storage; rotate its secret once. |
webhook.createdAt | integer (int64) | Yes | Unix ms. |
webhook.updatedAt | integer (int64) | Yes | Unix ms. |
webhook.lastDeliveryAt | integer (int64), nullable | Yes | Unix ms of the last delivery attempt |
webhook.lastStatus | string, nullable | Yes | The result of the last attempt: ok, http_<status>, blocked (the URL was refused), error, secret_plaintext_ineligible; null before the first attempt. |
secret | string | Yes | The signing secret. Shown once; store it now. The HMAC key is its UTF-8 bytes. |
requestId | string | No |
Response example (200)
{
"ok": true,
"webhook": {
"id": "7f3a2c10-5b8e-4d2a-9c61-0e4a7b9d1f35",
"url": "https://hooks.example.com/noxtica",
"events": [
"kyc.session.created",
"kyc.session.completed"
],
"description": null,
"enabled": true,
"secretSealed": true,
"createdAt": 1790760000000,
"updatedAt": 1790764000000,
"lastDeliveryAt": 1790762445000,
"lastStatus": "ok"
},
"secret": "whsec_example_do_not_use_fedcba9876543210",
"requestId": "req-test"
}
Example request
curl
curl -X POST "https://collect.noxtica.com/v1/webhooks/example-webhookId/rotate-secret" \
-H "Authorization: Bearer $NOXTICA_API_KEY"
Node.js (global fetch, Node 18 or later)
const response = await fetch('https://collect.noxtica.com/v1/webhooks/example-webhookId/rotate-secret', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.NOXTICA_API_KEY}`,
},
});
console.log(response.status, await response.text());
Python (standard library)
import os
import urllib.request
request = urllib.request.Request(
"https://collect.noxtica.com/v1/webhooks/example-webhookId/rotate-secret",
headers={
"Authorization": f"Bearer {os.environ['NOXTICA_API_KEY']}",
},
method="POST",
)
with urllib.request.urlopen(request) as response:
print(response.status, response.read().decode())
Send a test delivery to an endpoint
POST /v1/webhooks/{webhookId}/test
Server-to-server. Sends one signed sample delivery of an event type to the endpoint, with the same four headers, envelope and signature as a real delivery, and reports what your receiver answered. Use it to check reachability and signature verification before you rely on an endpoint, and to see the exact payload of any event.
eventType picks the event (any type of GET /v1/webhooks/event-types, whether or not the endpoint subscribes to it); without it the first event of the endpoint is used. The sample carries
obvious placeholder data (ids such as test-session), never real data, and its delivery id starts with test_: ignore deliveries with that prefix in your business logic. A test delivery is
a single attempt: it is not retried, it is not recorded in the delivery list, and it updates the endpoint’s lastStatus. The test is audited before it leaves. A tighter rate limit than the
other operations applies.
The call answers 200 whenever the attempt was made, even when your receiver refused it: read delivered, status and result. The session and review events are signed only with a sealed
secret; for an endpoint that does not have one the answer carries error: secret_plaintext_ineligible and nothing is sent: rotate the secret, then test again.
Authentication: Bearer token (ApiKeyAuth), scope write:webhooks.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
webhookId | path | string | Yes | The id of one of your webhook endpoints (id of the endpoint object). Pattern ^[A-Za-z0-9._:-]{1,128}$. |
Request body
Content type application/json, optional.
| Field | Type | Required | Description |
|---|---|---|---|
eventType | string | No | The event to send a sample of. Default is the first event of the endpoint (submission.scored when it has none). Allowed values: kyc.session.created, kyc.session.opened, kyc.session.verifying, kyc.session.review_pending, kyc.session.completed, kyc.session.unverified, kyc.session.error, kyc.session.expired, kyc.session.cancelled, kyc.review.decided, kyc.verification.completed, kyc.erasure.completed, kyc.document.expiry_warning, kyc.reverification.due, kyb.session.created, kyb.session.opened, kyb.session.submitted, kyb.session.under_review, kyb.session.completed, kyb.session.expired, kyb.session.abandoned, kyb.entity.created, kyb.entity.under_review, kyb.entity.closed, kym.session.created, kym.session.opened, kym.session.submitted, kym.session.under_review, kym.session.completed, kym.session.expired, kym.session.abandoned, kym.case.status_changed, kym.alert.created, submission.scored, risk.flagged, risk.high, risk.cluster_flagged, account.agent_linked, pulse.detection.v1, pulse.enrolment.linked.v1, and 1 more. |
Responses
| Status | Meaning | Error codes | Content |
|---|---|---|---|
200 | The attempt was made (or refused for the reason in error). | application/json WebhookTestResult | |
400 | invalid_json, unknown_field or invalid_event_type (not a type of the event catalog). | invalid_event_type, invalid_json, unknown_field | application/json WebhookApiError |
401 | The Authorization: Bearer sk_... header is missing or malformed, or the key is unknown, revoked, or belongs to a suspended or deleted organisation. The body is deliberately identical for every cause. | invalid_api_key | application/json InvalidApiKeyError |
403 | The API key is valid but does not carry the scope this operation requires; error names the missing scope. | API key does not have read:device scope | application/json ScopeForbiddenError |
404 | webhook_not_found: no endpoint with this id exists in your organisation (an id of another organisation gets the same answer). | webhook_not_found | application/json WebhookApiError |
413 | The request body exceeded this route’s byte cap. | body_too_large | application/json ErrorEnvelope |
415 | unsupported_media_type: a body was sent that is not Content-Type: application/json. | unsupported_media_type | application/json WebhookApiError |
429 | rate_limit_exceeded: too many requests. Wait Retry-After seconds (also retryAfter in the body) before retrying. The test delivery has a tighter limit than the other operations. | rate_limit_exceeded | application/json WebhookApiError |
503 | webhooks_unavailable: a temporary fault, or webhook_secret_kek_required: encryption of webhook secrets is not available for your organisation, so nothing was written. Retry with backoff. | webhooks_unavailable | application/json WebhookApiError |
503 | Noxtica could not read the key’s record. This is a temporary fault on Noxtica’s side and says nothing about your key. Retry after the Retry-After delay; do not treat it as a revoked key. | api_key_auth_unavailable | application/json |
Response headers
| Status | Header | Type | Description |
|---|---|---|---|
429 | Retry-After | integer | Seconds until the bucket allows another request. |
503 | Retry-After | integer | Seconds to wait before retrying. |
Response fields (200, application/json)
| Field | Type | Always returned | Description |
|---|---|---|---|
ok | boolean | Yes | The attempt was made. Allowed values: true. |
delivered | boolean | Yes | true when your receiver answered with a 2xx. |
eventType | string | Yes | |
deliveryId | string | Yes | The delivery id sent in X-Noxtica-Delivery; starts with test_. |
status | integer, nullable | Yes | The HTTP status your receiver answered |
result | string | Yes | The outcome in the lastStatus vocabulary: ok, http_<status>, blocked, error, secret_plaintext_ineligible. |
ms | integer | Yes | How long the attempt took |
error | string | No | Present when nothing was sent because the endpoint’s secret is not sealed and the event needs one. Allowed values: secret_plaintext_ineligible. |
message | string | No | |
requestId | string | No |
Response example (200)
{
"ok": true,
"delivered": true,
"eventType": "kyc.session.created",
"deliveryId": "test_5b8e4d2a-9c61-4a7b-8f35-0e4a7b9d1f35",
"status": 200,
"result": "ok",
"ms": 183,
"requestId": "req-test"
}
Example request
curl
curl -X POST "https://collect.noxtica.com/v1/webhooks/example-webhookId/test" \
-H "Authorization: Bearer $NOXTICA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"eventType": "kyc.session.created"
}'
Node.js (global fetch, Node 18 or later)
const response = await fetch('https://collect.noxtica.com/v1/webhooks/example-webhookId/test', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.NOXTICA_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
eventType: 'kyc.session.created',
}),
});
console.log(response.status, await response.text());
Python (standard library)
import json
import os
import urllib.request
request = urllib.request.Request(
"https://collect.noxtica.com/v1/webhooks/example-webhookId/test",
data=json.dumps({
"eventType": "kyc.session.created",
}).encode(),
headers={
"Authorization": f"Bearer {os.environ['NOXTICA_API_KEY']}",
"Content-Type": "application/json",
},
method="POST",
)
with urllib.request.urlopen(request) as response:
print(response.status, response.read().decode())
List recent deliveries of an endpoint
GET /v1/webhooks/{webhookId}/deliveries
Server-to-server. Returns the recent deliveries of KYC, KYB and KYM events to one endpoint, newest first: what happened to each (still retrying, delivered, refused for good, or dead after the
retry budget). The list is a notification surface, never authority, and it never holds a URL, a body or a secret: lastError is a closed code. Deliveries of the other products (risk scoring,
account and Pulse events) are not listed; their outcome is the endpoint’s lastStatus. Test deliveries are not listed.
Page with cursor: pass the nextCursor of the previous page unchanged; nextCursor is null on the last page.
Authentication: Bearer token (ApiKeyAuth), scope read:webhooks.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
webhookId | path | string | Yes | The id of one of your webhook endpoints (id of the endpoint object). Pattern ^[A-Za-z0-9._:-]{1,128}$. |
limit | query | integer | No | Page size, 1 to 50 (default 25). A value outside the range is refused with 400 limit_out_of_bounds. Minimum 1, maximum 50. Default 25. |
cursor | query | string | No | The nextCursor of the previous page, unchanged. Anything else is refused with 400 invalid_cursor. At most 320 characters. |
Responses
| Status | Meaning | Error codes | Content |
|---|---|---|---|
200 | One page of deliveries. | application/json WebhookDeliveryList | |
400 | invalid_query_parameters, limit_out_of_bounds or invalid_cursor. | invalid_cursor, invalid_query_parameters, limit_out_of_bounds | application/json WebhookApiError |
401 | The Authorization: Bearer sk_... header is missing or malformed, or the key is unknown, revoked, or belongs to a suspended or deleted organisation. The body is deliberately identical for every cause. | invalid_api_key | application/json InvalidApiKeyError |
403 | The API key is valid but does not carry the scope this operation requires; error names the missing scope. | API key does not have read:device scope | application/json ScopeForbiddenError |
404 | webhook_not_found: no endpoint with this id exists in your organisation (an id of another organisation gets the same answer). | webhook_not_found | application/json WebhookApiError |
429 | rate_limit_exceeded: too many requests. Wait Retry-After seconds (also retryAfter in the body) before retrying. The test delivery has a tighter limit than the other operations. | rate_limit_exceeded | application/json WebhookApiError |
503 | webhooks_unavailable: a temporary fault, or webhook_secret_kek_required: encryption of webhook secrets is not available for your organisation, so nothing was written. Retry with backoff. | webhooks_unavailable | application/json WebhookApiError |
503 | Noxtica could not read the key’s record. This is a temporary fault on Noxtica’s side and says nothing about your key. Retry after the Retry-After delay; do not treat it as a revoked key. | api_key_auth_unavailable | application/json |
Response headers
| Status | Header | Type | Description |
|---|---|---|---|
429 | Retry-After | integer | Seconds until the bucket allows another request. |
503 | Retry-After | integer | Seconds to wait before retrying. |
Response fields (200, application/json)
| Field | Type | Always returned | Description |
|---|---|---|---|
ok | boolean | Yes | Allowed values: true. |
deliveries | array of WebhookDelivery | Yes | |
deliveries[] | object (WebhookDelivery) | No | The outcome of one delivery of a KYC, KYB or KYM event to one endpoint. |
deliveries[].id | string | Yes | The delivery id; equals the X-Noxtica-Delivery header and the envelope id. |
deliveries[].eventType | string | Yes | A webhook event type, exactly as it appears in the envelope type, the X-Noxtica-Event header and an endpoint’s events. Allowed values: kyc.session.created, kyc.session.opened, kyc.session.verifying, kyc.session.review_pending, kyc.session.completed, kyc.session.unverified, kyc.session.error, kyc.session.expired, kyc.session.cancelled, kyc.review.decided, kyc.verification.completed, kyc.erasure.completed, kyc.document.expiry_warning, kyc.reverification.due, kyb.session.created, kyb.session.opened, kyb.session.submitted, kyb.session.under_review, kyb.session.completed, kyb.session.expired, kyb.session.abandoned, kyb.entity.created, kyb.entity.under_review, kyb.entity.closed, kym.session.created, kym.session.opened, kym.session.submitted, kym.session.under_review, kym.session.completed, kym.session.expired, kym.session.abandoned, kym.case.status_changed, kym.alert.created, submission.scored, risk.flagged, risk.high, risk.cluster_flagged, account.agent_linked, pulse.detection.v1, pulse.enrolment.linked.v1, and 1 more. |
deliveries[].state | string | Yes | retrying: the last attempt failed and another is scheduled. delivered: your receiver answered with a 2xx. terminal: refused for good (a 4xx, a refused URL, or a secret that cannot sign this event). dead: the retry budget is spent. Allowed values: retrying, delivered, terminal, dead. |
deliveries[].attempts | integer | Yes | Minimum 0. |
deliveries[].httpStatus | integer, nullable | Yes | The HTTP status of the last attempt |
deliveries[].lastError | string, nullable | Yes | A closed code, null for a delivered row: http_<status>, timeout, network_error, blocked_url, secret_plaintext_ineligible, retries_exhausted. |
deliveries[].createdAt | integer (int64) | Yes | Unix ms the delivery was first recorded. |
deliveries[].deliveredAt | integer (int64), nullable | Yes | Unix ms of the successful attempt |
nextCursor | string, nullable | Yes | Pass it as cursor for the next page; null on the last page. |
requestId | string | No |
Response example (200)
{
"ok": true,
"deliveries": [
{
"id": "6d3c3a8e-6b4b-4a8f-8f4e-0a0e6b3d9d21:kyc.session.completed:7f3a2c10-5b8e-4d2a-9c61-0e4a7b9d1f35",
"eventType": "kyc.session.completed",
"state": "delivered",
"attempts": 1,
"httpStatus": 200,
"lastError": null,
"createdAt": 1790762445000,
"deliveredAt": 1790762446000
},
{
"id": "6d3c3a8e-6b4b-4a8f-8f4e-0a0e6b3d9d21:kyc.session.review_pending:7f3a2c10-5b8e-4d2a-9c61-0e4a7b9d1f35",
"eventType": "kyc.session.review_pending",
"state": "retrying",
"attempts": 2,
"httpStatus": 503,
"lastError": "http_503",
"createdAt": 1790762400000,
"deliveredAt": null
}
],
"nextCursor": null,
"requestId": "req-test"
}
Example request
curl
curl "https://collect.noxtica.com/v1/webhooks/example-webhookId/deliveries" \
-H "Authorization: Bearer $NOXTICA_API_KEY"
Node.js (global fetch, Node 18 or later)
const response = await fetch('https://collect.noxtica.com/v1/webhooks/example-webhookId/deliveries', {
method: 'GET',
headers: {
Authorization: `Bearer ${process.env.NOXTICA_API_KEY}`,
},
});
console.log(response.status, await response.text());
Python (standard library)
import os
import urllib.request
request = urllib.request.Request(
"https://collect.noxtica.com/v1/webhooks/example-webhookId/deliveries",
headers={
"Authorization": f"Bearer {os.environ['NOXTICA_API_KEY']}",
},
method="GET",
)
with urllib.request.urlopen(request) as response:
print(response.status, response.read().decode())
This page is generated from the Noxtica OpenAPI specification release v0.16.1: v1.yaml version 1.5.1-2026-11-03 (SHA-256 41508500e857). Do not edit it by hand.