{
"id": "evt_01JA2Z8K6Q4V7W9XBCDEFGHJKM",
"type": "audit.event",
"created_at": "2026-10-29T00:00:00Z",
"data": {
"id": "aud_01JA2ZE5F6G7H8J9K0M1N2P3Q4",
"workspace_id": "tnt_01JA2Z8K6Q4V7W9XBCDEFGHJKM",
"environment": "live",
"action": "member.role_changed",
"outcome": "succeeded",
"actor": {
"type": "user",
"external_user_id": "user_2EXAMPLE",
"console_credential_id": "01JA2Z8K6Q4V7W9XBCDEFGHJKM",
"principal_id": "mem_01JA2Z8K6Q4V7W9XBCDEFGHJKM"
},
"target": {
"type": "member",
"id": "mem_01JA2ZB4C5D6E7F8G9H0JKMNPQ"
},
"detail": {
"role": "admin"
},
"created_at": "2026-10-23T09:10:00.000Z"
}
}Audit event recorded
Event type audit.event. Sent only to an explicit audit-stream subscription. data contains the immutable audit event, with its actor, action, target, outcome and affected environment.
The stream begins at subscription creation. It applies your environment and action filters before each delivery. Use audit exports for available earlier events.
Delivery is at least once and unordered. Deduplicate on the webhook id, which remains stable across retries and endpoint deliveries.
Verify NR-Webhook-Signature over the raw body before parsing. Signatures and retry schedules follow the other webhook event types.
Stopping a stream or shortening retention prevents future eligible deliveries. Data already delivered follows your receiver’s retention policy. Replay retained audit events through the audit-stream replay route. The ordinary webhook replay route refuses them.
{
"id": "evt_01JA2Z8K6Q4V7W9XBCDEFGHJKM",
"type": "audit.event",
"created_at": "2026-10-29T00:00:00Z",
"data": {
"id": "aud_01JA2ZE5F6G7H8J9K0M1N2P3Q4",
"workspace_id": "tnt_01JA2Z8K6Q4V7W9XBCDEFGHJKM",
"environment": "live",
"action": "member.role_changed",
"outcome": "succeeded",
"actor": {
"type": "user",
"external_user_id": "user_2EXAMPLE",
"console_credential_id": "01JA2Z8K6Q4V7W9XBCDEFGHJKM",
"principal_id": "mem_01JA2Z8K6Q4V7W9XBCDEFGHJKM"
},
"target": {
"type": "member",
"id": "mem_01JA2ZB4C5D6E7F8G9H0JKMNPQ"
},
"detail": {
"role": "admin"
},
"created_at": "2026-10-23T09:10:00.000Z"
}
}Headers
Body
Body of every webhook delivery: {id, type, created_at, data}, signed as described in this reference (NR-Webhook-Signature over 'timestamp.payload'). Ten event types. assessment.updated fires when an assessment's score, band, recommendation, coverage or status changes while it is served; updates that change none of these are coalesced, and the final one has status complete. assessment.updated reports progress only and is not actionable: act on account.risk_changed. An expiry is terminal and carries only minimal data: status 'expired', change_reason 'expired', the last served assessment_version and no assessment (GET now answers 404); the consumer deletes what it holds for the assessment. account.deleted fires once when DELETE /v1/accounts/{account_id} erased at least one assessment of the account: its data names the account_id, how many assessments went and when; the consumer deletes what it holds from the account's assessments created at or before data.deleted_at, ignores a later-arriving update of such an assessment, and keeps any assessment created after it (the account assessed again), even when the event arrives last. A repeat erasure that deleted nothing sends no event. workspace.deleted is the last event an environment's endpoints receive: it fires once per environment when its workspace is deleted (DELETE /v1/workspaces/{workspace_id}), after the deletion took effect (every key answers 401, every assessment and account is gone) and before the endpoints themselves are removed; the consumer deletes what it holds for that environment and stops calling the API with its keys. webhook_endpoint.disabled fires when one of the environment's endpoints was disabled after failing continuously for 72 hours: it goes to the environment's other verified endpoints (the disabled endpoint receives nothing until it is verified again), and is not sent when there are none. account.risk_changed is the one actionable event. It fires once when the decision of an account for at least one flow changes, and for the account's first decision that is not allow; a first decision of allow sends nothing, and so does a score that moves without changing any flow's decision. Its data is the account as GET /v1/accounts/{account_id} answers it for the change (the new score, decisions and reasons, at the risk_version that change made) and the decisions per flow it replaced (allow for every flow before the account's first decision). A held flow (settings admission held) announces held when its assessment is answered, then exactly one change away from held: the decision of the completed investigation, or the flow's on-expiry decision when the hold's deadline passed first, so an expired hold is always announced. The event only wakes the receiver: decide from the account at its newest risk_version, or from GET /v1/accounts/{account_id}. screening.completed, person.flagged and person.decided are screening's: screening.completed fires once when a screening of a group finishes completed, partial or failed, with its counts by band, how many had no footprint and how many it did not fully cover; person.flagged fires for each person a screening flags, with its highest band and not what was posted; person.decided fires for each decision a reviewer records (cleared, watch or escalated). They name groups, people and screenings by id only: read the person or its report for anything more. endpoint.verification carries a challenge the endpoint must echo to prove it is the intended receiver. Deliveries are at-least-once and unordered: deduplicate on id, drop an assessment whose detail.assessment_version is not newer than the one held, and drop an account whose risk_version is not newer than the one held. Polling GET /v1/assessments/{assessment_id} stays authoritative. An event sent by POST /v1/webhooks/{endpoint_id}/test carries test: true and a fixed example assessment. audit.event carries the immutable public audit event only to an explicit audit-stream subscription. Its id is stable across retries and endpoint fan-out. An endpoint must be verified; environment and action filters apply before queueing and are rechecked before each delivery. Workspace-scoped events require an unrestricted member to configure. Streams start at subscription time; audit exports provide available historical events. Delivered data is controlled by the receiver and is not remotely erased by changing NoResponse retention.
Every webhook event type: the body's type, and the event_type of a delivery attempt and a replay.
assessment.updated, endpoint.verification, account.deleted, workspace.deleted, webhook_endpoint.disabled, account.risk_changed, audit.event, screening.completed, person.flagged, person.decided Shape set by type: the assessment resource (the assessment schema) or $defs/assessment_expired for assessment.updated, $defs/endpoint_verification for endpoint.verification, $defs/account_deleted for account.deleted, $defs/workspace_deleted for workspace.deleted, $defs/webhook_endpoint_disabled for webhook_endpoint.disabled, $defs/account_risk_changed for account.risk_changed, $defs/screening_completed for screening.completed, $defs/person_flagged for person.flagged, $defs/person_decided for person.decided. audit.event uses the audit event schema.
Response
Accepted. Any 2xx within 5 seconds acknowledges the delivery; the body is ignored. A receiver that has already processed this id still answers 2xx.