Entity Lifecycle Events
The Kanoniv Cloud API emits events for every identity state transition. Events provide a server-side audit stream that complements the agent-side provenance system.
Event Types
| Event | Trigger |
|---|---|
entity.created | A new canonical entity is created (first resolve or ingest for a new identity) |
entity.updated | An entity's canonical data changes (new source record matched, attributes mutated) |
entity.merged | Two or more entities are merged into one (duplicate resolution) |
entity.split | An entity is split into separate entities (incorrect merge reversal) |
Querying Events
GET /v1/eventsReturns a paginated list of events, newest first.
Query Parameters
| Parameter | Type | Description |
|---|---|---|
since | string (RFC 3339) | Only return events after this timestamp |
entity_id | string (UUID) | Filter to events affecting a specific entity |
event_type | string | Filter by event type (e.g. entity.merged) |
limit | integer | Maximum events to return (default: 50, max: 1000) |
Example Request
curl -H "Authorization: Bearer $TOKEN" \
"https://api.kanoniv.com/v1/events?since=2026-03-15T00:00:00.000Z&event_type=entity.merged&limit=10"Example Response
{
"events": [
{
"id": "evt_01HXYZ...",
"event_type": "entity.merged",
"entity_id": "550e8400-e29b-41d4-a716-446655440000",
"tenant_id": "t_abc123",
"payload": {
"surviving_entity_id": "550e8400-e29b-41d4-a716-446655440000",
"absorbed_entity_ids": ["660f9500-f39c-52e5-b827-557766551111"],
"source_count": 3,
"confidence": 0.97
},
"created_at": "2026-03-15T12:34:56.789Z"
}
],
"has_more": false
}Incremental Polling
Use the since parameter to implement incremental polling. Store the timestamp of the last processed event and pass it on the next request.
from kanoniv import Client
import time
client = Client(api_key="kn_...")
last_seen = "2026-03-15T00:00:00.000Z"
while True:
events = client.audit.list(since=last_seen, limit=100)
for event in events:
process_event(event)
last_seen = event["created_at"]
time.sleep(5)TIP
Use RFC 3339 timestamps with milliseconds and a Z suffix (e.g. 2026-03-15T12:00:00.000Z). The API decodes + as a space in URL parameters, so +00:00 offsets will break.
Event Payloads
entity.created
{
"entity_id": "550e8400-...",
"source_name": "crm",
"external_id": "sf_123",
"is_new": true
}entity.updated
{
"entity_id": "550e8400-...",
"changed_fields": ["email", "phone"],
"source_name": "billing"
}entity.merged
{
"surviving_entity_id": "550e8400-...",
"absorbed_entity_ids": ["660f9500-..."],
"source_count": 3,
"confidence": 0.97
}entity.split
{
"original_entity_id": "550e8400-...",
"new_entity_ids": ["770a0600-...", "880b1700-..."],
"reason": "incorrect merge reversal"
}Events vs. Provenance
Events and provenance entries serve different purposes and work together to provide a complete audit picture.
Events are generated by the Kanoniv Cloud server. They are authoritative records of what happened in the identity graph. Use events when you need to:
- React to entity changes in real time (trigger downstream syncs)
- Monitor the health of your identity graph (merge rate, split rate)
- Build incremental export pipelines (sync to a data warehouse)
Provenance entries are generated by agents using the kanoniv-agent-auth library. They are cryptographic proofs of who decided what. Use provenance when you need to:
- Prove which agent authorized a merge and why
- Build a verifiable chain of custody for identity decisions
- Enable third-party auditing without trusting the server
In a typical deployment, an agent creates a provenance entry before calling the Cloud API, and the Cloud API emits an event after the operation completes. The provenance entry records the agent's intent and authorization; the event records the system's execution.
Agent creates ProvenanceEntry (signed proof of intent)
-> Agent calls POST /v1/resolve/realtime
-> Server executes the operation
-> Server emits entity.created eventWebhook Delivery
Events can be delivered via webhooks to external systems. Kanoniv queues webhook deliveries internally and retries failed deliveries with exponential backoff. Webhook configuration is managed through the API or dashboard.
Webhook payloads include the full event object wrapped in a delivery envelope:
{
"delivery_id": "dlv_01HXYZ...",
"event": {
"id": "evt_01HXYZ...",
"event_type": "entity.merged",
"entity_id": "550e8400-...",
"payload": { ... },
"created_at": "2026-03-15T12:34:56.789Z"
}
}