Core Concepts
Kanoniv is a shared identity runtime. Multiple systems and AI agents write to it concurrently. The engine guarantees one canonical entity per real-world person or organization.
The problem
AI agents operate concurrently. When a lead fills out a form, four agents wake up at the same time:
- SDR Agent creates a CRM contact in HubSpot
- Billing Agent creates a Stripe customer
- Onboarding Agent opens a Zendesk ticket
- Enrichment Agent pulls data from Clearbit
Without coordination, you get 4 records in 4 systems for 1 person. Worse - the billing agent might create a second Stripe customer when it processes the same lead from a different source. The enrichment agent links to the wrong CRM contact.
No system flags anything as wrong. Every agent succeeded.
The resolve primitive
Every agent calls one endpoint before writing to any system:
POST /v1/resolve/realtimeThe engine ingests the record, matches it against the identity graph, and returns a canonical entity ID - all in one call.
{
"entity_id": "550e8400-e29b-41d4-a716-446655440000",
"is_new": false,
"confidence": 0.95,
"version": 3
}- First call for a new person:
is_new: true, entity created - Every subsequent call (from any source):
is_new: false, matched to existing entity - All agents get the same
entity_id- use it to write to their respective systems
Key entities
External entities
Records from source systems. Immutable - Kanoniv never modifies the original data.
{
"source": "hubspot",
"external_id": "hs-0042",
"data": { "email": "[email protected]", "name": "John Smith" }
}Canonical entities
The golden record. One per real-world entity, built by merging fields from all linked sources.
{
"entity_id": "550e8400-...",
"canonical_data": {
"email": "[email protected]",
"name": "John Smith",
"company": "Acme Labs",
"title": "CEO"
},
"field_provenance": {
"email": "hubspot",
"name": "hubspot",
"company": "clearbit",
"title": "clearbit"
},
"version": 3,
"state": "active"
}Every field has provenance - you always know which source each value came from.
Identity links
Many-to-one mappings from external records to canonical entities.
hubspot:hs-0042 -+
stripe:cus_8847 +-> Canonical: 550e8400-...
zendesk:tkt-1192 +
clearbit:enr-7721 -+Versioned mutations
Every write to a canonical entity increments its version. Concurrent writers use optimistic locking:
PATCH /v1/entities/550e8400-.../mutate
{
"patch": { "title": "CEO" },
"expected_version": 2
}- If the entity is at version 2: mutation succeeds, version becomes 3
- If another agent already updated it:
409 Conflictwith the current version - The losing agent retries with the new version - both updates applied, zero data loss
This is the same pattern databases use internally. No distributed locks, no leader election, no eventual consistency. Deterministic serialization.
The event layer
Identity state transitions are first-class events:
| Event | Trigger |
|---|---|
entity.created | First resolve call for a new entity |
entity.updated | Mutation applied to canonical data |
entity.merged | Two entities discovered to be the same person |
Downstream systems subscribe to these events to keep their data in sync. When an entity merges, every system that holds a reference to the old entity gets notified.
The matching engine
Under the hood, the engine runs a deterministic pipeline:
- Normalize - Standardize emails, phones, names (70+ nickname mappings)
- Block - Group likely matches using blocking keys and LSH
- Match - Score candidate pairs using rules or Fellegi-Sunter probabilistic matching
- Decide - Merge / Review / Reject based on confidence thresholds
- Merge - Create or update canonical entities
- Survive - Apply field priority to determine winning values
The engine supports both rules-based matching (exact email, fuzzy name) and probabilistic matching (trained weights, active learning). Same engine runs locally via the Python SDK and on the Cloud API.
Learn more
- Entities - External vs canonical entities in detail
- Identity Graph - Graph structure and linkage semantics
- Matching Rules - Rule types, scoring, and thresholds
- Survivorship - How field values are selected for golden records
- Overrides - Manual corrections and review queue
- API Reference - Full endpoint documentation
