Skip to content

Entities

Understanding external and canonical entities in Kanoniv.

External Entities

External entities are raw records from source systems. They represent the data exactly as it exists in each source.

Characteristics

  • Immutable — Never modified after import
  • Source-scoped — Uniquely identified by (source, external_id)
  • Raw + Normalized — Stores both original and normalized data

Example

json
{
  "id": "crm:contact_123",
  "source": "crm",
  "external_id": "contact_123",
  "entity_type": "customer",
  "raw_data": {
    "email": "[email protected]",
    "name": "  John   Doe  "
  },
  "normalized_data": {
    "email": "[email protected]",
    "name": "john doe"
  }
}

The normalization stage standardizes emails, names, and phone numbers so that matching rules work across inconsistent formatting.


Canonical Entities

Canonical entities are the "golden records" — the single source of truth created by merging external entities using your spec's survivorship rules.

Characteristics

  • Mutable — Updated when new sources are linked or survivorship changes
  • Merged — Contains data from multiple sources
  • Provenance-tracked — Knows which source contributed each field

Example

json
{
  "canonical_id": "550e8400-e29b-41d4-a716-446655440000",
  "entity_type": "customer",
  "canonical_data": {
    "email": "[email protected]",
    "name": "John Doe",
    "company": "Acme Corporation",
    "plan": "enterprise"
  },
  "field_provenance": {
    "email": "crm",
    "name": "crm",
    "company": "crm",
    "plan": "billing"
  },
  "confidence_score": 0.94
}

Every field has provenance — you always know which source system each value came from and which survivorship strategy selected it.


The mapping that connects external entities to canonical entities. Many external records can link to one canonical.

External EntityCanonical Entity
crm:contact_123->550e8400-...
billing:cus_456->550e8400-...
marketing:lead_789->550e8400-...
  • auto — Created by the matching engine based on spec rules
  • manual — Created by a human override (force merge)

Need real-time identity lookups?

Kanoniv Cloud provides a resolution API to query the identity graph by external ID and discover all linked records in under 1ms.


Entity Type Detection

Kanoniv's field profiler can automatically classify what kind of entity your data represents. Rather than requiring you to declare the entity type up front, the profiler examines the actual data values, detects which identity signals are present, and infers the entity type.

Supported Entity Types

Entity TypeKey SignalsBlocking Key Templates
personemail, phone, first_name, last_name, full_name, company_name[email], [phone], [last_name, first_name]
companydomain, tax_id, industry, company_name, email, phone[domain], [tax_id], [company_name]
productsku, upc, product_name, brand, category[sku], [upc], [brand, category]
transactiontransaction_id, amount, currency[transaction_id], [amount, currency]
healthcaremrn, npi, patient_name, date_of_birth, email, phone[mrn], [npi], [date_of_birth, last_name]

Each entity type has its own signal catalog that defines which fields to look for, what matching algorithms and weights to apply, and which blocking key combinations to generate.

How Inference Works

The profiler uses value-based detection, not column name matching. It inspects actual cell values to classify columns (e.g. looking for @ in email fields, digit patterns in phone fields, corporate suffixes like "Ltd", "Inc", "Corp" in company name fields). Once signals are detected, the profiler scores each entity type:

  1. Detect signals. The profiler samples rows and classifies each column by inspecting its values. A column is tagged as email, phone, sku, mrn, etc. based on value patterns.

  2. Score entity types. Each entity type expects certain signal combinations. For example, person scores high when both an identifier signal (email or phone) and a name signal (first_name, last_name, or full_name) are present. product scores high when SKU or UPC plus a product name or brand are detected.

  3. Pick the winner. The entity type with the highest score is selected. If no signals are detected at all, the profiler defaults to person.

Using the Entity Type Hint

You can override the inferred entity type by passing an explicit hint. This is useful when:

  • Your data contains signals that match multiple entity types
  • You know the entity type but the data is ambiguous
  • You want to use a specific signal catalog's blocking keys and field defaults

Cloud API: Pass entity_type in the POST /v1/autodetect request body.

CLI: The kanoniv autodetect command displays the inferred entity type in its output.

Python SDK: The discover_entity_sources() function infers entity types per source during profiling.

python
from kanoniv import discover_entity_sources, bootstrap_spec, Source

sources = [Source.from_csv("products", "catalog.csv")]
discovery = discover_entity_sources(sources)

# Check what the profiler inferred
for profile in discovery.profiles:
    print(f"{profile.source_name}: entity type detected from signals")

# Bootstrap uses the inferred entity type's signal catalog
spec = bootstrap_spec(discovery)

Relationship to Specs

The entity type detected by the profiler is a profiling concept - it determines which signal catalog and blocking key templates to use when bootstrapping a spec. Once a spec is generated (either manually or via bootstrap), the spec's entity.name field is what the engine uses during reconciliation. The engine itself does not distinguish between entity types at runtime; it executes whatever rules and fields are defined in the spec.

The identity and delegation layer for AI agents.