Identity resolution for mem0. Same person, different IDs = unified memory.
mem0 stores memories keyed by user_id. If two agents use different identifiers for the same person, mem0 treats them as separate users:
from mem0 import Memory
m = Memory()
m.add("Prefers annual billing", user_id="bill@acme.com")
m.add("Needs 50 seat quote", user_id="william.smith@acme.com")
m.search("billing", user_id="bill@acme.com")
# Only finds 1 memory. The other is invisible.Bill and William Smith are the same person. But mem0 doesn't know that.
from kanoniv_mem0 import KanonivMemory
m = KanonivMemory(kanoniv_api_key="kn_live_...")
m.add("Prefers annual billing", user_id="bill@acme.com")
m.add("Needs 50 seat quote", user_id="william.smith@acme.com")
m.search("billing", user_id="bill@acme.com")
# Finds BOTH memories. Same canonical entity.KanonivMemory resolves every user_id to a canonical entity via Kanoniv's identity graph before mem0 stores or retrieves anything. Different IDs that belong to the same person get the same entity_id. Memories unify automatically.
pip install kanoniv-mem0from kanoniv_mem0 import KanonivMemory
# Drop-in replacement for mem0's Memory
m = KanonivMemory(kanoniv_api_key="kn_live_...")
# Agent A - support agent
m.add(
"I'm Bill, VP of Engineering at Acme. Switch us to annual billing.",
user_id="bill@acme.com",
)
# Agent B - sales agent (different email, same person)
m.add(
"This is William Smith. Quote me for 50 Enterprise seats.",
user_id="william.smith@acme.com",
)
# Agent C - searches by either ID, gets everything
results = m.search("billing", user_id="bill@acme.com")
# Returns memories from BOTH agents
results = m.get_all(user_id="william.smith@acme.com")
# Returns ALL memories for this person, regardless of which ID was usedYour code KanonivMemory mem0
| | |
| add(user_id="bill@..") | |
|------------------------>| |
| | resolve("bill@..") |
| |-----> Kanoniv API |
| |<----- entity_id: ENT_7f|
| | |
| | add(user_id="ENT_7f") |
| |----------------------->|
| | | store
- You call
add()orsearch()with anyuser_id(email, phone, name, internal ID) KanonivMemorycalls Kanoniv's resolve endpoint to get the canonicalentity_id- The canonical ID is passed to mem0 as the
user_id - Different identifiers for the same person resolve to the same entity
- mem0 stores and retrieves using the unified ID
The resolve call adds ~5ms (sub-ms if cached in Kanoniv's Redis layer). Results are also cached locally per session.
KanonivMemory is a drop-in replacement for mem0.Memory. All the same methods work:
| Method | Identity Resolved? | Description |
|---|---|---|
add() |
Yes | Add memories from messages |
search() |
Yes | Search memories by query |
get_all() |
Yes | Get all memories for a user |
delete_all() |
Yes | Delete all memories for a user |
get() |
No | Get a specific memory by ID |
update() |
No | Update a specific memory |
delete() |
No | Delete a specific memory |
history() |
No | Get memory change history |
reset() |
No | Reset all memories |
# Check how a user_id resolves
m.get_entity_id("bill@acme.com")
# -> "ENT_7f82..."
# Same person, same entity
m.get_entity_id("william.smith@acme.com")
# -> "ENT_7f82..."
# Clear the local resolve cache
m.clear_cache()m = KanonivMemory(
# mem0 config (optional - pass any mem0 MemoryConfig or dict)
config={"vector_store": {"provider": "qdrant", ...}},
# Kanoniv config
kanoniv_api_key="kn_live_...", # Get free key at app.kanoniv.com
kanoniv_base_url="https://api.kanoniv.com", # Default
source_name="mem0", # Source name in identity graph
cache_resolves=True, # Cache resolve results (default: True)
)m = KanonivMemory(
kanoniv_api_key="kn_test_...", # Sandbox keys start with kn_test_
)Sandbox gives you 1,000 entities for free, instant reset, full API access.
If Kanoniv's API is unreachable, KanonivMemory falls back to using the raw user_id - exactly like vanilla mem0. Memory still works, you just lose cross-ID unification until the connection is restored. No data loss, no errors.
Kanoniv is deterministic identity infrastructure for AI systems. It resolves records to canonical entities using configurable matching rules (email, phone, name, company), probabilistic scoring, and constraint-based merging.
- Deterministic: Same input always produces the same entity_id
- Real-time: Resolve calls return in <10ms
- Explainable: Every resolution includes confidence scores and match reasons
- Multi-signal: Matches on email, phone, name, company, and custom fields
Get a free API key at app.kanoniv.com.
Apache 2.0