API Reference
Complete reference for the Kanoniv REST API.
Quick Start
Install the Python SDK and create a client:
bash
pip install kanoniv[cloud]python
from kanoniv.client import KanonivClient
client = KanonivClient(
api_key="kn_...",
base_url="https://api.kanoniv.com",
)
# Resolve an identity
result = client.resolve(system="Stripe", external_id="cus_123")
print(result["canonical_id"])Base URL
https://api.kanoniv.com/v1All API endpoints are prefixed with /v1.
Authentication
All API requests require an API key. Keys are prefixed with kn_ and scoped per tenant.
python
from kanoniv.client import KanonivClient
client = KanonivClient(api_key="kn_...", base_url="https://api.kanoniv.com")bash
curl https://api.kanoniv.com/v1/entities \
-H "X-API-Key: kn_..."See Authentication for details on creating keys, scopes, and security best practices.
Response Format
All responses use a consistent envelope:
json
{
"data": { ... },
"meta": {
"request_id": "req_abc123",
"timestamp": "2026-02-05T10:00:00Z"
}
}Error responses:
json
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid email format",
"details": { "field": "email" }
},
"meta": {
"request_id": "req_abc123"
}
}SDK Exception Mapping
The Python SDK maps HTTP status codes to typed exceptions:
python
from kanoniv import (
KanonivError, # Base -- catch all
ValidationError, # 400
AuthenticationError, # 401
ForbiddenError, # 403
NotFoundError, # 404
ConflictError, # 409
RateLimitError, # 429
ServerError, # 5xx
)| Exception | HTTP Status | Description |
|---|---|---|
ValidationError | 400 | Bad request body or query parameters |
AuthenticationError | 401 | Invalid or missing credentials |
ForbiddenError | 403 | Insufficient permissions or wrong role |
NotFoundError | 404 | Resource does not exist |
ConflictError | 409 | Resource conflict (e.g., duplicate name) |
RateLimitError | 429 | Too many requests; respect Retry-After |
ServerError | 5xx | Server-side error; retry with backoff |
python
try:
entity = client.entities.get("nonexistent-uuid")
except NotFoundError:
print("Entity not found")
except RateLimitError as e:
print(f"Rate limited -- retry after {e.retry_after}s")
except KanonivError as e:
print(f"API error {e.status_code}: {e}")HTTP Status Codes
| Code | Meaning |
|---|---|
| 200 | Success |
| 201 | Created |
| 204 | No Content (successful delete) |
| 400 | Bad Request (validation error) |
| 401 | Unauthorized (invalid/missing auth) |
| 403 | Forbidden (insufficient permissions) |
| 404 | Not Found |
| 409 | Conflict |
| 429 | Rate Limited |
| 500 | Internal Server Error |
Rate Limits
| Tier | Limit |
|---|---|
| Authenticated (per tenant) | 100 req/min |
| Unauthenticated (per IP) | 20 req/min |
Rate limit headers are included on every response:
http
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1707134400When rate limited, the response includes a Retry-After header. The Python SDK respects this automatically with its built-in retry logic.
Endpoints
Auth
POST /v1/auth/login:Authenticate with email and passwordPOST /v1/auth/signup:Create a new accountPOST /v1/auth/verify:Verify email addressPOST /v1/auth/refresh:Refresh an expired access tokenPOST /v1/auth/change-password:Change account passwordPOST /v1/auth/logout:Invalidate current sessionGET /v1/auth/me/tenant:Get current tenant info
Resolution
GET /v1/resolve:Resolve external ID to canonical entityPOST /v1/resolve/realtime:Real-time resolve with Fellegi-Sunter probabilistic scoring and inline entity mergePOST /v1/resolve/quick:Resolve and auto-create if not foundGET /v1/resolve/pending:List pending review decisionsGET /v1/canonical/:id:Get canonical entity by IDGET /v1/canonical/:id/linked:Get linked external entitiesPOST /v1/entities/linked/bulk:Bulk crosswalk - fetch linked entities for up to 1000 canonical IDs
Entities
GET /v1/entities:Search entitiesGET /v1/entities/:id/history:Entity change historyPOST /v1/entities/:id/lock:Lock entity from mergingPOST /v1/entities/:id/revert/:event_id:Revert to prior state
Identity Specs
GET /v1/identity/specs:List spec versionsPOST /v1/identity/specs:Upload a new spec versionGET /v1/identity/specs/:version:Get spec by version
Reconciliation
POST /v1/reconcile/dry-run:Dry-run reconciliation without persisting results
Jobs
GET /v1/jobs:List reconciliation jobsPOST /v1/jobs/run:Trigger a reconciliation jobGET /v1/jobs/:id:Get job status and detailsPOST /v1/jobs/:id/cancel:Cancel a running job
Observability
GET /v1/identity/specs/:version/summary:Get spec plan summaryGET /v1/jobs/:id/summary:Get job execution summaryGET /v1/jobs/:id/health:Get job health metricsGET /v1/jobs/:id/telemetry:Get job telemetry dataGET /v1/jobs/:id/diff:Get job entity diff
Preview
POST /v1/preview/simulate:Simulate reconciliation on sample dataGET /v1/preview/:id/results:Get simulation results
Rules
GET /v1/rules:List active rulesPOST /v1/rules:Create rule versionGET /v1/rules/:name/history:Rule version history
Sources
GET /v1/sources:List sourcesPOST /v1/sources:Create sourceGET /v1/sources/:id:Get sourcePUT /v1/sources/:id:Update sourceDELETE /v1/sources/:id:Delete sourcePOST /v1/sources/:id/sync:Trigger sync
Overrides
GET /v1/overrides:List overridesPOST /v1/overrides:Create overrideDELETE /v1/overrides/:id:Revoke override
Autodetect
POST /v1/autodetect:Profile ingested data, detect identity signals, and infer entity type
Ingest
POST /v1/ingest/batch:Batch JSON ingest (500 records per request)POST /v1/ingest/parquet:Parquet bulk ingest (Arrow data plane)POST /v1/ingest/file/process:File upload ingest (CSV, JSON)
Feedback
GET /v1/feedback:List feedback labelsPOST /v1/feedback:Create feedback labels (batch)DELETE /v1/feedback/:id:Delete feedback label
Audit
GET /v1/audit:Query audit logGET /v1/audit/entity/:entity_id:Entity audit trail
Settings
GET /v1/settings/audit-streams:List audit streamsPOST /v1/settings/audit-streams:Create audit streamPUT /v1/settings/audit-streams/:id:Update audit streamDELETE /v1/settings/audit-streams/:id:Delete audit streamGET /v1/settings/retention-policies:List retention policiesPOST /v1/settings/retention-policies:Upsert retention policyDELETE /v1/settings/retention-policies/:id:Delete retention policyGET /v1/settings/survivorship:List survivorship policiesPOST /v1/settings/survivorship:Upsert survivorship policyDELETE /v1/settings/survivorship/:id:Delete survivorship policyGET /v1/settings/reconciliation:Get reconciliation settingsPATCH /v1/settings/reconciliation:Update reconciliation settingsGET /v1/settings/sso-config:List SSO configurationsPOST /v1/settings/sso-config:Upsert SSO configurationDELETE /v1/settings/sso-config/:id:Delete SSO configuration
Billing
POST /v1/billing/checkout:Create Stripe checkout sessionPOST /v1/billing/portal:Create billing portal sessionGET /v1/billing/status:Get billing status and usage
Admin
GET /v1/users:List usersPOST /v1/users:Create userPUT /v1/users/:id:Update user roleDELETE /v1/users/:id:Deactivate userGET /v1/api-keys:List API keysPOST /v1/api-keys:Create API keyDELETE /v1/api-keys/:id:Revoke API keyPATCH /v1/tenant:Update tenant settingsGET /v1/stats:Get dashboard statistics
