CLI
The kanoniv command-line tool ships with the Python SDK. It provides 100+ commands across 11 domains plus workflow, LLM, and auth commands. Offline commands (spec validate/compile/hash/diff/plan) run locally via the embedded Rust engine. Cloud commands call the Kanoniv API.
Installation
pip install kanoniv[cloud]The [cloud] extra installs httpx and pydantic for API access. Offline commands work without it.
Upgrade to the latest version:
pip install --upgrade kanoniv[cloud]For data ingestion and export, you also need DuckDB and PyArrow:
pip install duckdb pyarrowGlobal Flags
These flags apply to all commands:
| Flag | Env Variable | Default | Description |
|---|---|---|---|
--api-key <KEY> | KANONIV_API_KEY | - | API key for cloud commands |
--api-url <URL> | KANONIV_API_URL | https://api.kanoniv.com | API base URL |
--format <FMT> | - | table | Output format: json or table |
--version | - | - | Show CLI version |
Authentication
Cloud commands require an API key. Set it via environment variable, flag, or login:
# Option 1: Environment variable (recommended for CI)
export KANONIV_API_KEY=your-api-key
# Option 2: Inline flag
kanoniv ask "How many entities?" --api-key your-api-key
# Option 3: Login (stores credentials locally)
kanoniv loginThe CLI resolves credentials in order: --api-key flag, KANONIV_API_KEY env var, stored credentials from kanoniv login.
login / logout / context
# Store credentials locally
kanoniv login
# Clear stored credentials
kanoniv logout
# Show current API URL, key, and credentials file
kanoniv contextDomain Commands
The CLI is organized into 11 domains. Each domain groups related commands under a namespace: kanoniv <domain> <action>.
entity - Resolved identity entities (18 commands)
Entities are resolved identities - all records that represent the same real-world thing, clustered into a single canonical node. Graph mutation commands (merge, split, reassign, delete, link, unlink) operate directly on the persistent identity graph with immediate effect.
entity show
Show entity details: canonical attributes, confidence, member count.
kanoniv entity show <entity-id>
kanoniv entity show <entity-id> --records
kanoniv entity show <entity-id> --attrs
kanoniv entity show <entity-id> --sources
kanoniv entity show <entity-id> --json
kanoniv entity show <entity-id> --relationships
kanoniv entity show <entity-id> --relationships --field phone
kanoniv entity show <entity-id> --relationships --jsonUUID auto-detection: if the first argument to kanoniv entity is a UUID, it routes directly to entity show. No subcommand needed:
# These are equivalent
kanoniv entity 8bcb340d-60f2-45a6-9e7d-134bc39eb675
kanoniv entity show 8bcb340d-60f2-45a6-9e7d-134bc39eb675| Argument | Description |
|---|---|
entity_id | Entity UUID |
| Flag | Default | Description |
|---|---|---|
--records | false | Include linked source records with confidence scores |
--attrs | false | Show only canonical attributes (gold record) |
--sources | false | Show field provenance (which source won each field) |
--relationships | false | Show shared identity signals between linked records |
--field <FIELD> | - | Filter relationships to a specific field (e.g. phone, email). Used with --relationships |
--json | false | Raw JSON output |
Relationships show which identity signals (email, phone, name, etc.) are shared across the source records that were linked into this entity. This is useful for understanding why records were merged.
# Show all shared signals
kanoniv entity show 8bcb340d-... --relationships
# Filter to just phone signals
kanoniv entity show 8bcb340d-... --relationships --field phone
# Get raw JSON for programmatic use
kanoniv entity show 8bcb340d-... --relationships --jsonentity search
Search entities by attributes. Supports attribute filters, record count filters, field presence filters, and free-text search.
kanoniv entity search -q "John Smith"
kanoniv entity search --email [email protected] --source crm
kanoniv entity search --entity-type person --limit 50
# Find duplicates (entities with 2+ linked records)
kanoniv entity search --min-records 2
# Find singletons
kanoniv entity search --max-records 1
# High-confidence entities only
kanoniv entity search --min-confidence 0.9
# Entities with email
kanoniv entity search --has email
# Entities missing phone (data quality)
kanoniv entity search --missing phone
# Combined power query
kanoniv entities --entity-type person --search john --min-records 2 --has email --limit 5| Flag | Default | Description |
|---|---|---|
-q, --query <TEXT> | - | Free-text search |
--search <TEXT> | - | Alias for -q / --query |
--name <NAME> | - | Filter by name |
--email <EMAIL> | - | Filter by email |
--phone <PHONE> | - | Filter by phone |
--source <SOURCE> | - | Filter by source name |
--entity-type <TYPE> | - | Filter by entity type (person, company, product) |
--min-records <N> | - | Minimum linked source records (e.g. 2 = find duplicates) |
--max-records <N> | - | Maximum linked source records (e.g. 1 = find singletons) |
--min-confidence <F> | - | Minimum confidence score (0.0-1.0) |
--has <FIELDS> | - | Only entities with non-empty values for these comma-separated fields |
--missing <FIELDS> | - | Only entities missing these comma-separated fields |
--limit <N> | 20 | Max results |
--offset <N> | 0 | Offset for pagination |
entity list
List entities. A convenience alias for entity search with no required filters. Supports all the same filtering flags.
kanoniv entity list
kanoniv entity list --entity-type person --limit 50
kanoniv entity list --max-records 1
kanoniv entity list --min-records 2 --has email| Flag | Default | Description |
|---|---|---|
--entity-type <TYPE> | - | Filter by entity type |
--min-records <N> | - | Minimum linked source records |
--max-records <N> | - | Maximum linked source records |
--min-confidence <F> | - | Minimum confidence score (0.0-1.0) |
--has <FIELDS> | - | Only entities with non-empty values for these comma-separated fields |
--missing <FIELDS> | - | Only entities missing these comma-separated fields |
--limit <N> | 20 | Max results |
--offset <N> | 0 | Offset for pagination |
entity linked
Show all source records linked to an entity.
kanoniv entity linked <entity-id>| Argument | Description |
|---|---|
entity_id | Entity UUID |
entity history
Show merge history and lifecycle events for an entity.
kanoniv entity history <entity-id>| Argument | Description |
|---|---|
entity_id | Entity UUID |
entity neighbors
Show graph neighbors of an entity.
kanoniv entity neighbors <entity-id>
kanoniv entity neighbors <entity-id> --depth 2| Argument / Flag | Default | Description |
|---|---|---|
entity_id | - | Entity UUID |
--depth <N> | 1 | Traversal depth |
entity merge
Immediately merge two entities in the identity graph.
kanoniv entity merge <entity-a> <entity-b>
kanoniv entity merge <entity-a> <entity-b> --reason "Confirmed same person"| Argument / Flag | Description |
|---|---|
entity_a | First entity UUID |
entity_b | Second entity UUID |
--reason <TEXT> | Reason for merge |
entity split
Split source records out of a canonical entity into new entities.
kanoniv entity split <canonical-id> <member-id-1> [<member-id-2> ...]
kanoniv entity split <canonical-id> <member-id-1> --reason "Different people"| Argument / Flag | Description |
|---|---|
canonical_id | Canonical entity UUID to split from |
member_ids | One or more external entity UUIDs to eject |
--reason <TEXT> | Reason for split |
entity reassign
Move a source record from its current entity to a different one.
kanoniv entity reassign <external-entity-id> <target-entity-id>
kanoniv entity reassign <external-entity-id> <target-entity-id> --reason "Wrong cluster"| Argument / Flag | Description |
|---|---|
ext_id | External entity UUID to move |
to_entity | Target canonical entity UUID |
--reason <TEXT> | Reason for reassignment |
entity delete
Delete an empty canonical entity (no members).
kanoniv entity delete <entity-id>| Argument | Description |
|---|---|
entity_id | Entity UUID |
entity link
Create a soft relationship edge between two entities.
kanoniv entity link <entity-a> <entity-b>
kanoniv entity link <entity-a> <entity-b> --weight 0.8| Argument / Flag | Default | Description |
|---|---|---|
entity_a | - | First entity UUID |
entity_b | - | Second entity UUID |
--weight <F> | 1.0 | Edge weight |
entity unlink
Remove a soft relationship edge between two entities.
kanoniv entity unlink <entity-a> <entity-b>| Argument | Description |
|---|---|
entity_a | First entity UUID |
entity_b | Second entity UUID |
entity explain
Explain why an entity exists in its current state - merge history, lifecycle events, and match evidence.
kanoniv entity explain <entity-id>| Argument | Description |
|---|---|
entity_id | Entity UUID |
entity lock
Lock an entity from further merges.
kanoniv entity lock <entity-id>| Argument | Description |
|---|---|
entity_id | Entity UUID |
entity revert
Revert an entity to a previous state.
kanoniv entity revert <entity-id> <event-id>| Argument | Description |
|---|---|
entity_id | Entity UUID |
event_id | Event ID to revert to |
entity attrs
Show canonical attributes (gold record fields) for an entity.
kanoniv entity attrs <entity-id>| Argument | Description |
|---|---|
entity_id | Entity UUID |
entity candidates
Show merge candidates - nearby entities that might match.
kanoniv entity candidates <entity-id>
kanoniv entity candidates <entity-id> --limit 20| Argument / Flag | Default | Description |
|---|---|---|
entity_id | - | Entity UUID |
--limit <N> | 10 | Max results |
entity diff
Diff two entities' canonical attributes side by side.
kanoniv entity diff <entity-a> <entity-b>| Argument | Description |
|---|---|
entity_a | First entity UUID |
entity_b | Second entity UUID |
source - Data sources (9 commands)
Sources are datasets - tables, files, or systems that feed records into the identity resolution pipeline.
source list
List all sources.
kanoniv source listsource show
Show source details.
kanoniv source show <source-id>| Argument | Description |
|---|---|
source_id | Source UUID |
source schema
Show source schema - columns, types, roles, and sample data.
kanoniv source schema <source-id>| Argument | Description |
|---|---|
source_id | Source UUID |
source create
Create a new source.
kanoniv source create my_crm
kanoniv source create salesforce --type api --config '{"instance": "na1"}'| Argument / Flag | Default | Description |
|---|---|---|
name | - | Source name |
--type <TYPE> | csv | Source type |
--config <JSON> | - | Source config as JSON |
source delete
Delete a source and all its records.
kanoniv source delete <source-id>| Argument | Description |
|---|---|
source_id | Source UUID |
source sync
Trigger a source sync (re-fetch data from connector).
kanoniv source sync <source-id>| Argument | Description |
|---|---|
source_id | Source UUID |
source stats
Show source statistics: record counts, field coverage, cardinality.
kanoniv source stats <source-id>| Argument | Description |
|---|---|
source_id | Source UUID |
source quality
Show data quality report for a source - quality score, grade, and issues.
kanoniv source quality <source-id>| Argument | Description |
|---|---|
source_id | Source UUID |
source entities
List entities resolved from a specific source.
kanoniv source entities <source-id>
kanoniv source entities <source-id> --limit 50| Argument / Flag | Default | Description |
|---|---|---|
source_id | - | Source UUID |
--limit <N> | 20 | Max results |
match - Matching and similarity (7 commands)
The matching layer handles similarity scoring and resolution decisions - the core science of identity resolution.
match explain
Explain match between two records with field-level similarity breakdown.
kanoniv match explain crm:12345 billing:67890Records are specified in source:external_id format.
| Argument | Description |
|---|---|
record_a | First record (source:external_id) |
record_b | Second record (source:external_id) |
match rules
Show active matching rules.
kanoniv match rulesmatch pending
List pending match decisions awaiting human review.
kanoniv match pending
kanoniv match pending --limit 50| Flag | Default | Description |
|---|---|---|
--limit <N> | 20 | Max results |
match decide
Accept or reject a pending match decision.
kanoniv match decide <entity-a> <entity-b> --accept
kanoniv match decide <entity-a> <entity-b> --reject --reason "Different people"| Argument / Flag | Description |
|---|---|
entity_a | First entity UUID |
entity_b | Second entity UUID |
--accept | Accept the match |
--reject | Reject the match |
--reason <TEXT> | Reason for decision |
You must specify exactly one of --accept or --reject.
match candidates
Show match candidates for an entity - records that could potentially match.
kanoniv match candidates <entity-id>
kanoniv match candidates <entity-id> --limit 50| Argument / Flag | Default | Description |
|---|---|---|
entity_id | - | Entity UUID |
--limit <N> | 20 | Max results |
match cluster
Show the match cluster an entity belongs to - its cluster ID, size, coherence score, and members.
kanoniv match cluster <entity-id>| Argument | Description |
|---|---|
entity_id | Entity UUID |
match test
Test match two records (dry-run) - score without persisting any changes.
kanoniv match test crm:12345 billing:67890Records are specified in source:external_id format.
| Argument | Description |
|---|---|
record_a | First record (source:external_id) |
record_b | Second record (source:external_id) |
graph - Identity graph analytics (10 commands)
The persistent identity graph holds entities, relationships, and merge edges. Graph analytics reveal influence, risk, and structural patterns.
graph stats
Show graph statistics: entity counts, edges, merges, cluster sizes.
kanoniv graph statsgraph cluster
Show all members of an entity's cluster.
kanoniv graph cluster <entity-id>| Argument | Description |
|---|---|
entity_id | Entity UUID |
graph clusters
List all clusters in the identity graph. Optionally filter by minimum cluster size.
kanoniv graph clusters
kanoniv graph clusters --limit 50
kanoniv graph clusters --min-size 3
kanoniv graph clusters --min-size 3 --limit 10| Flag | Default | Description |
|---|---|---|
--limit <N> | 20 | Max results |
--min-size <N> | - | Minimum cluster size (e.g. 3 = only clusters with 3+ members) |
graph bridges
Show bridge signals that link different entity types.
kanoniv graph bridgesgraph refresh
Refresh graph analytics - recompute influence scores, risk scores, and cluster metrics.
kanoniv graph refreshgraph influence
Show the influence score for an entity - how connected and central it is in the graph.
kanoniv graph influence <entity-id>| Argument | Description |
|---|---|
entity_id | Entity UUID |
graph risk
Show the risk score for an entity - potential identity fraud or data quality issues.
kanoniv graph risk <entity-id>| Argument | Description |
|---|---|
entity_id | Entity UUID |
graph orphans
List orphan entities - entities with no connections to other entities.
kanoniv graph orphans
kanoniv graph orphans --entity-type person --limit 50| Flag | Default | Description |
|---|---|---|
--limit <N> | 20 | Max results |
--entity-type <TYPE> | - | Filter by entity type |
graph conflicts
List conflicting or incoherent clusters in the graph.
kanoniv graph conflicts
kanoniv graph conflicts --limit 50| Flag | Default | Description |
|---|---|---|
--limit <N> | 20 | Max results |
graph density
Show graph density and connectivity metrics - edge density, degree distribution, clustering coefficient, path lengths.
kanoniv graph densityrow - Source records (5 commands)
Rows are individual source records - the raw data fed into the identity resolution pipeline before clustering into entities.
row show
Show a source record by source name and external ID.
kanoniv row show crm 12345| Argument | Description |
|---|---|
source | Source name |
external_id | External ID |
row resolve
Real-time resolve a record - ingest, match, and link in one call.
kanoniv row resolve crm 12345
kanoniv row resolve crm 99999 --data '{"email": "[email protected]", "name": "John"}'| Argument / Flag | Description |
|---|---|
source | Source name |
external_id | External ID |
--data <JSON> | Record data as JSON |
row lookup
Look up what entity a source record belongs to. Returns just the entity ID.
kanoniv row lookup crm 12345| Argument | Description |
|---|---|
source | Source name |
external_id | External ID |
row memberships
List source-to-entity memberships with optional filters.
kanoniv row memberships
kanoniv row memberships --source crm
kanoniv row memberships --entity-id <entity-id>
kanoniv row memberships --source crm --limit 100| Flag | Default | Description |
|---|---|---|
--source <NAME> | - | Filter by source name |
--entity-id <ID> | - | Filter by entity UUID |
--limit <N> | 50 | Max results |
row trace
Show match audit trail for a source record - every comparison, score, and decision.
kanoniv row trace crm 12345| Argument | Description |
|---|---|
source | Source name |
external_id | External ID |
spec - Identity spec management (9 commands)
Specs define the identity model - entity types, matching rules, blocking keys, thresholds, and survivorship policies. Five commands run offline using the local Rust engine. Four commands use the Cloud API.
spec validate (offline)
Check a spec for schema and semantic errors.
kanoniv spec validate my-spec.yamlValid.With errors:
Found 2 error(s):
Missing required field: identity_version
rules[0]: weight 1.5 must be between 0 and 1| Argument | Description |
|---|---|
path | Path to spec YAML file |
spec compile (offline)
Compile a spec to intermediate representation (IR).
kanoniv spec compile my-spec.yaml
kanoniv spec compile my-spec.yaml -o compiled.json| Argument / Flag | Description |
|---|---|
path | Path to spec YAML file |
-o, --output <PATH> | Write IR to file instead of stdout |
spec hash (offline)
Compute a deterministic SHA-256 hash of a spec's canonical form.
kanoniv spec hash my-spec.yaml
# sha256:a1b2c3d4e5f6...Useful for detecting changes in CI pipelines. If the hash changes, the resolution plan changed.
| Argument | Description |
|---|---|
path | Path to spec YAML file |
spec diff (offline)
Compare two spec versions.
kanoniv spec diff v1.yaml v2.yamlRules added:
+ fuzzy_phone
Rules removed:
- legacy_name
Rules modified:
~ exact_email: weight changed from 1.0 to 0.8
Thresholds changed:
thresholds.match: 0.85 -> 0.9| Argument | Description |
|---|---|
v1 | Path to first spec YAML |
v2 | Path to second spec YAML |
spec plan (offline)
Generate a detailed execution plan with static risk analysis.
kanoniv spec plan my-spec.yamlOutputs execution stages and risk flags. The plan includes 8 stages:
| Stage | Name | Description |
|---|---|---|
| 1 | Normalize sources | Read and normalize fields from all sources |
| 2 | Generate blocking keys | Apply blocking strategy to reduce comparison space |
| 3 | Exact matches | Evaluate exact match rules |
| 4 | Fuzzy matches | Evaluate fuzzy/phonetic/composite match rules |
| 5 | Score and decide | Aggregate weighted scores and apply thresholds |
| 6 | Cluster entities | Transitive closure via UnionFind to group matches |
| 7 | Apply survivorship | Build golden records from field-level rules |
| 8 | Emit outputs | Produce canonical table, lineage table, and audit trail |
Risk flags
Static analysis produces risk flags at four severity levels:
| Code | Severity | Trigger |
|---|---|---|
NO_BLOCKING | critical | No blocking keys defined (O(n^2) comparisons) |
SINGLE_SIGNAL | high | Only one match rule |
LOW_THRESHOLD | high | Fuzzy rule threshold below 0.8 |
PHONE_WITHOUT_BLOCKING | high | Phone match rule without phone-based blocking key |
HIGH_WEIGHT_FUZZY | medium | Fuzzy rule with weight above 0.9 |
NO_SURVIVORSHIP | medium | No survivorship rules defined |
NO_REVIEW_THRESHOLD | medium | No review threshold configured |
SINGLE_SOURCE | low | Only one data source |
MISSING_TEMPORAL | low | No temporal configuration |
| Argument | Description |
|---|---|
path | Path to spec YAML file |
Python equivalent
The same functionality is available in Python via kanoniv.plan(sources, spec). See Python SDK.
spec list (cloud)
List identity specs in the Cloud.
kanoniv spec listspec show (cloud)
Show spec details and YAML content.
kanoniv spec show person_v1| Argument | Description |
|---|---|
version | Spec version name |
spec upload (cloud)
Upload a YAML spec to the Cloud.
kanoniv spec upload my-spec.yaml
kanoniv spec upload my-spec.yaml --compile| Argument / Flag | Description |
|---|---|
path | Path to spec YAML file |
--compile | Compile spec after upload |
spec delete (cloud)
Delete a spec from the Cloud.
kanoniv spec delete person_v1| Argument | Description |
|---|---|
version | Spec version name |
job - Background jobs (4 commands)
Jobs are background tasks - reconciliation, autotune, exports, and recomputes.
job list
List recent jobs.
kanoniv job list
kanoniv job list --limit 5
kanoniv job list --type reconciliation| Flag | Default | Description |
|---|---|---|
--limit <N> | 20 | Max results |
--type <TYPE> | - | Filter by job type |
job show
Show job details, status, duration, and results.
kanoniv job show <job-id>| Argument | Description |
|---|---|
job_id | Job UUID |
job cancel
Cancel a running job.
kanoniv job cancel <job-id>| Argument | Description |
|---|---|
job_id | Job UUID |
job run
Run a new job. Optionally wait for completion with polling.
kanoniv job run reconciliation
kanoniv job run autotune --wait
kanoniv job run export --payload '{"format": "csv"}'| Argument / Flag | Description |
|---|---|
job_type | Job type (reconciliation, autotune, export) |
--wait | Wait for completion (polls every 2s, 30 min timeout) |
--payload <JSON> | Job payload as JSON |
export - Export data (4 commands)
Export resolved entities, memberships, graph data, and match audit results to local files.
export entities
Export resolved canonical entities to CSV or JSON.
kanoniv export entities -o entities.csv
kanoniv export entities -o person_entities.csv --entity-type person
kanoniv export entities -o full_export.csv --reveal-pii
kanoniv export entities -o entities.json --format json| Flag | Default | Description |
|---|---|---|
-o, --output <PATH> | (required) | Output file path |
--entity-type <TYPE> | - | Filter by entity type |
--reveal-pii | false | Include unmasked PII fields (admin only) |
--format <FMT> | csv | Output format: csv or json |
The CSV export flattens canonical_data fields into columns alongside entity_id, entity_type, confidence_score, member_count, and updated_at.
export memberships
Export source-to-entity memberships.
kanoniv export memberships -o memberships.csv
kanoniv export memberships -o memberships.json --format json| Flag | Default | Description |
|---|---|---|
-o, --output <PATH> | (required) | Output file path |
--format <FMT> | csv | Output format: csv or json |
Membership CSV columns: source_system, source_id, entity_id, confidence, link_type, created_at.
export graph
Export the identity graph (nodes and edges) to a file.
kanoniv export graph -o graph.json
kanoniv export graph -o graph.csv --format csv --entity-type person| Flag | Default | Description |
|---|---|---|
-o, --output <PATH> | (required) | Output file path |
--entity-type <TYPE> | - | Filter by entity type |
--format <FMT> | json | Output format: json or csv |
export matches
Export match audit results.
kanoniv export matches -o matches.csv
kanoniv export matches -o matches.json --format json --entity-type person| Flag | Default | Description |
|---|---|---|
-o, --output <PATH> | (required) | Output file path |
--entity-type <TYPE> | - | Filter by entity type |
--format <FMT> | csv | Output format: csv or json |
Match CSV columns: entity_a_id, entity_b_id, score, decision, match_type, created_at.
override - Manual merge/split overrides (3 commands)
Overrides are manual corrections - force-merge or force-split directives that take precedence over the engine's automatic matching decisions.
override list
List all overrides.
kanoniv override listoverride create
Create a manual merge or split override.
kanoniv override create <entity-a> <entity-b> --type merge
kanoniv override create <entity-a> <entity-b> --type split| Argument / Flag | Description |
|---|---|
entity_a | First entity UUID |
entity_b | Second entity UUID |
--type <TYPE> | Override type: merge or split (required) |
override delete
Delete an override.
kanoniv override delete <override-id>| Argument | Description |
|---|---|
override_id | Override UUID |
feedback - Active learning labels (3 commands)
Feedback labels drive active learning - manual match/no_match annotations that train the Fellegi-Sunter probabilistic model.
feedback list
List feedback labels.
kanoniv feedback list
kanoniv feedback list --limit 50| Flag | Default | Description |
|---|---|---|
--limit <N> | 20 | Max results |
feedback create
Create a feedback label.
kanoniv feedback create <entity-a> <entity-b> --source-a crm --source-b billing --label match
kanoniv feedback create <entity-a> <entity-b> --source-a crm --source-b billing --label no_match --reason "Different people"| Argument / Flag | Description |
|---|---|
entity_a | First entity/record ID |
entity_b | Second entity/record ID |
--source-a <NAME> | Source name for entity A (required) |
--source-b <NAME> | Source name for entity B (required) |
--label <LABEL> | Label: match or no_match (required) |
--reason <TEXT> | Reason for the label |
feedback delete
Delete a feedback label.
kanoniv feedback delete <feedback-id>| Argument | Description |
|---|---|
feedback_id | Feedback label UUID |
system - System operations (6 commands)
Operational visibility and maintenance for the Kanoniv platform.
system version
Show version info. Works offline.
kanoniv system versionsystem health
Check API health.
kanoniv system healthsystem stats
Show dashboard statistics for your tenant.
kanoniv system stats
kanoniv system stats --entity-type person| Flag | Default | Description |
|---|---|---|
--entity-type <TYPE> | - | Filter stats to a specific entity type |
Output:
Dashboard
Entities: 2653
Records: 3500
Pending reviews: 12
Merge rate: 24.2%
By Entity Type
TYPE RECORDS ENTITIES MERGE RATE
person 3500 2653 24.2%system purge
Delete all data for the current tenant. Removes sources, entities, identity plans, jobs, agent runs, and conversations.
Optionally scope the purge to a single entity type - this deletes only the external entities, canonical entities, identity links, match audit, and merge history for that type, leaving everything else intact.
# Full purge (everything)
kanoniv system purge
kanoniv system purge --confirm
# Entity-type scoped purge (only delete product data)
kanoniv system purge --entity-type product
kanoniv system purge --entity-type product --confirm| Flag | Description |
|---|---|
--confirm | Skip interactive confirmation prompt |
--entity-type <TYPE> | Only purge data for this entity type (e.g. product, person, company). Other entity types are not affected. |
system reindex
Rebuild search indexes. Optionally target a specific index.
kanoniv system reindex
kanoniv system reindex --target entities
kanoniv system reindex --target graph| Flag | Description |
|---|---|
--target <TARGET> | Specific target to reindex (e.g. entities, graph) |
system recompute
Recompute derived data - canonical records, graph metrics, and other aggregations.
kanoniv system recompute
kanoniv system recompute --target canonical
kanoniv system recompute --target metrics| Flag | Description |
|---|---|
--target <TARGET> | Specific target to recompute (e.g. canonical, metrics) |
Workflow Commands
Top-level convenience commands for common identity resolution workflows. These are not nested under a domain.
ingest
Ingest CSV or JSON files into Kanoniv Cloud. Files are read locally with DuckDB, converted to Parquet, and uploaded.
# Single file
kanoniv ingest crm_contacts.csv
# Multiple files
kanoniv ingest crm.csv billing.csv support.csv
# Directory (all CSV and JSON files)
kanoniv ingest ./data/
# Glob pattern
kanoniv ingest ./data/*.csv
# Filter by entity type (skips files without matching identity signals)
kanoniv ingest ./data/ --entity-type person
# Multiple entity types in one command
kanoniv ingest ./data/ --entity-type person product company
# Explicit ID column
kanoniv ingest crm.csv --id-column crm_idOutput (multi-entity-type):
Filtering for entity type: person
scan: crm_contacts -> email, phone, person_name
crm_contacts: 2100 records (2100 new, 0 updated)
skip: product_catalog (no person identity fields)
Subtotal (person): 2100 records across 1 sources
Filtering for entity type: product
skip: crm_contacts (no product identity fields)
scan: product_catalog -> sku, product_name, price
product_catalog: 800 records (800 new, 0 updated)
Total: 2900 records (2 source-type pairs skipped)| Argument / Flag | Description |
|---|---|
files | CSV/JSON files, globs, or directories (one or more) |
--entity-type <TYPE> [TYPE ...] | Entity type(s) to filter for (e.g. person product company). Each file is scanned per type. |
--id-column <COL> | Column to use as external_id (auto-detected from *_id or id columns if not set) |
The --entity-type filter inspects actual data values (not column names) to detect identity signals.
Dependencies
Ingest requires duckdb and pyarrow. Install with: pip install duckdb pyarrow
autodetect
Profile ingested data and detect identity signals. Returns detected columns, blocking keys, and the inferred entity type.
# Profile all ingested data
kanoniv autodetect
# Profile only person-relevant sources
kanoniv autodetect --entity-type person
# Profile and bootstrap an identity plan
kanoniv autodetect --bootstrap
# Full pipeline: detect person signals and bootstrap a plan
kanoniv autodetect --entity-type person --bootstrap
# Multiple entity types: profile and bootstrap all in one command
kanoniv autodetect --entity-type person product company --bootstrapOutput:
Autodetect Results
Entity type: person
Total records: 3500
Rows sampled: 500
Sources: crm_contacts, billing_customers
Signals: email, phone, first_name, last_name
Blocking Keys
[email]
[phone]
[last_name, first_name]
COLUMN SIGNAL UNIQUENESS NULL_RATE CARDINALITY
email email 0.95 0.01 3325
phone phone 0.88 0.05 3080
first_name first_name 0.12 0.00 892
last_name last_name 0.08 0.00 624
ok: Bootstrapped identity plan: person_v1| Flag | Default | Description |
|---|---|---|
--entity-type <TYPE> [TYPE ...] | - | Entity type(s) to profile: person, company, product, transaction, healthcare. Multiple types run sequentially. |
--bootstrap | false | Generate an identity plan from detected signals |
--version <NAME> | {entity_type}_v1 | Custom version name for the bootstrapped plan |
--sample-size <N> | 500 | Number of rows to sample per source |
reconcile
Run batch reconciliation to merge records into canonical entities.
# Submit and return immediately
kanoniv reconcile
# Wait for completion
kanoniv reconcile --wait
# Reconcile a specific entity type
kanoniv reconcile --wait --entity-type person
# Reconcile multiple entity types in one command
kanoniv reconcile --wait --entity-type person product company
# Dry run (evaluate without persisting)
kanoniv reconcile --dry-runOutput (multi-entity-type with --wait):
Submitted reconciliation (person): abc12345-...
Submitted reconciliation (product): def67890-...
Submitted reconciliation (company): ghi24680-...
Reconciling (person)... completed (12s)
ok: Reconciliation (person) complete (12s)
Merges: 847
Entities: 2653
Reconciling (product)... completed (8s)
ok: Reconciliation (product) complete (8s)
Merges: 42
Entities: 120
Reconciling (company)... completed (3s)
ok: Reconciliation (company) complete (3s)
Merges: 18
Entities: 45| Flag | Default | Description |
|---|---|---|
--wait | false | Wait for reconciliation to complete (polls every 2s, 30 min timeout) |
--dry-run | false | Evaluate without persisting results |
--entity-type <TYPE> [TYPE ...] | - | Entity type(s) to reconcile (uses {type}_v1 plan version). Jobs are submitted in parallel, then waited sequentially. |
autotune
Optimize matching thresholds using the autotuning algorithm.
# Run autotune with defaults
kanoniv autotune
# Custom iteration limit
kanoniv autotune --max-iterations 100
# Tune a specific plan version
kanoniv autotune --version person_v1| Flag | Default | Description |
|---|---|---|
--wait | false | Wait for autotune to complete |
--max-iterations <N> | 50 | Maximum optimization iterations |
--version <NAME> | - | Identity plan version to optimize |
LLM Commands
ask
Chat with the Kanoniv LLM assistant. Streams responses in real-time. The LLM has access to tools that can query your data, search entities, check stats, and run reconciliation.
Chat (default)
kanoniv ask "What data do I have?"You have 3,500 records across 2 sources:
- crm_contacts: 2,100 records
- billing_customers: 1,400 records
All records are typed as "person" entities.
conversation: 550e8400-e29b-41d4-a716-446655440000Follow-up questions automatically continue the last conversation:
kanoniv ask "How many duplicates were found?"Start a new conversation:
kanoniv ask --new "Search for John Anderson"Plan mode
Generate an agent execution plan:
kanoniv ask "Set up automated deduplication for my CRM data" --planGenerate spec
Create an identity spec from a description:
kanoniv ask "Match customers by email and name. Block on email domain." \
--generate-spec --sources crm,billingExplain
Get evidence-based explanations for merge decisions:
kanoniv ask "Why were these two entities merged?" \
--entity-ids 550e8400-...,6ba7b810-...Flags
| Flag | Description |
|---|---|
--new | Start a new conversation (ignore last conversation) |
--conversation <ID> | Continue a specific conversation by ID |
--plan | Generate an agent execution plan instead of chatting |
--generate-spec | Generate a YAML spec from the message |
--sources <NAMES> | Comma-separated source names (used with --generate-spec) |
--entity-ids <IDS> | Comma-separated entity UUIDs (used for explain) |
agent
Manage autonomous agents from the terminal.
# List all agent configurations
kanoniv agent list
# Enable an agent with settings
kanoniv agent enable auto_merge --settings '{"min_confidence": 0.95}'
# Disable an agent
kanoniv agent disable auto_split
# Trigger an immediate run
kanoniv agent trigger auto_merge
# List recent runs
kanoniv agent runs
kanoniv agent runs --type auto_merge --limit 5
# List pending actions
kanoniv agent actions --status pending
# Approve or reject an action
kanoniv agent approve <action-id>
kanoniv agent reject <action-id>| Subcommand | Flags | Description |
|---|---|---|
list | - | List all agent configurations |
enable <TYPE> | --settings <JSON> | Enable agent with optional settings |
disable <TYPE> | - | Disable agent |
trigger <TYPE> | - | Trigger immediate run |
runs | --type <TYPE>, --limit <N> | List agent runs |
actions | --status <STATUS>, --limit <N> | List agent actions |
approve <ID> | - | Approve pending action |
reject <ID> | - | Reject pending action |
Aliases and Shortcuts
The CLI provides several shorthand aliases for common operations. These are useful for interactive use and scripting.
UUID Auto-Route
Pass a UUID directly to kanoniv entity and it auto-routes to entity show:
# These are equivalent
kanoniv entity 8bcb340d-60f2-45a6-9e7d-134bc39eb675
kanoniv entity show 8bcb340d-60f2-45a6-9e7d-134bc39eb675Plural Aliases
Plural forms route to the corresponding domain or a default action:
| Alias | Routes To |
|---|---|
kanoniv entities | kanoniv entity search |
kanoniv clusters | kanoniv graph clusters |
kanoniv sources | kanoniv source |
kanoniv matches | kanoniv match |
kanoniv rows | kanoniv row |
kanoniv overrides | kanoniv override |
kanoniv specs | kanoniv spec |
For example, kanoniv entities --min-records 2 is equivalent to kanoniv entity search --min-records 2. And kanoniv clusters --min-size 3 is equivalent to kanoniv graph clusters --min-size 3.
Legacy Flat Commands
Legacy flat commands from earlier CLI versions are automatically rewritten:
| Legacy Command | Routes To |
|---|---|
kanoniv validate <path> | kanoniv spec validate <path> |
kanoniv compile <path> | kanoniv spec compile <path> |
kanoniv hash <path> | kanoniv spec hash <path> |
kanoniv diff <v1> <v2> | kanoniv spec diff <v1> <v2> |
kanoniv plan <path> | kanoniv spec plan <path> |
kanoniv jobs | kanoniv job list |
kanoniv stats | kanoniv system stats |
kanoniv purge | kanoniv system purge |
Typical Workflow
A complete identity resolution pipeline from the command line:
# 1. Ingest your data (all entity types at once)
kanoniv ingest ./data/ --entity-type person product company
# 2. Profile and bootstrap identity plans for each type
kanoniv autodetect --entity-type person product company --bootstrap
# 3. Run reconciliation for all types
kanoniv reconcile --wait --entity-type person product company
# 4. Check results
kanoniv stats
# 5. Search and filter entities
kanoniv entities --entity-type person --limit 10
kanoniv entities --min-records 2 # find duplicates
kanoniv entities --min-confidence 0.9 --has email # high-confidence with email
kanoniv entities --missing phone # data quality gaps
kanoniv entities --entity-type person --search john --min-records 2 --limit 5
# 6. Drill into a specific entity
kanoniv entity 8bcb340d-60f2-45a6-9e7d-134bc39eb675 # UUID shorthand
kanoniv entity 8bcb340d-... --records # with linked records
kanoniv entity 8bcb340d-... --attrs # just the gold record
kanoniv entity 8bcb340d-... --sources # field provenance
kanoniv entity 8bcb340d-... --relationships # shared identity signals
kanoniv entity 8bcb340d-... --relationships --field email # just email signals
# 7. Investigate matches
kanoniv match explain crm:12345 billing:67890
kanoniv match pending
# 8. Graph analytics
kanoniv graph stats
kanoniv clusters --min-size 3
kanoniv graph orphans --entity-type person
# 9. Export resolved entities
kanoniv export entities -o person_entities.csv --entity-type person --reveal-pii
# 10. Ask questions about your data
kanoniv ask --new "What data do I have?"
kanoniv ask "How many duplicates were found?"
kanoniv ask "Search for John Anderson"Exit Codes
| Code | Meaning |
|---|---|
0 | Success |
1 | Validation errors, file not found, parse error, or command failure |
CI/CD Integration
Pre-commit hook
# .git/hooks/pre-commit
#!/bin/sh
for file in $(git diff --cached --name-only -- '*.yaml'); do
if head -1 "$file" | grep -q "api_version: kanoniv"; then
kanoniv spec validate "$file" || exit 1
fi
doneGitHub Actions
- name: Validate Kanoniv specs
run: |
pip install kanoniv
find specs/ -name '*.yaml' -exec kanoniv spec validate {} \;Full Command Reference
kanoniv [--api-key <KEY>] [--api-url <URL>] [--format json|table]
|
|-- entity (18 commands) -----------------------------------
| entity <uuid> Shorthand for entity show
| entity show <id> Show entity details
| [--records] [--attrs]
| [--sources] [--json]
| [--relationships]
| [--field <FIELD>]
| entity list List entities
| [--entity-type <T>]
| [--min-records <N>] [--max-records <N>]
| [--min-confidence <F>]
| [--has <FIELDS>] [--missing <FIELDS>]
| [--limit <N>] [--offset <N>]
| entity search Search entities
| [-q <query>] [--search <TEXT>]
| [--name <N>] [--email <E>] [--phone <P>]
| [--source <S>] [--entity-type <T>]
| [--min-records <N>] [--max-records <N>]
| [--min-confidence <F>]
| [--has <FIELDS>] [--missing <FIELDS>]
| [--limit <N>] [--offset <N>]
| entity linked <id> Show linked source records
| entity history <id> Show merge history and events
| entity neighbors <id> Show graph neighbors
| [--depth <N>]
| entity merge <id-a> <id-b> Merge two entities
| [--reason <TEXT>]
| entity split <canon-id> <members..> Split members from entity
| [--reason <TEXT>]
| entity reassign <ext-id> <to-id> Move record to another entity
| [--reason <TEXT>]
| entity delete <id> Delete empty entity
| entity link <id-a> <id-b> Create soft edge
| [--weight <F>]
| entity unlink <id-a> <id-b> Remove soft edge
| entity explain <id> Explain entity state
| entity lock <id> Lock entity from merges
| entity revert <id> <event-id> Revert to previous state
| entity attrs <id> Show canonical attributes
| entity candidates <id> Show merge candidates
| [--limit <N>]
| entity diff <id-a> <id-b> Diff two entities
|
|-- source (9 commands) ------------------------------------
| source list List all sources
| source show <id> Show source details
| source schema <id> Show source schema
| source create <name> Create a new source
| [--type <TYPE>] [--config <JSON>]
| source delete <id> Delete a source
| source sync <id> Trigger source sync
| source stats <id> Show source statistics
| source quality <id> Data quality report
| source entities <id> List entities from source
| [--limit <N>]
|
|-- match (7 commands) -------------------------------------
| match explain <a> <b> Explain match between records
| match rules Show active matching rules
| match pending List pending decisions
| [--limit <N>]
| match decide <id-a> <id-b> Accept or reject match
| --accept | --reject
| [--reason <TEXT>]
| match candidates <id> Match candidates for entity
| [--limit <N>]
| match cluster <id> Show match cluster
| match test <a> <b> Test match (dry-run)
|
|-- graph (10 commands) ------------------------------------
| graph stats Graph statistics
| graph cluster <id> Show cluster members
| graph clusters List all clusters
| [--limit <N>] [--min-size <N>]
| graph bridges Bridge signals
| graph refresh Refresh graph analytics
| graph influence <id> Entity influence score
| graph risk <id> Entity risk score
| graph orphans List orphan entities
| [--limit <N>] [--entity-type <T>]
| graph conflicts List incoherent clusters
| [--limit <N>]
| graph density Density and connectivity
|
|-- row (5 commands) ---------------------------------------
| row show <source> <ext-id> Show a source record
| row resolve <source> <ext-id> Real-time resolve
| [--data <JSON>]
| row lookup <source> <ext-id> Look up entity for record
| row memberships List memberships
| [--source <S>] [--entity-id <ID>]
| [--limit <N>]
| row trace <source> <ext-id> Match audit trail
|
|-- spec (9 commands) --------------------------------------
| spec validate <path> Validate spec (offline)
| spec compile <path> Compile to IR (offline)
| [-o <output>]
| spec hash <path> Compute spec hash (offline)
| spec diff <v1> <v2> Diff two specs (offline)
| spec plan <path> Execution plan (offline)
| spec list List specs (cloud)
| spec show <version> Show spec details (cloud)
| spec upload <path> Upload spec (cloud)
| [--compile]
| spec delete <version> Delete spec (cloud)
|
|-- job (4 commands) ---------------------------------------
| job list List recent jobs
| [--limit <N>] [--type <TYPE>]
| job show <id> Show job details
| job cancel <id> Cancel a running job
| job run <type> Run a new job
| [--wait] [--payload <JSON>]
|
|-- export (4 commands) ------------------------------------
| export entities Export canonical entities
| -o <output>
| [--entity-type <T>] [--reveal-pii]
| [--format csv|json]
| export memberships Export memberships
| -o <output>
| [--format csv|json]
| export graph Export identity graph
| -o <output>
| [--entity-type <T>]
| [--format json|csv]
| export matches Export match audit
| -o <output>
| [--entity-type <T>]
| [--format csv|json]
|
|-- override (3 commands) ----------------------------------
| override list List all overrides
| override create <id-a> <id-b> Create override
| --type merge|split
| override delete <id> Delete an override
|
|-- feedback (3 commands) ----------------------------------
| feedback list List feedback labels
| [--limit <N>]
| feedback create <id-a> <id-b> Create label
| --source-a <NAME> --source-b <NAME>
| --label match|no_match
| [--reason <TEXT>]
| feedback delete <id> Delete a label
|
|-- system (6 commands) ------------------------------------
| system version Show version (offline)
| system health Check API health
| system stats Dashboard statistics
| [--entity-type <T>]
| system purge Delete all tenant data
| [--confirm]
| system reindex Rebuild search indexes
| [--target <TARGET>]
| system recompute Recompute derived data
| [--target <TARGET>]
|
|-- Workflows (top-level) ----------------------------------
| ingest <files...> Ingest CSV/JSON files
| [--entity-type <T>]
| [--id-column <COL>]
| autodetect Profile data, detect signals
| [--entity-type <T>]
| [--bootstrap]
| [--version <NAME>]
| [--sample-size <N>]
| reconcile Run reconciliation
| [--wait] [--dry-run]
| [--entity-type <T>]
| autotune Optimize thresholds
| [--wait]
| [--max-iterations <N>]
| [--version <NAME>]
|
|-- LLM / Agent --------------------------------------------
| ask <message> Chat with the LLM
| [--new] [--conversation <ID>]
| [--plan] [--generate-spec]
| [--sources <NAMES>]
| [--entity-ids <IDS>]
| agent list List agent configs
| agent enable <TYPE> Enable agent
| [--settings <JSON>]
| agent disable <TYPE> Disable agent
| agent trigger <TYPE> Trigger agent run
| agent runs List agent runs
| [--type <TYPE>] [--limit <N>]
| agent actions List agent actions
| [--status <S>] [--limit <N>]
| agent approve <ID> Approve action
| agent reject <ID> Reject action
|
|-- Auth ---------------------------------------------------
| login Store API credentials
| logout Clear stored credentials
| context Show current auth context
|
|-- Aliases ------------------------------------------------
| entities [flags] -> entity search [flags]
| clusters [flags] -> graph clusters [flags]
| sources [action] -> source [action]
| matches [action] -> match [action]
| rows [action] -> row [action]
| overrides [action] -> override [action]
| specs [action] -> spec [action]
| jobs [flags] -> job list [flags]
| stats [flags] -> system stats [flags]