The details behind the flow
Build with DupeZero.
Configure a dataset. Submit records. Resolve identities. Retrieve results with their evidence.
This guide documents the Rust control-plane API as it exists today. The signed-in web application calls it through a server-side backend-for-frontend. A browser session cookie is not a control-plane API credential.
Obtain your deployment’s API origin and an organization-scoped key from your administrator. Public production API onboarding and a complete OpenAPI operation contract are not yet established by this repository. The examples use environment variables for your own configured deployment.
# Use the API origin supplied for your deployment, without a trailing slash.
export ER_API_ORIGIN='https://your-api.example.com'
export ER_ORG='your-org'
export ER_DATASET='contacts'
# Set ER_API_KEY through your secret manager or local shell.
# Never put an operator token in browser code.- Provision an organization and obtain a scoped key.
- Create or select a dataset and wait for it to become active.
- Configure sources, identity comparisons, review policy, and survivorship.
- Publish a validated configuration, then submit a source delivery.
- Monitor the returned job and retrieve results after success.
- Inspect evidence and apply corrections through reconciliation.
One organization. Multiple datasets.
An organization is the ownership and authorization boundary. It contains datasets, keys, connections, and organization-level settings. A dataset is a separate resolution workspace with its own source mappings, configuration versions, models, jobs, and results. The same upstream system can feed several datasets through their separately configured mappings.
Paths use the organization and dataset routing names: /v1/orgs/{org}/datasets/{ds}. Do not substitute a display name or assume a dataset’s entity identifiers belong to another dataset.
Dataset creation currently supports person and account entity types, fixed at creation. Organization admins can use auto-provisioning when the deployment has a provisioning profile; supplying infrastructure paths and lake settings requires operator access.
curl --fail-with-body -X POST "$ER_API_ORIGIN/v1/orgs/$ER_ORG/datasets" -H "Authorization: Bearer $ER_API_KEY" -H 'Content-Type: application/json' --data '{"name":"contacts","display_name":"Contacts","entity_type":"person"}'Creation may initiate provisioning. Fetch the dataset and check its state before submitting work. If auto-provisioning is unavailable, have the operator configure the environment; inventing a lake path is not a client-side workaround.
Authentication and roles
Send Authorization: Bearer <credential> on control-plane requests. Organization API keys have the form erk_<key_id>_<secret>. The server derives organization scope and role from the stored key. Headers cannot promote a caller.
| Role | Typical authority |
|---|---|
| viewer | Read datasets, results, and evidence. |
| steward | Submit deliveries and jobs; record review decisions and corrections. |
| admin | Manage configuration and organization settings; create auto-provisioned datasets. |
| operator | Provision infrastructure and operate cross-organization service surfaces. |
The hierarchy is viewer → steward → admin → operator. Each endpoint still applies its own guard. An invalid or missing credential returns 401; insufficient authority within the organization returns 403; an organization outside the key’s scope returns 404.
curl --fail-with-body "$ER_API_ORIGIN/v1/orgs/$ER_ORG/datasets" -H "Authorization: Bearer $ER_API_KEY"This endpoint returns a bare JSON array, not an items envelope. Keep keys in server-side integrations, rotate them through the operator-managed key lifecycle, and use the least role your workflow needs.
Sources, matching, and survivorship
A published dataset configuration defines the source names, mapped fields, standardization, blocking, comparisons, model behavior, and survivorship used by resolution. Uploads reference a source name already present in that active configuration. Adding a source to the marketing example does not configure a real dataset.
Read the active configuration at GET /v1/orgs/{org}/datasets/{ds}/config. Create a draft with POST …/config/versions and a JSON body containing a yaml string. The service validates the YAML and hashes the configuration. Use the returned version for validation and publication operations in the reference below.
# config.yaml is your deployment-reviewed dataset configuration.
python3 -c 'import json; print(json.dumps({"yaml": open("config.yaml").read()}))' > config-request.json
curl --fail-with-body -X POST "$ER_API_ORIGIN/v1/orgs/$ER_ORG/datasets/$ER_DATASET/config/versions" -H "Authorization: Bearer $ER_API_KEY" -H 'Content-Type: application/json' --data-binary @config-request.jsonA saved draft is not the active configuration. Publication checks are part of the workflow; validation failures need a configuration correction, not a blind retry. Matching decides which records belong together. Survivorship decides which field values appear on the resulting golden record. Keep these decisions separate.
Submit a source delivery
The file-ingestion endpoint accepts a multipart field named file and a required source query parameter. The source must exist in the active dataset configuration. The dataset must be active and have a configured delivery location.
curl --fail-with-body -X POST "$ER_API_ORIGIN/v1/orgs/$ER_ORG/datasets/$ER_DATASET/imports?source=crm" -H "Authorization: Bearer $ER_API_KEY" -F 'file=@records.csv;type=text/csv'The server stages an immutable delivery and enqueues its consumer. A successful upload returns HTTP 202 with delivery_id and a job object. Record both. Accepted means queued, not resolved.
{
"delivery_id": "<delivery identifier>",
"job": { "id": "<job identifier>", "state": "queued", "...": "additional job fields" }
}Missing source or file fields return 422; uploads above the deployment’s configured cap return 413; inactive state can return 409; unavailable delivery storage can return 503. The JSON record-push surface is a separate operation in the reference and caps a request at 10,000 records; larger submissions belong in file deliveries. Consult its declared body before using it.
Run and monitor
An upload already returns the job consuming its delivery. Poll that job rather than automatically enqueueing a second full run. For separately requested processing, the job endpoint accepts kind, optional priority, and an optional configured segment name.
curl --fail-with-body -X POST "$ER_API_ORIGIN/v1/orgs/$ER_ORG/datasets/$ER_DATASET/jobs" -H "Authorization: Bearer $ER_API_KEY" -H 'Content-Type: application/json' --data '{"kind":"run_all_full"}'curl --fail-with-body "$ER_API_ORIGIN/v1/orgs/$ER_ORG/datasets/$ER_DATASET/jobs/$ER_JOB_ID" -H "Authorization: Bearer $ER_API_KEY"Track queued, running, succeeded, failed, and canceled states. A successful submission is HTTP 202; the eventual job outcome is separate. Inspect task details for failed work. Resume, cancel, and task-clear operations have distinct effects; check their reference entries instead of recreating jobs indiscriminately.
Use a bounded polling interval with backoff in your client. A segment is a name from published configuration, not SQL supplied by the request. Unknown segments are rejected at submission.
Retrieve results and evidence
The golden-record list is an Apache Arrow IPC stream, not JSON. Read application/vnd.apache.arrow.stream with an Arrow-capable client. The response headers carry x-er-snapshot and, when another page exists, x-er-next-cursor.
curl --fail-with-body --get "$ER_API_ORIGIN/v1/orgs/$ER_ORG/datasets/$ER_DATASET/golden-records" -H "Authorization: Bearer $ER_API_KEY" --data-urlencode 'limit=100' --dump-header result-headers.txt --output records.arrowFor the next page, send the returned opaque value as the cursor query parameter. Keep query filters such as q consistent across that traversal. The cursor pins the snapshot; do not decode, edit, or construct it. An invalid cursor returns 422. Historical snapshots may become unavailable after retention and maintenance.
GET …/golden-records/{entity_id} returns JSON detail with members, lineage, and events. Its optional snapshot parameter requests a historical version. Do not parse a list response as if it were a detail response.
Other collections vary: some return bare arrays, some wrap rows under a named key, and some return pagination metadata. Each reference entry includes the generated envelope where available. There is no universal collection wrapper.
Review, correct, reconcile
Use match evidence to understand a proposed grouping before deciding. Review policy determines which matches can proceed automatically and which need a person. AI-assisted review is a recommendation workflow; it does not remove the need to understand the configured approval policy.
Assertions record that records must match or must remain separate. Unmerge splits selected members out of an entity. These changes may be staged until reconciliation applies them; an accepted correction is not the same thing as a refreshed golden record.
curl --fail-with-body -X POST "$ER_API_ORIGIN/v1/orgs/$ER_ORG/datasets/$ER_DATASET/golden-records/$ER_ENTITY_ID/unmerge" -H "Authorization: Bearer $ER_API_KEY" -H 'Content-Type: application/json' --data '{"records":["<member-record-key>"],"apply_now":true}'Inspect the returned state and any queued job before reading the final result. A correction preserves the decision history and changes reconciliation; it does not retrain the probability model. Conflicting assertions require resolution, not silent precedence. The contradiction inspection operation exposes those conflicts.
Connect the systems you use
Source transport, dataset mapping, and destination delivery are separate concerns. Salesforce-specific connections and writeback live alongside shared ingestion and result contracts. File deliveries, object storage, and custom clients should reuse those shared contracts where supported.
ZoomInfo: the landing-page example shows a proposed custom integration on both sides of the flow. This repository does not contain a verified ZoomInfo connector. Read access, permitted write operations, field mappings, and account entitlements must be established before promising a working read or write path.
Webhook registration and delivery operations appear in the reference. Confirm configured signing, event selection, and delivery behavior before relying on notifications. Reconciliation inside DupeZero does not by itself imply a successful write to an external system; track the destination operation independently.
Errors, retries, and compatibility
Control-plane handler errors generally use a JSON detail field. Request extraction and infrastructure failures may differ; always inspect HTTP status and content type before decoding a response.
HTTP/1.1 403 Forbidden
Content-Type: application/json
{"detail":"requires admin role"}| Status | Client action |
|---|---|
| 401 | Check the credential; do not retry the same invalid key. |
| 403 | Use the required role for this operation. |
| 404 | Check scope and identifiers; a cross-org request is deliberately indistinguishable from absence. |
| 409 | Inspect current resource state before resubmitting. |
| 413 | Reduce the delivery size to the configured cap. |
| 422 | Correct the request, configuration, or cursor. |
| 501 / 503 | Check deployment capabilities and service readiness; distinguish missing setup from transient unavailability. |
| 5xx / network error | For safe reads, use bounded backoff. For writes, verify the outcome before retrying. |
No general idempotency-key contract is established here. Repeating an upload or job submission can create another delivery or job. Persist returned identifiers; if a write times out, inspect its outcome before issuing a replacement. Only rely on idempotence explicitly documented for an operation.
The generated OpenAPI schemas do not yet provide complete operation coverage or a production compatibility guarantee. Pin your client to the deployed version and test the complete workflow against that environment. No live-request console runs from this public page.
Usage and pricing
The Home slider represents records in an example run. It is not a rate card, throughput promise, or invoice calculator. Adding sources redistributes that total; it does not imply a per-source charge.
The current pricing direction is per-run compute, with commercial rates still to be established. The web application’s existing usage panel meters AI calls and token units; those counts are not a billing ledger. Bring-your-own model keys can also incur provider charges outside DupeZero.
Record volume alone cannot predict runtime or price: comparisons, candidate generation, configuration, and actual execution work matter. Confirm a commercial estimate for your workload before treating any usage number as cost.
Reference
Every declared operation.
This inventory is generated from the control plane’s route manifest and response-envelope contract. It describes the current implementation, including operator-only routes. It is not a promise that every operation is enabled for your deployment.
Request schemas below describe JSON body structure where it has been declared. A missing schema does not mean an endpoint accepts an empty body. Query parameters and non-JSON payloads are described in the workflow guides for ingestion and result retrieval. Response descriptors identify the envelope, not a complete response schema.
Role caveat: dataset creation is recorded as operator in the manifest. The auto-provisioning path accepts an organization admin; supplying config_path requires operator access.
Dataset operations
82 operations. Expand an entry for its path parameters, declared request shape, and response envelope.
DELETE/v1/orgs/{org}/datasets/{ds}/assertions/{assertion_id}steward
stage an assertion retraction
- Authentication / minimum role
- Bearer credential with steward authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds, assertion_id
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
A response descriptor is not yet generated for this operation. Do not infer its payload from another endpoint.
Link to this operationDELETE/v1/orgs/{org}/datasets/{ds}/entity-links/{link_id}steward
remove a link
- Authentication / minimum role
- Bearer credential with steward authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds, link_id
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
A response descriptor is not yet generated for this operation. Do not infer its payload from another endpoint.
Link to this operationDELETE/v1/orgs/{org}/datasets/{ds}/schedules/{schedule_id}admin
delete a schedule
- Authentication / minimum role
- Bearer credential with admin authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds, schedule_id
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
A response descriptor is not yet generated for this operation. Do not infer its payload from another endpoint.
Link to this operationGET/v1/orgs/{org}/datasets/{ds}viewer
one dataset's detail
- Authentication / minimum role
- Bearer credential with viewer authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
{
"envelope": "scalar"
}GET/v1/orgs/{org}/datasets/{ds}/assertionsviewer
the assertion ledger
- Authentication / minimum role
- Bearer credential with viewer authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
{
"envelope": "page",
"key": "items"
}GET/v1/orgs/{org}/datasets/{ds}/assertions:contradictionsviewer
the unsatisfiable rule sets
- Authentication / minimum role
- Bearer credential with viewer authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
{
"envelope": "wrapped",
"key": "contradictions"
}GET/v1/orgs/{org}/datasets/{ds}/blocking-estimateviewer
what a run would cost before it runs
- Authentication / minimum role
- Bearer credential with viewer authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
{
"envelope": "scalar"
}GET/v1/orgs/{org}/datasets/{ds}/configviewer
the org's active (published) config
- Authentication / minimum role
- Bearer credential with viewer authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
{
"envelope": "scalar"
}GET/v1/orgs/{org}/datasets/{ds}/config/versionsviewer
list an org's config versions, newest first
- Authentication / minimum role
- Bearer credential with viewer authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
{
"envelope": "bare"
}GET/v1/orgs/{org}/datasets/{ds}/config/versions/{version}viewer
one config version with its `yaml`
- Authentication / minimum role
- Bearer credential with viewer authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds, version
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
{
"envelope": "scalar"
}GET/v1/orgs/{org}/datasets/{ds}/data-qualityviewer
data-quality scores over the org's lake
- Authentication / minimum role
- Bearer credential with viewer authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
{
"envelope": "scalar"
}GET/v1/orgs/{org}/datasets/{ds}/duplicatesviewer
duplicate groups (entities with >=2 members)
- Authentication / minimum role
- Bearer credential with viewer authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
{
"envelope": "record",
"keys": [
"items",
"snapshot",
"next_cursor"
]
}GET/v1/orgs/{org}/datasets/{ds}/entities/{entity_id}/linksviewer
every link touching one entity, from either side
- Authentication / minimum role
- Bearer credential with viewer authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds, entity_id
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
{
"envelope": "wrapped",
"key": "items"
}GET/v1/orgs/{org}/datasets/{ds}/golden-recordsviewer
a keyset page of the org's golden (resolved) records
- Authentication / minimum role
- Bearer credential with viewer authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
{
"envelope": "arrow",
"cursor_in": "headers"
}GET/v1/orgs/{org}/datasets/{ds}/golden-records/{entity_id}viewer
one resolved entity with members/lineage/events
- Authentication / minimum role
- Bearer credential with viewer authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds, entity_id
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
{
"envelope": "scalar"
}GET/v1/orgs/{org}/datasets/{ds}/ignore-wordsviewer
the org's ignore-words dictionary
- Authentication / minimum role
- Bearer credential with viewer authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
{
"envelope": "wrapped",
"key": "rows"
}GET/v1/orgs/{org}/datasets/{ds}/importsviewer
ingest-batch receipts
- Authentication / minimum role
- Bearer credential with viewer authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
{
"envelope": "page",
"key": "items"
}GET/v1/orgs/{org}/datasets/{ds}/imports/recentviewer
the most recent ingest-batch receipts
- Authentication / minimum role
- Bearer credential with viewer authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
{
"envelope": "bare"
}GET/v1/orgs/{org}/datasets/{ds}/insightsviewer
the resolution metrics over time
- Authentication / minimum role
- Bearer credential with viewer authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
{
"envelope": "record",
"keys": [
"snapshot",
"series"
]
}GET/v1/orgs/{org}/datasets/{ds}/insights/sourcesviewer
one run's per-source duplicate attribution
- Authentication / minimum role
- Bearer credential with viewer authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
{
"envelope": "record",
"keys": [
"snapshot",
"run_id",
"sources"
]
}GET/v1/orgs/{org}/datasets/{ds}/jobsviewer
list an org's jobs, newest first
- Authentication / minimum role
- Bearer credential with viewer authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
{
"envelope": "wrapped",
"key": "jobs"
}GET/v1/orgs/{org}/datasets/{ds}/jobs/{job_id}viewer
one job by id
- Authentication / minimum role
- Bearer credential with viewer authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds, job_id
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
{
"envelope": "bare"
}GET/v1/orgs/{org}/datasets/{ds}/jobs/{job_id}/tasksviewer
every try of every task of one job, in topological then try order, archived tries included
- Authentication / minimum role
- Bearer credential with viewer authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds, job_id
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
{
"envelope": "wrapped",
"key": "tasks"
}GET/v1/orgs/{org}/datasets/{ds}/labeling/nextviewer
what to label next
- Authentication / minimum role
- Bearer credential with viewer authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
{
"envelope": "record",
"keys": [
"items",
"snapshot",
"threshold",
"band",
"coverage"
]
}GET/v1/orgs/{org}/datasets/{ds}/labelsviewer
the labels a tenant has recorded
- Authentication / minimum role
- Bearer credential with viewer authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
{
"envelope": "wrapped",
"key": "labels"
}GET/v1/orgs/{org}/datasets/{ds}/lexiconviewer
the org's nickname lexicon
- Authentication / minimum role
- Bearer credential with viewer authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
{
"envelope": "wrapped",
"key": "pairs"
}GET/v1/orgs/{org}/datasets/{ds}/match-previewsteward
a READ-ONLY score-only match preview (frontend §7.16, `GET /v1/orgs/{org}/datasets/{ds}/match-preview`)
- Authentication / minimum role
- Bearer credential with steward authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
{
"envelope": "scalar"
}GET/v1/orgs/{org}/datasets/{ds}/match-scoresviewer
active pairwise match scores
- Authentication / minimum role
- Bearer credential with viewer authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
{
"envelope": "record",
"keys": [
"items",
"snapshot",
"next_cursor"
]
}GET/v1/orgs/{org}/datasets/{ds}/merge-plansviewer
merge plans for entities touched by a merge/member-add
- Authentication / minimum role
- Bearer credential with viewer authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
{
"envelope": "wrapped",
"key": "items"
}GET/v1/orgs/{org}/datasets/{ds}/metricsviewer
dashboard counters over the org's lake
- Authentication / minimum role
- Bearer credential with viewer authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
{
"envelope": "scalar"
}GET/v1/orgs/{org}/datasets/{ds}/modelsviewer
the tenant's model versions
- Authentication / minimum role
- Bearer credential with viewer authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
{
"envelope": "record",
"keys": [
"items",
"active"
]
}GET/v1/orgs/{org}/datasets/{ds}/models/{name}/versions/{version}viewer
one model version with its document and weights
- Authentication / minimum role
- Bearer credential with viewer authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds, name, version
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
{
"envelope": "scalar"
}GET/v1/orgs/{org}/datasets/{ds}/models/{name}/versions/{version}/evaluationviewer
how a model version scored against its own labels
- Authentication / minimum role
- Bearer credential with viewer authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds, name, version
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
{
"envelope": "scalar"
}GET/v1/orgs/{org}/datasets/{ds}/profileviewer
a corpus stage's profile
- Authentication / minimum role
- Bearer credential with viewer authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
{
"envelope": "scalar"
}GET/v1/orgs/{org}/datasets/{ds}/qualityviewer
the corpus's data-quality picture
- Authentication / minimum role
- Bearer credential with viewer authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
{
"envelope": "scalar"
}GET/v1/orgs/{org}/datasets/{ds}/recordsviewer
standardized source records by `record_key`
- Authentication / minimum role
- Bearer credential with viewer authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
{
"envelope": "record",
"keys": [
"items",
"snapshot"
]
}GET/v1/orgs/{org}/datasets/{ds}/reviewsviewer
the open-review queue
- Authentication / minimum role
- Bearer credential with viewer authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
{
"envelope": "record",
"keys": [
"items",
"snapshot",
"next_cursor",
"unscored_hidden"
]
}GET/v1/orgs/{org}/datasets/{ds}/reviews/{review_id}viewer
one review by id
- Authentication / minimum role
- Bearer credential with viewer authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds, review_id
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
{
"envelope": "scalar"
}GET/v1/orgs/{org}/datasets/{ds}/reviews/{review_id}/merge-groupviewer
the review merge dialog's group
- Authentication / minimum role
- Bearer credential with viewer authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds, review_id
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
{
"envelope": "record",
"keys": [
"items",
"total",
"snapshot"
]
}GET/v1/orgs/{org}/datasets/{ds}/runsviewer
the 20 most recent runs
- Authentication / minimum role
- Bearer credential with viewer authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
{
"envelope": "bare"
}GET/v1/orgs/{org}/datasets/{ds}/runs/{run_id}/entity-eventsviewer
one run's entity events
- Authentication / minimum role
- Bearer credential with viewer authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds, run_id
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
{
"envelope": "record",
"keys": [
"items",
"run_id",
"snapshot",
"next_cursor"
]
}GET/v1/orgs/{org}/datasets/{ds}/s3-ingestviewer
this tenant's auto-ingest state
- Authentication / minimum role
- Bearer credential with viewer authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
{
"envelope": "record",
"keys": [
"bucket",
"prefix",
"sources"
]
}GET/v1/orgs/{org}/datasets/{ds}/schedulesviewer
list an org's schedules
- Authentication / minimum role
- Bearer credential with viewer authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
{
"envelope": "bare"
}GET/v1/orgs/{org}/datasets/{ds}/segmentsviewer
the segments the active config declares
- Authentication / minimum role
- Bearer credential with viewer authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
{
"envelope": "wrapped",
"key": "segments"
}GET/v1/orgs/{org}/datasets/{ds}/stagedviewer
how many steward actions await the next reconcile
- Authentication / minimum role
- Bearer credential with viewer authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
{
"envelope": "wrapped",
"key": "pending_count"
}GET/v1/orgs/{org}/datasets/{ds}/taggingsviewer
every tagging of one subject kind in one dataset
- Authentication / minimum role
- Bearer credential with viewer authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
{
"envelope": "record",
"keys": [
"taggings",
"truncated"
]
}PATCH/v1/orgs/{org}/datasets/{ds}admin
update a dataset's display fields
- Authentication / minimum role
- Bearer credential with admin authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds
{
"type": "object",
"properties": {
"display_name": {
"type": "string"
}
},
"required": [],
"additionalProperties": false
}A response descriptor is not yet generated for this operation. Do not infer its payload from another endpoint.
Link to this operationPATCH/v1/orgs/{org}/datasets/{ds}/schedules/{schedule_id}admin
enable/disable a schedule
- Authentication / minimum role
- Bearer credential with admin authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds, schedule_id
{
"type": "object",
"properties": {
"enabled": {
"type": "boolean"
}
},
"required": [
"enabled"
],
"additionalProperties": false
}A response descriptor is not yet generated for this operation. Do not infer its payload from another endpoint.
Link to this operationPOST/v1/orgs/{org}/datasets/{ds}/assertionssteward
stage an always/never assertion on a pair
- Authentication / minimum role
- Bearer credential with steward authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds
{
"type": "object",
"properties": {
"kind": {
"type": "string"
},
"a": {
"type": "string"
},
"b": {
"type": "string"
},
"note": {
"type": "string"
},
"apply_now": {
"type": "boolean"
}
},
"required": [
"kind",
"a",
"b"
],
"additionalProperties": false
}A response descriptor is not yet generated for this operation. Do not infer its payload from another endpoint.
Link to this operationPOST/v1/orgs/{org}/datasets/{ds}/config/versionsadmin
create a draft config version
- Authentication / minimum role
- Bearer credential with admin authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds
{
"type": "object",
"properties": {
"yaml": {
"type": "string"
}
},
"required": [
"yaml"
],
"additionalProperties": false
}A response descriptor is not yet generated for this operation. Do not infer its payload from another endpoint.
Link to this operationPOST/v1/orgs/{org}/datasets/{ds}/config/versions/{version}/publishadmin
publish a draft config version
- Authentication / minimum role
- Bearer credential with admin authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds, version
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
A response descriptor is not yet generated for this operation. Do not infer its payload from another endpoint.
Link to this operationPOST/v1/orgs/{org}/datasets/{ds}/entity-linkssteward
link two entities WITHOUT merging them
- Authentication / minimum role
- Bearer credential with steward authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds
{
"type": "object",
"properties": {
"parent_entity_id": {
"type": "string"
},
"child_entity_id": {
"type": "string"
},
"kind": {
"type": "string"
},
"note": {
"type": "string"
}
},
"required": [
"parent_entity_id",
"child_entity_id",
"kind"
],
"additionalProperties": false
}A response descriptor is not yet generated for this operation. Do not infer its payload from another endpoint.
Link to this operationPOST/v1/orgs/{org}/datasets/{ds}/extractsteward
pull an sObject from Salesforce into this dataset
- Authentication / minimum role
- Bearer credential with steward authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds
{
"type": "object"
}A response descriptor is not yet generated for this operation. Do not infer its payload from another endpoint.
Link to this operationPOST/v1/orgs/{org}/datasets/{ds}/golden-records/{entity_id}/unmergesteward
split members out of a resolved entity
- Authentication / minimum role
- Bearer credential with steward authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds, entity_id
{
"type": "object",
"properties": {
"records": {
"type": "array",
"items": {
"type": "string"
}
},
"apply_now": {
"type": "boolean"
}
},
"required": [
"records"
],
"additionalProperties": false
}A response descriptor is not yet generated for this operation. Do not infer its payload from another endpoint.
Link to this operationPOST/v1/orgs/{org}/datasets/{ds}/importssteward
upload one source's delivery
- Authentication / minimum role
- Bearer credential with steward authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
A response descriptor is not yet generated for this operation. Do not infer its payload from another endpoint.
Link to this operationPOST/v1/orgs/{org}/datasets/{ds}/jobssteward
enqueue a job for an org
- Authentication / minimum role
- Bearer credential with steward authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds
{
"type": "object",
"properties": {
"kind": {
"type": "string"
},
"priority": {
"type": "integer"
},
"segment": {
"type": "string"
}
},
"required": [
"kind"
],
"additionalProperties": false
}A response descriptor is not yet generated for this operation. Do not infer its payload from another endpoint.
Link to this operationPOST/v1/orgs/{org}/datasets/{ds}/jobs/{job_id}/cancelsteward
cancel a job
- Authentication / minimum role
- Bearer credential with steward authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds, job_id
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
A response descriptor is not yet generated for this operation. Do not infer its payload from another endpoint.
Link to this operationPOST/v1/orgs/{org}/datasets/{ds}/jobs/{job_id}/resumesteward
requeue a failed/canceled job
- Authentication / minimum role
- Bearer credential with steward authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds, job_id
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
A response descriptor is not yet generated for this operation. Do not infer its payload from another endpoint.
Link to this operationPOST/v1/orgs/{org}/datasets/{ds}/jobs/{job_id}/tasks/{task_id}/clearsteward
clear one task and everything downstream of it, so it re-runs WITHOUT re-running the whole job
- Authentication / minimum role
- Bearer credential with steward authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds, job_id, task_id
{
"type": "object",
"properties": {
"retries": {
"type": "integer"
},
"resource_class": {
"type": "string"
}
},
"required": [],
"additionalProperties": false
}A response descriptor is not yet generated for this operation. Do not infer its payload from another endpoint.
Link to this operationPOST/v1/orgs/{org}/datasets/{ds}/labelssteward
record a verdict on a pair
- Authentication / minimum role
- Bearer credential with steward authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds
{
"type": "object",
"properties": {
"rec_a_key": {
"type": "string"
},
"rec_b_key": {
"type": "string"
},
"verdict": {
"type": "string"
},
"note": {
"type": "string"
},
"model_version": {
"type": "string"
},
"score_at_label": {
"type": "number"
}
},
"required": [
"rec_a_key",
"rec_b_key",
"verdict"
],
"additionalProperties": false
}A response descriptor is not yet generated for this operation. Do not infer its payload from another endpoint.
Link to this operationPOST/v1/orgs/{org}/datasets/{ds}/mass-updatesteward
stage golden field overrides across many entities in one window
- Authentication / minimum role
- Bearer credential with steward authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds
{
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"entity_id": {
"type": "string"
},
"attribute": {
"type": "string"
},
"value": {
"type": "string"
},
"clear": {
"type": "boolean"
}
},
"required": [
"entity_id",
"attribute"
],
"additionalProperties": false
}
},
"apply_now": {
"type": "boolean"
}
},
"required": [
"items"
],
"additionalProperties": false
}A response descriptor is not yet generated for this operation. Do not infer its payload from another endpoint.
Link to this operationPOST/v1/orgs/{org}/datasets/{ds}/mergessteward
merge a GROUP of records from the review dialog
- Authentication / minimum role
- Bearer credential with steward authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds
{
"type": "object",
"properties": {
"records": {
"type": "array",
"items": {
"type": "string"
}
},
"master": {
"type": "string"
},
"overrides": {
"type": "array",
"items": {
"type": "object",
"properties": {
"attribute": {
"type": "string"
},
"value": {
"type": "string"
},
"clear": {
"type": "boolean"
}
},
"required": [
"attribute"
],
"additionalProperties": false
}
},
"review_id": {
"type": "string"
},
"apply_now": {
"type": "boolean"
}
},
"required": [
"records",
"master"
],
"additionalProperties": false
}A response descriptor is not yet generated for this operation. Do not infer its payload from another endpoint.
Link to this operationPOST/v1/orgs/{org}/datasets/{ds}/models/versionsadmin
mint a new model version
- Authentication / minimum role
- Bearer credential with admin authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds
{
"type": "object",
"properties": {
"model_json": {
"type": "string"
},
"model_version_label": {
"type": "string"
},
"name": {
"type": "string"
},
"tf_snapshot_id": {
"type": "string"
},
"provenance": {}
},
"required": [
"model_json",
"model_version_label"
],
"additionalProperties": false
}A response descriptor is not yet generated for this operation. Do not infer its payload from another endpoint.
Link to this operationPOST/v1/orgs/{org}/datasets/{ds}/models/{name}/versions/{version}/activateadmin
activate a model version
- Authentication / minimum role
- Bearer credential with admin authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds, name, version
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
A response descriptor is not yet generated for this operation. Do not infer its payload from another endpoint.
Link to this operationPOST/v1/orgs/{org}/datasets/{ds}/models:compileadmin
compile the org's ACTIVE config into a new draft model version
- Authentication / minimum role
- Bearer credential with admin authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
A response descriptor is not yet generated for this operation. Do not infer its payload from another endpoint.
Link to this operationPOST/v1/orgs/{org}/datasets/{ds}/profilesteward
profile a corpus stage
- Authentication / minimum role
- Bearer credential with steward authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds
{
"type": "object"
}A response descriptor is not yet generated for this operation. Do not infer its payload from another endpoint.
Link to this operationPOST/v1/orgs/{org}/datasets/{ds}/records/protectsteward
pin a record master for its entity
- Authentication / minimum role
- Bearer credential with steward authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds
{
"type": "object",
"properties": {
"record_key": {
"type": "string"
},
"record_keys": {
"type": "array",
"items": {
"type": "string"
}
},
"apply_now": {
"type": "boolean"
}
},
"required": [],
"additionalProperties": false
}A response descriptor is not yet generated for this operation. Do not infer its payload from another endpoint.
Link to this operationPOST/v1/orgs/{org}/datasets/{ds}/records/suppresssteward
exclude a record from golden assembly
- Authentication / minimum role
- Bearer credential with steward authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds
{
"type": "object",
"properties": {
"record_key": {
"type": "string"
},
"record_keys": {
"type": "array",
"items": {
"type": "string"
}
},
"apply_now": {
"type": "boolean"
}
},
"required": [],
"additionalProperties": false
}A response descriptor is not yet generated for this operation. Do not infer its payload from another endpoint.
Link to this operationPOST/v1/orgs/{org}/datasets/{ds}/records/unprotectsteward
retract a record protection
- Authentication / minimum role
- Bearer credential with steward authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds
{
"type": "object",
"properties": {
"record_key": {
"type": "string"
},
"record_keys": {
"type": "array",
"items": {
"type": "string"
}
},
"apply_now": {
"type": "boolean"
}
},
"required": [],
"additionalProperties": false
}A response descriptor is not yet generated for this operation. Do not infer its payload from another endpoint.
Link to this operationPOST/v1/orgs/{org}/datasets/{ds}/records/unsuppresssteward
retract a record suppression
- Authentication / minimum role
- Bearer credential with steward authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds
{
"type": "object",
"properties": {
"record_key": {
"type": "string"
},
"record_keys": {
"type": "array",
"items": {
"type": "string"
}
},
"apply_now": {
"type": "boolean"
}
},
"required": [],
"additionalProperties": false
}A response descriptor is not yet generated for this operation. Do not infer its payload from another endpoint.
Link to this operationPOST/v1/orgs/{org}/datasets/{ds}/records:ingeststeward
push records as JSON
- Authentication / minimum role
- Bearer credential with steward authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds
{
"type": "object",
"properties": {
"source": {
"type": "string"
},
"records": {
"type": "array",
"items": {}
}
},
"required": [
"source",
"records"
],
"additionalProperties": false
}A response descriptor is not yet generated for this operation. Do not infer its payload from another endpoint.
Link to this operationPOST/v1/orgs/{org}/datasets/{ds}/resolveviewer
resolve an UNSAVED record against the corpus
- Authentication / minimum role
- Bearer credential with viewer authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds
{
"type": "object",
"properties": {
"source": {
"type": "string"
},
"record": {},
"limit": {
"type": "integer"
}
},
"required": [
"source",
"record"
],
"additionalProperties": false
}A response descriptor is not yet generated for this operation. Do not infer its payload from another endpoint.
Link to this operationPOST/v1/orgs/{org}/datasets/{ds}/resumeadmin
resume a suspended dataset
- Authentication / minimum role
- Bearer credential with admin authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
A response descriptor is not yet generated for this operation. Do not infer its payload from another endpoint.
Link to this operationPOST/v1/orgs/{org}/datasets/{ds}/reviews/bulk-resolvesteward
stage many review resolutions in one window
- Authentication / minimum role
- Bearer credential with steward authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds
{
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"review_id": {
"type": "string"
},
"resolution": {
"type": "string"
}
},
"required": [
"review_id",
"resolution"
],
"additionalProperties": false
}
},
"apply_now": {
"type": "boolean"
}
},
"required": [
"items"
],
"additionalProperties": false
}A response descriptor is not yet generated for this operation. Do not infer its payload from another endpoint.
Link to this operationPOST/v1/orgs/{org}/datasets/{ds}/reviews/{review_id}/resolvesteward
stage a review resolution
- Authentication / minimum role
- Bearer credential with steward authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds, review_id
{
"type": "object",
"properties": {
"resolution": {
"type": "string"
}
},
"required": [
"resolution"
],
"additionalProperties": false
}A response descriptor is not yet generated for this operation. Do not infer its payload from another endpoint.
Link to this operationPOST/v1/orgs/{org}/datasets/{ds}/schedulesadmin
create an API-sourced schedule
- Authentication / minimum role
- Bearer credential with admin authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds
{
"type": "object",
"properties": {
"kind": {
"type": "string"
},
"cron": {
"type": "string"
},
"params": {}
},
"required": [
"kind",
"cron"
],
"additionalProperties": false
}A response descriptor is not yet generated for this operation. Do not infer its payload from another endpoint.
Link to this operationPOST/v1/orgs/{org}/datasets/{ds}/suspendadmin
suspend an active dataset
- Authentication / minimum role
- Bearer credential with admin authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
A response descriptor is not yet generated for this operation. Do not infer its payload from another endpoint.
Link to this operationPUT/v1/orgs/{org}/datasets/{ds}/ignore-wordssteward
replace the org's ignore-words dictionary
- Authentication / minimum role
- Bearer credential with steward authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds
{
"type": "object",
"properties": {
"rows": {
"type": "array",
"items": {
"type": "object",
"properties": {
"word": {
"type": "string"
},
"dictionary": {
"type": "string"
}
},
"required": [
"word",
"dictionary"
],
"additionalProperties": false
}
}
},
"required": [
"rows"
],
"additionalProperties": false
}A response descriptor is not yet generated for this operation. Do not infer its payload from another endpoint.
Link to this operationPUT/v1/orgs/{org}/datasets/{ds}/lexiconsteward
replace the org's nickname lexicon
- Authentication / minimum role
- Bearer credential with steward authority. Organization routes also enforce organization scope.
- Path parameters
- org, ds
{
"type": "object",
"properties": {
"pairs": {
"type": "array",
"items": {
"type": "object",
"properties": {
"variant_a": {
"type": "string"
},
"variant_b": {
"type": "string"
}
},
"required": [
"variant_a",
"variant_b"
],
"additionalProperties": false
}
}
},
"required": [
"pairs"
],
"additionalProperties": false
}A response descriptor is not yet generated for this operation. Do not infer its payload from another endpoint.
Link to this operationOrganization operations
14 operations. Expand an entry for its path parameters, declared request shape, and response envelope.
DELETE/v1/orgs/{org}/connections/{connection_id}admin
retire a Salesforce connection
- Authentication / minimum role
- Bearer credential with admin authority. Organization routes also enforce organization scope.
- Path parameters
- org, connection_id
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
A response descriptor is not yet generated for this operation. Do not infer its payload from another endpoint.
Link to this operationDELETE/v1/orgs/{org}/webhooks/{webhook_id}admin
delete a webhook
- Authentication / minimum role
- Bearer credential with admin authority. Organization routes also enforce organization scope.
- Path parameters
- org, webhook_id
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
A response descriptor is not yet generated for this operation. Do not infer its payload from another endpoint.
Link to this operationGET/v1/orgs/{org}viewer
an org's detail
- Authentication / minimum role
- Bearer credential with viewer authority. Organization routes also enforce organization scope.
- Path parameters
- org
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
{
"envelope": "record",
"keys": [
"id",
"name",
"state",
"active_config_version",
"drop_root",
"resources"
]
}GET/v1/orgs/{org}/auditadmin
an org's audit feed
- Authentication / minimum role
- Bearer credential with admin authority. Organization routes also enforce organization scope.
- Path parameters
- org
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
{
"envelope": "bare"
}GET/v1/orgs/{org}/connectionsviewer
list an org's active Salesforce connections
- Authentication / minimum role
- Bearer credential with viewer authority. Organization routes also enforce organization scope.
- Path parameters
- org
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
{
"envelope": "bare"
}GET/v1/orgs/{org}/datasetsviewer
an org's datasets
- Authentication / minimum role
- Bearer credential with viewer authority. Organization routes also enforce organization scope.
- Path parameters
- org
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
{
"envelope": "bare"
}GET/v1/orgs/{org}/webhooksviewer
list an org's active webhooks
- Authentication / minimum role
- Bearer credential with viewer authority. Organization routes also enforce organization scope.
- Path parameters
- org
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
{
"envelope": "bare"
}GET/v1/orgs/{org}/webhooks/deliveriesviewer
the delivery log
- Authentication / minimum role
- Bearer credential with viewer authority. Organization routes also enforce organization scope.
- Path parameters
- org
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
{
"envelope": "wrapped",
"key": "deliveries"
}GET/v1/orgs/{org}/webhooks/eventsviewer
the event types this system can emit
- Authentication / minimum role
- Bearer credential with viewer authority. Organization routes also enforce organization scope.
- Path parameters
- org
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
{
"envelope": "wrapped",
"key": "events"
}POST/v1/orgs/{org}/connectionsadmin
register a Salesforce connection
- Authentication / minimum role
- Bearer credential with admin authority. Organization routes also enforce organization scope.
- Path parameters
- org
{
"type": "object",
"properties": {
"name": {
"type": "string"
},
"instance_url": {
"type": "string"
},
"client_id": {
"type": "string"
},
"client_secret": {
"type": "string"
},
"auth_kind": {
"type": "string"
},
"api_version": {
"type": "string"
}
},
"required": [
"name",
"instance_url",
"client_id",
"client_secret"
],
"additionalProperties": false
}A response descriptor is not yet generated for this operation. Do not infer its payload from another endpoint.
Link to this operationPOST/v1/orgs/{org}/webhooksadmin
register an outbound webhook
- Authentication / minimum role
- Bearer credential with admin authority. Organization routes also enforce organization scope.
- Path parameters
- org
{
"type": "object",
"properties": {
"url": {
"type": "string"
},
"events": {
"type": "array",
"items": {
"type": "string"
}
},
"secret": {
"type": "string"
}
},
"required": [
"url"
],
"additionalProperties": false
}A response descriptor is not yet generated for this operation. Do not infer its payload from another endpoint.
Link to this operationOperator and service operations
13 operations. Expand an entry for its path parameters, declared request shape, and response envelope.
DELETE/v1/orgs/{org}/api-keys/{key_id}operator
revoke an API key, org-scoped and idempotent
- Authentication / minimum role
- Bearer credential with operator authority. Organization routes also enforce organization scope.
- Path parameters
- org, key_id
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
A response descriptor is not yet generated for this operation. Do not infer its payload from another endpoint.
Link to this operationGET/healthzpublic
liveness
- Authentication / minimum role
- No bearer credential required.
- Path parameters
- None
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
{
"envelope": "wrapped",
"key": "status"
}GET/readyzpublic
readiness
- Authentication / minimum role
- No bearer credential required.
- Path parameters
- None
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
{
"envelope": "record",
"keys": [
"ready",
"store",
"reason"
]
}GET/v1/auditoperator
the cross-tenant audit feed
- Authentication / minimum role
- Bearer credential with operator authority. Organization routes also enforce organization scope.
- Path parameters
- None
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
{
"envelope": "bare"
}GET/v1/jobsoperator
the cross-org queue view
- Authentication / minimum role
- Bearer credential with operator authority. Organization routes also enforce organization scope.
- Path parameters
- None
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
{
"envelope": "bare"
}GET/v1/orgsoperator
list all orgs
- Authentication / minimum role
- Bearer credential with operator authority. Organization routes also enforce organization scope.
- Path parameters
- None
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
{
"envelope": "bare"
}PATCH/v1/orgs/{org}/resourcesoperator
set an org's DuckDB parallelism knobs
- Authentication / minimum role
- Bearer credential with operator authority. Organization routes also enforce organization scope.
- Path parameters
- org
{
"type": "object",
"properties": {
"duckdb_threads": {
"type": "integer"
},
"duckdb_memory_limit": {
"type": "string"
}
},
"required": [],
"additionalProperties": false
}A response descriptor is not yet generated for this operation. Do not infer its payload from another endpoint.
Link to this operationPOST/v1/emailoperator
send one transactional email
- Authentication / minimum role
- Bearer credential with operator authority. Organization routes also enforce organization scope.
- Path parameters
- None
{
"type": "object"
}A response descriptor is not yet generated for this operation. Do not infer its payload from another endpoint.
Link to this operationPOST/v1/orgsoperator
create an org
- Authentication / minimum role
- Bearer credential with operator authority. Organization routes also enforce organization scope.
- Path parameters
- None
{
"type": "object",
"properties": {
"name": {
"type": "string"
},
"config_path": {
"type": "string"
},
"env": {
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"drop_root": {
"type": "string"
},
"s3_ingest_bucket": {
"type": "string"
},
"s3_ingest_prefix": {
"type": "string"
}
},
"required": [
"name"
],
"additionalProperties": false
}A response descriptor is not yet generated for this operation. Do not infer its payload from another endpoint.
Link to this operationPOST/v1/orgs/{org}/api-keysoperator
mint an API key for an org, returning the plaintext ONCE
- Authentication / minimum role
- Bearer credential with operator authority. Organization routes also enforce organization scope.
- Path parameters
- org
{
"type": "object",
"properties": {
"role": {
"type": "string"
}
},
"required": [
"role"
],
"additionalProperties": false
}A response descriptor is not yet generated for this operation. Do not infer its payload from another endpoint.
Link to this operationPOST/v1/orgs/{org}/datasetsoperator
create a dataset
- Authentication / minimum role
- Bearer credential with operator authority. Organization routes also enforce organization scope.
- Path parameters
- org
{
"type": "object",
"properties": {
"name": {
"type": "string"
},
"display_name": {
"type": "string"
},
"entity_type": {
"type": "string"
},
"config_path": {
"type": "string"
},
"env": {
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"drop_root": {
"type": "string"
},
"s3_ingest_bucket": {
"type": "string"
},
"s3_ingest_prefix": {
"type": "string"
}
},
"required": [
"name"
],
"additionalProperties": false
}A response descriptor is not yet generated for this operation. Do not infer its payload from another endpoint.
Link to this operationPOST/v1/orgs/{org}/resumeoperator
resume a suspended org
- Authentication / minimum role
- Bearer credential with operator authority. Organization routes also enforce organization scope.
- Path parameters
- org
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
A response descriptor is not yet generated for this operation. Do not infer its payload from another endpoint.
Link to this operationPOST/v1/orgs/{org}/suspendoperator
suspend an active org
- Authentication / minimum role
- Bearer credential with operator authority. Organization routes also enforce organization scope.
- Path parameters
- org
No JSON body schema is declared. Check the workflow guide for multipart uploads and operation-specific requirements.
A response descriptor is not yet generated for this operation. Do not infer its payload from another endpoint.
Link to this operationSchema reference
The generated OpenAPI 3.1.0 document currently contains component schemas and no operation definitions. It cannot yet generate a complete working customer client. The reference above is derived separately from the routed implementation.
These schemas describe registered wire types. A response envelope may wrap one or more records; it is not interchangeable with the record’s schema.
AcctGoldenLineage
{
"type": "object",
"description": "Per-attribute survivorship provenance for a resolved account: which record each surviving value came from.",
"required": [
"id",
"entity_id",
"attribute",
"record_key",
"source_system",
"source_record_id",
"rule",
"survivorship_version",
"created_at",
"updated_at"
],
"properties": {
"attribute": {
"type": "string",
"description": "The survivable attribute decided (e.g. company_name, domain, address)."
},
"created_at": {
"type": "string",
"format": "date-time",
"description": "Run-logical creation time (the assembling run's clock; the mart is rebuilt whole)."
},
"entity_id": {
"type": "string",
"description": "The resolved account this attribute decision belongs to."
},
"id": {
"type": "string",
"description": "Content-derived row id: sha256('acct_golden_lineage:' || entity_id || ':' || attribute)."
},
"record_key": {
"type": "string",
"description": "The source record that won the attribute."
},
"rule": {
"type": "string",
"description": "The survivorship rule that selected this value."
},
"source_record_id": {
"type": "string",
"description": "Source-native id of the winning record."
},
"source_system": {
"type": "string",
"description": "Source system of the winning record."
},
"survivorship_version": {
"type": "string",
"description": "Survivorship policy version that produced this row."
},
"updated_at": {
"type": "string",
"format": "date-time",
"description": "Run-logical last-write time (equals created_at; the mart is rebuilt whole)."
}
}
}AcctGoldenRecord
{
"type": "object",
"description": "One resolved account/organization: the surviving value per attribute, at a snapshot.",
"required": [
"id",
"survivorship_version",
"assembled_at",
"created_at",
"updated_at"
],
"properties": {
"addr_city": {
"type": [
"string",
"null"
],
"description": "Surviving city of the address."
},
"addr_postal": {
"type": [
"string",
"null"
],
"description": "Surviving postal code of the address."
},
"addr_region": {
"type": [
"string",
"null"
],
"description": "Surviving region/state of the address."
},
"addr_street": {
"type": [
"string",
"null"
],
"description": "Surviving street of the address."
},
"assembled_at": {
"type": "string",
"format": "date-time",
"description": "Assembly time of this row (volatile)."
},
"company_name": {
"type": [
"string",
"null"
],
"description": "Surviving company name."
},
"created_at": {
"type": "string",
"format": "date-time",
"description": "Run-logical creation time (the assembling run's clock; the mart is rebuilt whole)."
},
"domain": {
"type": [
"string",
"null"
],
"description": "Surviving web domain."
},
"id": {
"type": "string",
"description": "Persistent entity id (deterministic UUIDv7, minted by reconcile); the survivorship key."
},
"metadata": {
"description": "Surviving opaque per-source metadata object."
},
"phone_e164": {
"type": [
"string",
"null"
],
"description": "Surviving phone number in E.164 form."
},
"survivorship_version": {
"type": "string",
"description": "Survivorship policy version that produced this row."
},
"updated_at": {
"type": "string",
"format": "date-time",
"description": "Run-logical last-write time (equals created_at; the mart is rebuilt whole)."
}
}
}ApiKey
{
"type": "object",
"description": "An org-scoped API key: its role and the at-rest hash of the secret.",
"required": [
"id",
"org_id",
"role",
"created_at",
"updated_at"
],
"properties": {
"created_at": {
"type": "string",
"format": "date-time",
"description": "When the key was issued."
},
"id": {
"type": "string",
"description": "The key's unique id (UUIDv7, minted at issue)."
},
"org_id": {
"type": "string",
"description": "The tenant the key authenticates."
},
"revoked_at": {
"type": [
"string",
"null"
],
"format": "date-time",
"description": "When the key was revoked, if it has been."
},
"role": {
"type": "string",
"description": "The role the key grants."
},
"updated_at": {
"type": "string",
"format": "date-time",
"description": "Wall-clock last-write time (database default; advanced by mutations once the entity migrates)."
}
}
}AuditLog
{
"type": "object",
"description": "The append-only audit ledger: one row per authenticated mutation (actor, action, optional org scope, and structured detail). Append-only constrains writes, not lifetime: rows past the deployment retention window (ER_AUDIT_RETENTION_DAYS, floor 400 days per the infra D-RETENTION decision) are retired by the dispatcher's retention sweep through delete/purge_expired.",
"required": [
"id",
"at",
"actor",
"action",
"detail",
"created_at",
"updated_at"
],
"properties": {
"action": {
"type": "string",
"description": "The action name (e.g. steward.mass_update)."
},
"actor": {
"type": "string",
"description": "The principal that performed the action (the signed-in user's email, or an API key id)."
},
"at": {
"type": "string",
"format": "date-time",
"description": "When the audited action occurred."
},
"created_at": {
"type": "string",
"format": "date-time",
"description": "Wall-clock creation time (database default; `at` remains the domain event stamp)."
},
"dataset": {
"type": [
"string",
"null"
],
"description": "The dataset the action concerned, by name, when it concerned one — context, like `org`, not a foreign key (this ledger outlives both)."
},
"detail": {
"description": "Structured detail for the action."
},
"id": {
"type": "integer",
"format": "int64",
"description": "Monotonic ledger id (bigserial); the primary key."
},
"org": {
"type": [
"string",
"null"
],
"description": "The tenant the action applies to, if the action is org-scoped."
},
"trace_id": {
"type": [
"string",
"null"
],
"description": "The W3C trace id (32 lowercase hex) of the request that caused this row, when the caller sent one. The JOIN KEY to the span store: spans carry `trace_id`, so this is what turns `which rows did this session write` into `and here is every SQL statement each one ran`. Stored as the bare id rather than the full `traceparent`, because the parent span id is per-hop and would not join. NULL for an unpropagated or non-HTTP caller — a CLI, the dispatcher's own bookkeeping — which is a real and permanent case, not a gap to backfill."
},
"updated_at": {
"type": "string",
"format": "date-time",
"description": "Wall-clock last-write time (equals created_at; audit rows are append-only)."
}
}
}CandidateKey
{
"type": "object",
"description": "What an equi-join on one column would cost as a blocking key, measured against the corpus rather than inferred from a model. Blocking decides the entire cost of a run, and it is chosen before anything is trained — so the question has to be answerable with no model at all, which is why these numbers come from a GROUP BY over the data and not from a settings document.",
"required": [
"id",
"profile_run_id",
"key_columns",
"row_count",
"covered_rows",
"distinct_values",
"expected_pairs",
"largest_block_pairs",
"largest_block_rows",
"entropy_bits",
"pair_loss_from_nulls",
"created_at",
"updated_at"
],
"properties": {
"covered_rows": {
"type": "integer",
"format": "int64",
"description": "Rows where every key column is non-null — the only rows this key can block, because an equality is never true of a NULL."
},
"created_at": {
"type": "string",
"format": "date-time",
"description": "Run-logical creation time."
},
"distinct_values": {
"type": "integer",
"format": "int64",
"description": "Distinct key values among the covered rows. The block count: more blocks of fewer rows each is what makes a key cheap."
},
"entropy_bits": {
"type": "number",
"format": "double",
"description": "Shannon entropy of the key's value distribution, in bits. In bits so it is directly comparable with the compiler's match-weight scale, which is also in bits — one unit across both halves of the system."
},
"expected_pairs": {
"type": "integer",
"format": "int64",
"description": "Pairs an equi-join on this key generates, exactly: the sum of C(n, 2) over the value groups. For a rule used FIRST, with nothing preceding it to dedup against, this equals the marginal comparison count a trained model's own counter reports — which is what the engine's golden test asserts, so the cheap path cannot drift from the expensive one."
},
"id": {
"type": "string",
"description": "Content-derived row id: sha256('candidate_keys:' || profile_run_id || ':' || key_columns)."
},
"key_columns": {
"type": "string",
"description": "The key's columns, joined by the unit-separator character (chr(31)) — one name for a single-column key, several for a composite. A delimiter rather than a list because this column is in the natural key, and DuckLake has no list equality to MERGE on; chr(31) specifically because it cannot occur in a column name."
},
"largest_block_pairs": {
"type": "integer",
"format": "int64",
"description": "Pairs contributed by the single largest block. The number that catches a key which looks affordable in total and is actually dominated by one value — the classic shape being a placeholder, where every record with a blank-but-present field lands in one enormous block."
},
"largest_block_rows": {
"type": "integer",
"format": "int64",
"description": "Rows in that largest block."
},
"pair_loss_from_nulls": {
"type": "number",
"format": "double",
"description": "The share of ALL corpus pairs this key can never reach because one endpoint or the other is NULL: `1 - (covered_rows / rows)^2`. The square is the part that surprises people — a key on a column that is 60% populated reaches only 36% of pairs — and it is why a cheap key is so often cheap for the wrong reason. Stored beside the cost so the trade is visible rather than implied."
},
"profile_run_id": {
"type": "string",
"description": "The profile run that measured this key. Named for the relation it points at, per the foreign-key convention; no `references` is declared because DuckLake enforces no foreign keys (V11)."
},
"row_count": {
"type": "integer",
"format": "int64",
"description": "Rows in the profiled corpus, carried so `expected_pairs` can be read as a share without a second lookup. Named row_count rather than rows because `rows` is reserved in DuckDB and a column called that cannot be selected unquoted."
},
"updated_at": {
"type": "string",
"format": "date-time",
"description": "Run-logical last-write time."
}
}
}ColumnProfile
{
"type": "object",
"description": "One column's shape within one profile run: how full it is, how many distinct values it holds, how long its values are, what types they parse as, and its most frequent values. One row per column rather than per value, because the lake schema language cannot express a partition (there is no partition_by field) and a per-value table would grow with the corpus instead of with the schema.",
"required": [
"id",
"profile_run_id",
"column_name",
"row_count",
"total_row_count",
"non_null_count",
"blank_count",
"distinct_approx",
"cast_bigint",
"cast_double",
"cast_date",
"cast_timestamp",
"cast_boolean",
"created_at",
"updated_at"
],
"properties": {
"blank_count": {
"type": "integer",
"format": "int64",
"description": "Rows where the column is present but empty once trimmed. Counted apart from NULL because ingest lands every delivered value as a JSON string, so an empty cell arrives as '' and is not NULL — a fill rate treating the two alike reports a column as populated when every value in it is blank."
},
"cast_bigint": {
"type": "integer",
"format": "int64",
"description": "Non-null values that parse as an integer."
},
"cast_boolean": {
"type": "integer",
"format": "int64",
"description": "Non-null values that parse as a boolean."
},
"cast_date": {
"type": "integer",
"format": "int64",
"description": "Non-null values that parse as a date. This is the whole of type detection here: ingest stores every delivered value as text, so the declared type says nothing about content and conformance is the only evidence of what a column actually holds."
},
"cast_double": {
"type": "integer",
"format": "int64",
"description": "Non-null values that parse as a double."
},
"cast_timestamp": {
"type": "integer",
"format": "int64",
"description": "Non-null values that parse as a timestamp."
},
"column_name": {
"type": "string",
"description": "The profiled column, as named in the corpus stage."
},
"created_at": {
"type": "string",
"format": "date-time",
"description": "Run-logical creation time."
},
"distinct_approx": {
"type": "integer",
"format": "int64",
"description": "HyperLogLog estimate of distinct values. Always present because it is cheap, and always approximate: measured on a fixture of 1000 genuinely distinct ids it returns 978, so it is wrong in both directions and must never settle a uniqueness question on its own."
},
"distinct_exact": {
"type": [
"integer",
"null"
],
"format": "int64",
"description": "Exact distinct count, NULL when it was not requested. The expensive one (a per-column sort), and the only one a uniqueness verdict may be read from."
},
"distinct_normalized": {
"type": [
"integer",
"null"
],
"format": "int64",
"description": "Exact distinct count after lowercasing, trimming and collapsing internal whitespace; NULL when not requested. Materially below distinct_exact is the signal that a column needs standardizing before it is compared, which is otherwise invisible — the raw count looks healthy precisely because the variants are counted as distinct values."
},
"entropy_bits": {
"type": [
"number",
"null"
],
"format": "double",
"description": "Shannon entropy of the value distribution, in bits. Reported in bits so it is directly comparable with the compiler's match-weight scale, which is also in bits — one unit across both halves of the system. A low value means one or two values dominate, which makes the column a poor blocking key however full it is."
},
"id": {
"type": "string",
"description": "Content-derived row id: sha256('column_profiles:' || profile_run_id || ':' || column_name)."
},
"len_avg": {
"type": [
"number",
"null"
],
"format": "double",
"description": "Mean trimmed value length."
},
"len_max": {
"type": [
"integer",
"null"
],
"format": "int64",
"description": "Longest trimmed value length. A value at a round number here is the signature of upstream truncation."
},
"len_min": {
"type": [
"integer",
"null"
],
"format": "int64",
"description": "Shortest trimmed value length. NULL for an all-NULL column, where a length has no meaning."
},
"len_p50": {
"type": [
"integer",
"null"
],
"format": "int64",
"description": "Approximate median trimmed length."
},
"len_p95": {
"type": [
"integer",
"null"
],
"format": "int64",
"description": "Approximate 95th-percentile trimmed length. Read against len_max it separates a long tail from a single outlier."
},
"lex_max": {
"type": [
"string",
"null"
],
"description": "Lexically largest trimmed value."
},
"lex_min": {
"type": [
"string",
"null"
],
"description": "Lexically smallest trimmed value."
},
"non_null_count": {
"type": "integer",
"format": "int64",
"description": "Rows where the column is not NULL."
},
"num_avg": {
"type": [
"number",
"null"
],
"format": "double",
"description": "Mean of the values that parse as numbers."
},
"num_max": {
"type": [
"number",
"null"
],
"format": "double",
"description": "Largest value that parses as a number, NULL when none does."
},
"num_min": {
"type": [
"number",
"null"
],
"format": "double",
"description": "Smallest value that parses as a number, NULL when none does."
},
"num_std": {
"type": [
"number",
"null"
],
"format": "double",
"description": "Sample standard deviation of the values that parse as numbers. NULL for fewer than two such values, where it is undefined rather than zero."
},
"profile_run_id": {
"type": "string",
"description": "The profile run this column belongs to. Named for the relation it points at, per the foreign-key convention, but no `references` is declared because DuckLake enforces no foreign keys (V11) and declaring one would claim a guarantee the lake does not provide."
},
"row_count": {
"type": "integer",
"format": "int64",
"description": "Rows read for this column (the sampled count when sampling was on)."
},
"top_values": {
"description": "The most frequent values with their counts and shares, bounded to a small k. Bounded because this is a per-column row: an unbounded list would put the corpus inside the profile. NOTE for consumers: these are REAL VALUES — live emails and phone numbers — so they are the one field here that carries personal data and must be role-gated before display and never sent to a model."
},
"total_row_count": {
"type": "integer",
"format": "int64",
"description": "Rows in the corpus whether or not they were sampled, so a sampled figure can be scaled and labelled honestly."
},
"updated_at": {
"type": "string",
"format": "date-time",
"description": "Run-logical last-write time."
}
}
}ConfigVersion
{
"type": "object",
"description": "A versioned config document for a tenant: its YAML, hash and publish state.",
"required": [
"id",
"org_id",
"dataset_id",
"version",
"yaml",
"config_hash",
"state",
"created_by",
"created_at",
"updated_at"
],
"properties": {
"config_hash": {
"type": "string",
"description": "Hash of the canonicalized config."
},
"created_at": {
"type": "string",
"format": "date-time",
"description": "When the version was created."
},
"created_by": {
"type": "string",
"description": "Principal that created the version."
},
"dataset_id": {
"type": "string",
"description": "The dataset this config version belongs to. Part of the natural key: rows belong to a dataset, not to the org at large."
},
"id": {
"type": "string",
"description": "The version row's unique id (UUIDv7, minted at draft)."
},
"org_id": {
"type": "string",
"description": "The tenant this config version belongs to."
},
"published_at": {
"type": [
"string",
"null"
],
"format": "date-time",
"description": "When the version was published, if it has been."
},
"state": {
"type": "string",
"description": "Whether the version is a draft or published."
},
"tier": {
"type": [
"string",
"null"
],
"description": "Optional service tier label."
},
"updated_at": {
"type": "string",
"format": "date-time",
"description": "Wall-clock last-write time (database default; advanced by mutations once the entity migrates)."
},
"version": {
"type": "integer",
"format": "int64",
"description": "The monotonic version number within the tenant."
},
"yaml": {
"type": "string",
"description": "The config document source."
}
}
}Dataset
{
"type": "object",
"description": "One of a tenant's resolution domains: its own lake location, config pointer, entity type and lifecycle state. The lake env points at a DuckLake catalog of its own (a METADATA_SCHEMA inside the org's metadata database, or a file catalog locally), so two datasets never share tables.",
"required": [
"id",
"org_id",
"name",
"entity_type",
"config_path",
"env",
"state",
"created_at",
"updated_at"
],
"properties": {
"active_config_version": {
"type": [
"integer",
"null"
],
"format": "int64",
"description": "The currently published config version, if any."
},
"config_path": {
"type": "string",
"description": "Path to the dataset's config document."
},
"created_at": {
"type": "string",
"format": "date-time",
"description": "When the dataset was created."
},
"display_name": {
"type": [
"string",
"null"
],
"description": "Optional human label; the name stays the stable routing handle."
},
"drop_root": {
"type": [
"string",
"null"
],
"description": "Delivery landing directory; one `<source>.csv` per config source."
},
"entity_type": {
"type": "string",
"description": "The one entity type this dataset's lake resolves. Fixed at creation: the lake's std/golden tables are per-type, so changing it would orphan the corpus. Publish refuses a config whose entity_type differs."
},
"env": {
"description": "Lake connection env (catalog, catalog schema, data path, config/model/TF/lexicon paths). Handed to the engine verbatim; the derived location keys always win over operator extras."
},
"id": {
"type": "string",
"description": "The dataset's unique id (UUIDv7, minted at creation)."
},
"name": {
"type": "string",
"description": "The dataset's name, unique within its org (the routing handle; URLs are name-based, same slug grammar as an org name). The migration sweep names every existing org's one dataset `default`."
},
"org_id": {
"type": "string",
"description": "The tenant this dataset belongs to."
},
"s3_ingest_bucket": {
"type": [
"string",
"null"
],
"description": "Bucket the auto-ingest poller watches for this dataset. Null means auto-ingest is off — the feature has to be opted into, because a poller that starts reading a bucket nobody pointed at it would be ingesting data on its own initiative."
},
"s3_ingest_prefix": {
"type": [
"string",
"null"
],
"description": "Key prefix under `s3_ingest_bucket`, with one directory per config source beneath it. A column rather than a key in `env` deliberately, for the same reason as the org's: `env` is handed to the engine subprocess, while this is read by the control plane itself."
},
"state": {
"type": "string",
"description": "Dataset lifecycle state. The org's own state gates the whole tenant above this."
},
"updated_at": {
"type": "string",
"format": "date-time",
"description": "Wall-clock last-write time (database default; advanced by mutations once the entity migrates)."
}
}
}EntityLink
{
"type": "object",
"description": "A relationship between two resolved entities that is NOT a merge: a household, a corporate hierarchy, a 'these are related but distinct' note. The product has one answer to 'these two records belong together' — merge them — and that answer is wrong for a husband and wife at one address, or a subsidiary and its parent. Merging them loses the distinction and no later run can recover it; refusing to record anything loses the relationship. A link records it without collapsing either side.",
"required": [
"id",
"org_id",
"dataset_id",
"parent_entity_id",
"child_entity_id",
"kind",
"origin",
"created_by",
"created_at",
"updated_at"
],
"properties": {
"child_entity_id": {
"type": "string",
"description": "The entity on the member side — the person in the household, the subsidiary."
},
"created_at": {
"type": "string",
"format": "date-time",
"description": "When the link was created."
},
"created_by": {
"type": "string",
"description": "The actor that created the link."
},
"dataset_id": {
"type": "string",
"description": "The dataset whose entities this link relates — entity ids are lake-local."
},
"id": {
"type": "string",
"description": "The link's unique id (UUIDv7, minted by the application)."
},
"kind": {
"type": "string",
"description": "What the relationship is. A closed set rather than free text because the whole value of a link is that something downstream can act on it, and an export or a rule cannot act on a spelling. `related` is the deliberate escape hatch for a real relationship that is neither of the other two — it says 'these are connected, do not merge them' without claiming to know how."
},
"note": {
"type": [
"string",
"null"
],
"description": "Optional free text — why this link exists, in the words of whoever made it."
},
"org_id": {
"type": "string",
"description": "The tenant. Every read is scoped by it."
},
"origin": {
"type": "string",
"description": "Where the link came from. Kept apart for the reason `pair_labels.origin` is: a steward's judgement and a model's suggestion are different evidence, and a surface that cannot tell them apart will present a guess as a decision. `llm` has no producer until an adjudicator can propose a link; it is declared here because the column's accepted values are the contract that producer will be written against."
},
"parent_entity_id": {
"type": "string",
"description": "The entity on the owning side — the household, the parent company. Deliberately NOT a foreign key, for the reason `taggings.subject_id` gives: an entity lives in the LAKE and this table is Postgres, so a database-level reference would point at a row this store does not own. The id is stable across runs because reconcile carries ids forward by membership overlap (INV-PERM) rather than re-deriving them, and an entity that loses that contest records `merged_into` — so a link survives its entity gaining members, and a merged-away side is followable rather than dangling."
},
"updated_at": {
"type": "string",
"format": "date-time",
"description": "When it was last changed."
}
}
}GoldenLineage
{
"type": "object",
"description": "Per-attribute survivorship provenance: which record each surviving golden value came from.",
"required": [
"id",
"entity_id",
"attribute",
"record_key",
"source_system",
"source_record_id",
"rule",
"survivorship_version",
"created_at",
"updated_at"
],
"properties": {
"attribute": {
"type": "string",
"description": "The survivable attribute decided (e.g. given_name, email, address)."
},
"created_at": {
"type": "string",
"format": "date-time",
"description": "Run-logical creation time (the assembling run's clock; the mart is rebuilt whole)."
},
"entity_id": {
"type": "string",
"description": "The resolved entity this attribute decision belongs to."
},
"id": {
"type": "string",
"description": "Content-derived row id: sha256('golden_lineage:' || entity_id || ':' || attribute)."
},
"record_key": {
"type": "string",
"description": "The source record that won the attribute."
},
"rule": {
"type": "string",
"description": "The survivorship rule that selected this value."
},
"source_record_id": {
"type": "string",
"description": "Source-native id of the winning record."
},
"source_system": {
"type": "string",
"description": "Source system of the winning record."
},
"survivorship_version": {
"type": "string",
"description": "Survivorship policy version that produced this row."
},
"updated_at": {
"type": "string",
"format": "date-time",
"description": "Run-logical last-write time (equals created_at; the mart is rebuilt whole)."
}
}
}GoldenRecord
{
"type": "object",
"description": "One resolved person: the surviving value per attribute, at a snapshot.",
"required": [
"id",
"survivorship_version",
"assembled_at",
"created_at",
"updated_at"
],
"properties": {
"addr_city": {
"type": [
"string",
"null"
],
"description": "Surviving city of the address."
},
"addr_number": {
"type": [
"string",
"null"
],
"description": "Surviving street number of the address."
},
"addr_postal": {
"type": [
"string",
"null"
],
"description": "Surviving postal code of the address."
},
"addr_region": {
"type": [
"string",
"null"
],
"description": "Surviving region/state of the address."
},
"addr_street": {
"type": [
"string",
"null"
],
"description": "Surviving street name of the address."
},
"addr_unit": {
"type": [
"string",
"null"
],
"description": "Surviving unit/apartment of the address."
},
"assembled_at": {
"type": "string",
"format": "date-time",
"description": "Assembly time of this row (volatile; excluded from determinism comparisons)."
},
"birth_date": {
"type": [
"string",
"null"
],
"format": "date",
"description": "Surviving birth date."
},
"created_at": {
"type": "string",
"format": "date-time",
"description": "Run-logical creation time (the assembling run's clock; the mart is rebuilt whole)."
},
"email": {
"type": [
"string",
"null"
],
"description": "Surviving email address."
},
"family_name": {
"type": [
"string",
"null"
],
"description": "Surviving family name."
},
"given_name": {
"type": [
"string",
"null"
],
"description": "Surviving given name."
},
"id": {
"type": "string",
"description": "Persistent entity id (deterministic UUIDv7, minted by reconcile); the survivorship key."
},
"metadata": {
"description": "Surviving opaque per-source metadata object."
},
"phone_e164": {
"type": [
"string",
"null"
],
"description": "Surviving phone number in E.164 form."
},
"survivorship_version": {
"type": "string",
"description": "Survivorship policy version that produced this row."
},
"updated_at": {
"type": "string",
"format": "date-time",
"description": "Run-logical last-write time (equals created_at; the mart is rebuilt whole)."
}
}
}IngestBatch
{
"type": "object",
"description": "One delivery receipt (S4.1): per-source landing counts for a batch, including tombstones and resurrections.",
"required": [
"id",
"run_id",
"source_system",
"path",
"new_count",
"changed_count",
"unchanged_count",
"tombstone_count",
"resurrected_count",
"full_refresh_keys",
"created_at",
"updated_at"
],
"properties": {
"changed_count": {
"type": "integer",
"format": "int64",
"description": "Rows superseding a key with new content."
},
"created_at": {
"type": "string",
"format": "date-time",
"description": "Creation stamp (the run's logical timestamp)."
},
"full_refresh_keys": {
"type": "boolean",
"description": "Whether the delivery tombstoned omitted keys."
},
"id": {
"type": "string",
"description": "The delivery batch's unique id (caller-supplied per delivery)."
},
"matched_count": {
"type": [
"integer",
"null"
],
"format": "int64",
"description": "Screening (E9b): delivered records that joined an existing entity — their best active score reached `thresholds.auto_merge`. NULL means the delivery was never screened, which is the honest answer for a run that scored nothing (a correction pass, or a rebuild with `skip_ingest`); 0 means it was screened and nothing matched."
},
"new_count": {
"type": "integer",
"format": "int64",
"description": "Rows landing a brand-new key."
},
"path": {
"type": "string",
"description": "The delivered file's path."
},
"resurrected_count": {
"type": "integer",
"format": "int64",
"description": "Previously tombstoned keys that returned."
},
"review_count": {
"type": [
"integer",
"null"
],
"format": "int64",
"description": "Screening (E9b): delivered records whose best active score landed in the gray band — at or above `review_low` but below `auto_merge`. These are the ones a steward has to decide."
},
"run_id": {
"type": "string",
"description": "The run that wrote this row."
},
"screened_at": {
"type": [
"string",
"null"
],
"format": "date-time",
"description": "When the delivery was screened, NULL if it was not. Separate from the counts so that `screened with everything unmatched` (counts 0/0/N) is distinguishable from `never screened` (all NULL) without reading three columns."
},
"source_system": {
"type": "string",
"description": "The delivering source system."
},
"tombstone_count": {
"type": "integer",
"format": "int64",
"description": "Keys tombstoned by a full refresh."
},
"unchanged_count": {
"type": "integer",
"format": "int64",
"description": "Rows matching the key's current content."
},
"unmatched_count": {
"type": [
"integer",
"null"
],
"format": "int64",
"description": "Screening (E9b): delivered records with no active score reaching `review_low` — genuinely new as far as the model can tell."
},
"updated_at": {
"type": "string",
"format": "date-time",
"description": "Run-logical last-write time. Receipts were written once until E9b; the screening pass now updates the row after the match stage, because the verdicts do not exist until the run has scored."
}
}
}Job
{
"type": "object",
"description": "A unit of work on the dispatcher's queue: its kind, params, lifecycle state and retry bookkeeping.",
"required": [
"id",
"org_id",
"kind",
"params",
"state",
"priority",
"attempt",
"max_attempts",
"created_at",
"updated_at"
],
"properties": {
"attempt": {
"type": "integer",
"format": "int64",
"description": "Attempts made so far."
},
"clear_number": {
"type": [
"integer",
"null"
],
"format": "int64",
"description": "Incremented by every clear; fences readiness verdicts composed before the clear. Read as COALESCE(clear_number, 0)."
},
"created_at": {
"type": "string",
"format": "date-time",
"description": "When the job was enqueued."
},
"created_by": {
"type": [
"string",
"null"
],
"description": "Principal that created the job."
},
"dataset_id": {
"type": [
"string",
"null"
],
"description": "The dataset this job runs against. NULL only for org-level kinds (provision) — every lake-touching job carries it, and the per-dataset writer lock keys on it once the queue is re-scoped."
},
"error_class": {
"type": [
"string",
"null"
],
"description": "Why the job failed, as a class the UI can act on: precondition (an input is missing — expected during onboarding), transient_io (worth retrying), config (the tenant config is wrong), internal (a bug). Null until a failure."
},
"error_detail": {
"type": [
"string",
"null"
],
"description": "The failure's human text, already chain-flattened. Kept beside error_class so a steward sees the reason without reading pod logs."
},
"finished_at": {
"type": [
"string",
"null"
],
"format": "date-time",
"description": "When the job finished."
},
"id": {
"type": "string",
"description": "The job's unique id (UUIDv7, minted at enqueue)."
},
"idempotency_key": {
"type": [
"string",
"null"
],
"description": "Optional dedup key, unique per org."
},
"image_digest": {
"type": [
"string",
"null"
],
"description": "Image digest the planning dispatcher ran, so a deploy mid-run is legible."
},
"kind": {
"type": "string",
"description": "The job kind (run_all, correct, maintain, train, ...)."
},
"max_attempts": {
"type": "integer",
"format": "int64",
"description": "Vestigial: no statement consults it. It bounded the job-level retry that went with the legacy in-process arm (#645); the live budget is task_instances.max_tries, per attempt."
},
"not_before": {
"type": [
"string",
"null"
],
"format": "date-time",
"description": "Earliest time the job may be claimed. A retry sets it to the backoff deadline."
},
"org_id": {
"type": "string",
"description": "The tenant this job runs for."
},
"owner_epoch": {
"type": [
"string",
"null"
],
"description": "The dispatcher process epoch that planned or adopted the run."
},
"params": {
"description": "Kind-specific parameters."
},
"policy_hash": {
"type": [
"string",
"null"
],
"description": "sha256 over the compiled DAG's per-node policy (retries, backoff, timeout, class, segment); a divergence proceeds with the diff logged."
},
"priority": {
"type": "integer",
"format": "int64",
"description": "Claim priority; higher runs first."
},
"resource_class": {
"type": [
"string",
"null"
],
"description": "Requested runner resource class."
},
"run_id": {
"type": [
"string",
"null"
],
"description": "The run this job produced, once dispatched."
},
"schedule_id": {
"type": [
"string",
"null"
],
"description": "The schedule that enqueued the job, if any."
},
"started_at": {
"type": [
"string",
"null"
],
"format": "date-time",
"description": "When the job started running."
},
"state": {
"type": "string",
"description": "Lifecycle state (queued, dispatching, running, succeeded, failed, canceling, canceled)."
},
"structural_fingerprint": {
"type": [
"string",
"null"
],
"description": "sha256 over the compiled DAG's shape (names, versions, edges, trigger rules), written at planning; a clear or adoption refuses on mismatch (batch-orchestration-design §3.4)."
},
"trace_context": {
"type": [
"string",
"null"
],
"description": "Propagated trace context."
},
"updated_at": {
"type": "string",
"format": "date-time",
"description": "When the job row was last updated."
}
}
}MatchingModel
{
"type": "object",
"description": "An immutable version of a tenant's matching model: the settings document the engine scores against, its hash, provenance and activation state.",
"required": [
"id",
"org_id",
"dataset_id",
"name",
"version",
"entity_type",
"model_json",
"model_hash",
"model_version_label",
"state",
"provenance",
"created_by",
"created_at",
"updated_at"
],
"properties": {
"activated_at": {
"type": [
"string",
"null"
],
"format": "date-time",
"description": "When this version was activated, if it ever was."
},
"created_at": {
"type": "string",
"format": "date-time",
"description": "When the version was created."
},
"created_by": {
"type": "string",
"description": "Principal that created the version."
},
"dataset_id": {
"type": "string",
"description": "The dataset whose corpus this model was trained for."
},
"entity_type": {
"type": "string",
"description": "Which canonical schema the model scores against; a model cannot be activated for a lake of the other entity type."
},
"id": {
"type": "string",
"description": "The version row's unique id (UUIDv7, minted when the version is created)."
},
"model_hash": {
"type": "string",
"description": "SHA-256 of model_json, so a scored row can be tied back to the exact document that produced it."
},
"model_json": {
"type": "string",
"description": "The settings document the engine loads (comparison levels, their SQL, m/u probabilities, blocking rules). Stored as text, not jsonb, so it round-trips byte-exact — model_hash is taken over these bytes and the engine's determinism depends on them."
},
"model_version_label": {
"type": "string",
"description": "The identity stamped onto every row this model scores (match_scores.model_version, runs.model_version). It is NOT the version number: it must equal the model_version the frozen term-frequency snapshot CSV is keyed by, because the TF lookup joins on (model_version, tf_snapshot_id) and a mismatch silently returns no term frequencies — changing a pair's score rather than failing. Seeded from the org's ER_MODEL_VERSION; required when uploading a model, for the same reason."
},
"name": {
"type": "string",
"description": "The model's name within the tenant; versions are monotonic within a name, so one tenant can keep several models (a classic rule model beside a trained one) and switch between them."
},
"org_id": {
"type": "string",
"description": "The tenant this model version belongs to."
},
"provenance": {
"description": "Where this version came from: the seeded starter file, a training run (corpus digest, args, seed), an authored upload, or the version it was derived from."
},
"state": {
"type": "string",
"description": "Draft until activated; exactly one version of a name is active at a time, and activating the next archives the previous. There is deliberately no partial unique index enforcing that: a single UPDATE that moves both rows can transiently violate a non-deferrable unique index even when the end state is legal, so activation is instead one atomic statement that cannot produce two actives, and the active read orders by version so a hypothetical second one could never be served silently."
},
"tf_snapshot_id": {
"type": [
"string",
"null"
],
"description": "The frozen term-frequency snapshot this model scores against, when it has one. Paired with model_version_label by the TF lookup."
},
"updated_at": {
"type": "string",
"format": "date-time",
"description": "Wall-clock last-write time (database default; advanced by mutations once the entity migrates)."
},
"version": {
"type": "integer",
"format": "int64",
"description": "The monotonic version number within (org, name). Versions are immutable: a retrain or a weight override mints the next one rather than editing this."
}
}
}MetricSnapshot
{
"type": "object",
"description": "One run's resolution metrics, kept so the dashboard can show a TREND rather than only a current value. The dashboard has always computed its numbers live from the lake, which means it can say what is true now and nothing about whether that is better or worse than last week — which is the question an operator actually has.",
"required": [
"id",
"run_id",
"captured_at",
"records",
"entities",
"duplicate_records",
"duplicate_groups",
"largest_group",
"review_backlog",
"auto_merge_pairs",
"review_band_pairs",
"created_at",
"updated_at"
],
"properties": {
"auto_merge_pairs": {
"type": "integer",
"format": "int64",
"description": "Active scores at or above the auto-merge threshold."
},
"captured_at": {
"type": "string",
"format": "date-time",
"description": "The run's logical clock, not wall time — so a replayed fixture produces the same snapshot."
},
"created_at": {
"type": "string",
"format": "date-time",
"description": "Run-logical creation time."
},
"duplicate_groups": {
"type": "integer",
"format": "int64",
"description": "Entities with more than one member."
},
"duplicate_records": {
"type": "integer",
"format": "int64",
"description": "Records sitting in an entity with more than one member — the numerator of the duplicate rate. Counting GROUPS instead would call a 5-record cluster and a 2-record cluster the same amount of duplication."
},
"entities": {
"type": "integer",
"format": "int64",
"description": "Entities the run resolved them into."
},
"id": {
"type": "string",
"description": "Content-derived row id: sha256('metric_snapshots:' || run_id)."
},
"largest_group": {
"type": "integer",
"format": "int64",
"description": "Members in the biggest entity. A sudden jump here is the signature of an over-merge, which an average cluster size hides completely."
},
"records": {
"type": "integer",
"format": "int64",
"description": "Records in the standardized corpus."
},
"review_backlog": {
"type": "integer",
"format": "int64",
"description": "Open review items after the run — the work the thresholds are handing to humans."
},
"review_band_pairs": {
"type": "integer",
"format": "int64",
"description": "Active scores in the gray band: scored, not merged. The two together say where the thresholds are actually sitting."
},
"run_id": {
"type": "string",
"description": "The run these metrics describe. One snapshot per run, so a re-run of the same id overwrites rather than double-counting."
},
"updated_at": {
"type": "string",
"format": "date-time",
"description": "Run-logical last-write time."
}
}
}MetricSnapshotSource
{
"type": "object",
"description": "One run's duplicate attribution, per source system. The corpus-wide duplicate rate says a tenant has a problem; it does not say WHERE the problem comes from, and the answer is nearly always one feed. Retained per run beside metric_snapshots for the same reason that table exists: a live number says what is true now and nothing about whether a source is getting better or worse.",
"required": [
"id",
"run_id",
"source_system",
"captured_at",
"records",
"duplicate_records",
"contributed_groups",
"created_at",
"updated_at"
],
"properties": {
"captured_at": {
"type": "string",
"format": "date-time",
"description": "The run's logical timestamp, duplicated here so the series is readable without joining."
},
"contributed_groups": {
"type": "integer",
"format": "int64",
"description": "How many duplicate groups contain at least one of this source's records. A source can account for few duplicate RECORDS while touching many groups, which is the signature of a feed that adds one bad row to everything rather than one bad batch."
},
"created_at": {
"type": "string",
"format": "date-time",
"description": "Creation stamp (the run's logical timestamp)."
},
"duplicate_records": {
"type": "integer",
"format": "int64",
"description": "How many of them share an entity with at least one other record — counted by RECORD rather than by group, the same judgement metric_snapshots made: counting groups calls a five-record cluster and a pair the same amount of duplication."
},
"id": {
"type": "string",
"description": "Content-derived row id: sha256('metric_snapshot_sources:' || run_id || ':' || source_system)."
},
"records": {
"type": "integer",
"format": "int64",
"description": "How many of this source's records are in the corpus."
},
"run_id": {
"type": "string",
"description": "The run this attribution describes; shares its id with the metric_snapshots row."
},
"source_system": {
"type": "string",
"description": "The delivering source system."
},
"updated_at": {
"type": "string",
"format": "date-time",
"description": "Last-update stamp; a re-run of the same run_id corrects rather than appends."
}
}
}Org
{
"type": "object",
"description": "A tenant: its config pointer, lake env, lifecycle state and active config version.",
"required": [
"id",
"name",
"config_path",
"env",
"state",
"created_at",
"updated_at"
],
"properties": {
"active_config_version": {
"type": [
"integer",
"null"
],
"format": "int64",
"description": "The currently published config version, if any."
},
"config_path": {
"type": "string",
"description": "Path to the tenant's config document."
},
"created_at": {
"type": "string",
"format": "date-time",
"description": "When the tenant was created."
},
"drop_root": {
"type": [
"string",
"null"
],
"description": "Optional object-store root for tenant purge."
},
"env": {
"description": "Lake connection env (catalog, data path, metadata schema)."
},
"id": {
"type": "string",
"description": "The tenant's unique id (UUIDv7, minted at creation)."
},
"max_concurrent_jobs": {
"type": [
"integer",
"null"
],
"format": "int64",
"description": "How many of this org's jobs may be active at once, across its datasets (the noisy-neighbor cap). NULL inherits the server default (ER_ORG_JOB_CAP, which ships as 1 — the pre-dataset single-writer profile). The per-DATASET writer lock is separate and absolute."
},
"name": {
"type": "string",
"description": "The tenant's unique name (the routing handle; URLs stay name-based)."
},
"s3_ingest_bucket": {
"type": [
"string",
"null"
],
"description": "Bucket the auto-ingest poller watches for this tenant. Null means auto-ingest is off, which is every existing tenant — the feature has to be opted into, because a poller that starts reading a bucket nobody pointed at it would be ingesting data on its own initiative."
},
"s3_ingest_prefix": {
"type": [
"string",
"null"
],
"description": "Key prefix under `s3_ingest_bucket`, with one directory per config source beneath it. A column rather than a key in `env` deliberately: `env` is handed to the engine subprocess, while this is read by the control plane itself, and D5 is what happens when the two stores of per-tenant settings disagree."
},
"state": {
"type": "string",
"description": "Tenant lifecycle state."
},
"updated_at": {
"type": "string",
"format": "date-time",
"description": "Wall-clock last-write time (database default; advanced by mutations once the entity migrates)."
}
}
}PairLabel
{
"type": "object",
"description": "A human (or model) verdict on one candidate pair — the training signal the engine has always been able to learn from and never had. One row per (org, pair): a re-label corrects the previous verdict rather than stacking another.",
"required": [
"id",
"org_id",
"dataset_id",
"rec_a_key",
"rec_b_key",
"verdict",
"origin",
"labeled_by",
"created_at",
"updated_at"
],
"properties": {
"created_at": {
"type": "string",
"format": "date-time",
"description": "When the verdict was first recorded."
},
"dataset_id": {
"type": "string",
"description": "The dataset whose record pair this verdict is about — record keys are lake-local."
},
"id": {
"type": "string",
"description": "UUIDv7, minted by the application."
},
"labeled_by": {
"type": "string",
"description": "The actor that recorded the verdict."
},
"model_version": {
"type": [
"string",
"null"
],
"description": "The model whose score prompted this label, when there was one. Null for a label recorded without a score in front of it."
},
"note": {
"type": [
"string",
"null"
],
"description": "Optional free text from the labeller."
},
"org_id": {
"type": "string",
"description": "The tenant whose corpus the pair belongs to; every read is scoped by it."
},
"origin": {
"type": "string",
"description": "Where the verdict came from. `human` is an explicit labelling session; `reviewer` is implicit feedback from resolving a review item; `llm` is a model's suggestion. Kept apart so training can weight or exclude a source, and so an accuracy number can say whose labels it was measured against."
},
"rec_a_key": {
"type": "string",
"description": "The pair's lower record key, canonical order — the same ordering match_scores uses, so a label and a score describe the same pair."
},
"rec_b_key": {
"type": "string",
"description": "The pair's higher record key, canonical order."
},
"score_at_label": {
"type": [
"number",
"null"
],
"format": "double",
"description": "The match probability shown to the labeller, so a later accuracy pass can tell what the model thought at the time rather than what it thinks now."
},
"updated_at": {
"type": "string",
"format": "date-time",
"description": "When it was last corrected."
},
"verdict": {
"type": "string",
"description": "Whether these two records are the same entity. Deliberately binary: a labeller who is unsure should skip rather than guess, because a guessed label trains the model on noise and is indistinguishable afterwards from a confident one."
}
}
}ProfileFinding
{
"type": "object",
"description": "One coded observation a profile made about a corpus — a column mostly null, a blocking key dominated by one value, a record id that is not unique. Stored rather than derived at read time because the thresholds that produced a finding belong to the run that applied them: re-deriving later against changed thresholds would silently rewrite history, and a finding is the part of a profile a user is most likely to act on.",
"required": [
"id",
"profile_run_id",
"code",
"column_name",
"severity",
"message",
"created_at",
"updated_at"
],
"properties": {
"code": {
"type": "string",
"description": "The finding's registry code (P001, P002, …). Codes are append-only and a retired rule keeps its code, so a stored finding stays interpretable after the rule that made it is gone — which is the point of coding them rather than storing only prose."
},
"column_name": {
"type": "string",
"description": "The column the finding is about, or the empty string for a dataset-level finding (a duplicate row rate, a schema change). A sentinel rather than NULL because this column is in the natural key, and a NULL key column never matches in a MERGE's ON clause — every re-profile would insert a second copy of the same finding."
},
"created_at": {
"type": "string",
"format": "date-time",
"description": "Run-logical creation time."
},
"detail": {
"description": "The measurements behind the message — the shares, counts and thresholds — so a consumer can chart or re-check a finding without re-reading the column profile. NULL for a finding whose message is already complete."
},
"id": {
"type": "string",
"description": "Content-derived row id: sha256('profile_findings:' || profile_run_id || ':' || code || ':' || column_name)."
},
"message": {
"type": "string",
"description": "The finding in one human sentence, with its numbers already in it. Rendered rather than templated at read time because the numbers are what make it actionable, and a message assembled later could be assembled against different data than the one that triggered it."
},
"profile_run_id": {
"type": "string",
"description": "The profile run that produced this finding. Named for the relation it points at, per the foreign-key convention; no `references` is declared because DuckLake enforces no foreign keys (V11)."
},
"severity": {
"type": "string",
"description": "How much the finding should interrupt: `error`, `warning` or `info`. Carried on the row rather than looked up from the registry so that a severity reclassification does not retroactively change what a past profile reported."
},
"updated_at": {
"type": "string",
"format": "date-time",
"description": "Run-logical last-write time."
}
}
}ProfileRun
{
"type": "object",
"description": "One execution of the dataset profiler over one corpus stage, and the cache key for its result. A profile exists to be looked at repeatedly and compared against the previous delivery, so recomputing it on every view would make the cheap tier expensive for no new information.",
"required": [
"id",
"subject",
"source_system",
"snapshot",
"tier",
"corpus_digest",
"row_count",
"column_count",
"sampled",
"duration_ms",
"captured_at",
"created_at",
"updated_at"
],
"properties": {
"captured_at": {
"type": "string",
"format": "date-time",
"description": "The run's logical clock, not wall time — so a replayed fixture produces the same row."
},
"column_count": {
"type": "integer",
"format": "int64",
"description": "Columns profiled. Read with row_count it says how wide the scan was, which is the only honest predictor of what a re-profile will cost."
},
"config_hash": {
"type": [
"string",
"null"
],
"description": "The config version in force when the profile ran, so a finding about a blocking rule can be traced to the rule set it was judged against. NULL for a profile that predates any published config — the common case for a first delivery, which is exactly when profiling is most useful."
},
"corpus_digest": {
"type": "string",
"description": "A content digest of the rows profiled, and the actual cache key: one hash per row over all its columns, summed (so row order does not matter) and folded together with the row count. Equal digest means equal data, which is the question a cache has to answer — unlike the lake snapshot, which also moves when something unrelated is written, including this profile itself. Computed in one extra scan, which is cheap beside the distinct counts and top-k the profile already pays for."
},
"created_at": {
"type": "string",
"format": "date-time",
"description": "Run-logical creation time."
},
"duration_ms": {
"type": "integer",
"format": "int64",
"description": "Wall-clock cost of the profile, kept so the decision to run a deeper tier can be made from a measurement rather than a guess."
},
"id": {
"type": "string",
"description": "Content-derived row id: sha256('profile_runs:' || subject || ':' || source_system || ':' || corpus_digest || ':' || tier)."
},
"ingest_batch_id": {
"type": [
"string",
"null"
],
"description": "For a `raw` subject profiled automatically as a delivery lands, the delivery it describes — which lets drift be read between two consecutive batches. Provenance and ONLY provenance: this described itself as the per-delivery cache key until the auto-profile was built, and it was neither, because the key is `corpus_digest` and nothing populated this column at all. The digest is the better key anyway — two deliveries carrying identical content share it, where keying on the batch recomputes the same answer for every redelivery of an unchanged file. NULL for the standardized and golden subjects, which describe the whole corpus rather than one landing, and NULL for a profile an operator or a schedule asked for, which describes whatever is landed now rather than one batch."
},
"model_version": {
"type": [
"string",
"null"
],
"description": "The model whose rules a tier-2 or tier-3 profile measured, when one existed. NULL is the normal case for a new corpus and is not a defect: the candidate-key estimates are deliberately computable without a model."
},
"row_count": {
"type": "integer",
"format": "int64",
"description": "Rows the profile actually read, which is the sampled count when sampling was on. Named row_count rather than rows because `rows` is reserved in DuckDB and a column called that cannot be selected unquoted."
},
"sample_proportion": {
"type": [
"number",
"null"
],
"format": "double",
"description": "The sampled share of rows, NULL when the whole corpus was read."
},
"sample_seed": {
"type": [
"integer",
"null"
],
"format": "int64",
"description": "The salt the deterministic sample was drawn with, NULL when unsampled. Recorded because the sample is reproducible only if the seed is known, and a profile nobody can redraw cannot be compared against its successor."
},
"sampled": {
"type": "boolean",
"description": "Whether the figures come from a sample. Stored as its own flag rather than inferred from sample_proportion, because a consumer rendering a number has to know whether it is exact before it decides how to label it."
},
"snapshot": {
"type": "integer",
"format": "int64",
"description": "The DuckLake snapshot version the profile was computed against — informational provenance, deliberately NOT the cache key. It cannot be: the snapshot counter is per-catalog and this profile's own write advances it, so keying on it means every profile invalidates itself and the stored result grows a duplicate on every view instead of being reused. Found by the e2e test that asserts two profiles of unchanged data are one row."
},
"source_system": {
"type": "string",
"description": "The source whose delivered rows were profiled, or `*` when the subject is not source-scoped. A sentinel rather than NULL because this column is part of the natural key, and NULL never equals NULL in a MERGE's ON clause — a nullable key column would miss every match and insert a duplicate profile on each run."
},
"subject": {
"type": "string",
"description": "Which stage of the corpus was profiled: `raw` (as delivered, per source), `standardized` (the canonical attributes), or `golden` (post-resolution). The same aggregates run over all three, which is why a post-resolution profile costs no new machinery. Not an accepted_values list because DuckLake enforces no CHECK constraints (V11) and declaring one would promise a guarantee no layer provides."
},
"tier": {
"type": "integer",
"format": "int64",
"description": "Profiling depth: 1 shape (one aggregate pass), 2 entity-resolution readiness (blocking cost, skew, coverage), 3 model readiness (agreement rates, u-probability pre-flight). Kept in the key so a cheap profile is never mistaken for a deep one, and so asking for tier 3 does not read a tier 1 row and report it as complete."
},
"updated_at": {
"type": "string",
"format": "date-time",
"description": "Run-logical last-write time. A re-profile of an unchanged snapshot rewrites the row in place rather than appending, so this moves while the rest of the row does not."
}
}
}RecordQuality
{
"type": "object",
"description": "A per-record data-quality score, 0-100, with the three dimensions kept separately. The dimensions are kept because a single number says a record is bad and not what to do about it: complete-but-invalid, valid-but-empty and simply old are three different jobs.",
"required": [
"id",
"record_key",
"score",
"completeness",
"run_id",
"scored_at",
"created_at",
"updated_at"
],
"properties": {
"completeness": {
"type": "number",
"format": "double",
"description": "Weighted fraction of the configured attributes that are populated."
},
"created_at": {
"type": "string",
"format": "date-time",
"description": "Run-logical creation time."
},
"freshness": {
"type": [
"number",
"null"
],
"format": "double",
"description": "1.0 within `fresh_days` of the run, decaying to 0.0 at `stale_days`. NULL when the source carries no timestamp, because unknown age is not the same as old."
},
"id": {
"type": "string",
"description": "Content-derived row id: sha256('record_qualities:' || record_key)."
},
"record_key": {
"type": "string",
"description": "The standardized record scored."
},
"run_id": {
"type": "string",
"description": "The run that scored it."
},
"score": {
"type": "number",
"format": "double",
"description": "0-100, the weighted mean of the dimensions that APPLY to this record. A dimension that cannot be judged is left out of the mean rather than counted as zero."
},
"scored_at": {
"type": "string",
"format": "date-time",
"description": "That run's logical clock."
},
"updated_at": {
"type": "string",
"format": "date-time",
"description": "Run-logical last-write time."
},
"validity": {
"type": [
"number",
"null"
],
"format": "double",
"description": "Fraction of the PRESENT validatable fields that passed standardization. NULL when the record has none of them — a record with no email is already penalised by completeness, and scoring its validity zero would penalise the same absence twice."
}
}
}S3IngestCursor
{
"type": "object",
"description": "What the auto-ingest poller has already read, one row per (org, source). The poller runs on every dispatcher tick and the newest object under a prefix stays the newest until a new one arrives, so without this row the same CSV would be re-ingested every few seconds forever — an unbounded run loop over the tenant's own lake. An upsert rather than a log: the question it answers is 'what is already in', not 'what has ever been in', and the audit log already answers the second.",
"required": [
"id",
"org_id",
"dataset_id",
"source",
"object_key",
"size_bytes",
"delivery_id",
"created_at",
"updated_at"
],
"properties": {
"created_at": {
"type": "string",
"format": "date-time",
"description": "When this source was first auto-ingested."
},
"dataset_id": {
"type": "string",
"description": "The dataset the polled source lands in."
},
"delivery_id": {
"type": "string",
"description": "The delivery this object became, tying the cursor to the audit row and the run it enqueued."
},
"etag": {
"type": [
"string",
"null"
],
"description": "The object's ETag when it was read. The reason this column exists: a tenant who overwrites `crm/daily.csv` with new content leaves the key identical, so a key-only cursor would never read the new rows. Nullable because a listing can omit it."
},
"id": {
"type": "string",
"description": "UUIDv7, minted by the application."
},
"object_key": {
"type": "string",
"description": "The full S3 key of the object last ingested, kept whole so a tenant asking 'which file produced this run' gets the answer rather than a reconstruction."
},
"org_id": {
"type": "string",
"description": "The tenant whose prefix was polled; every read is scoped by it."
},
"size_bytes": {
"type": "integer",
"format": "int64",
"description": "The object's size at ingest, so a later shrink is visible as one."
},
"source": {
"type": "string",
"description": "The config source this object landed as — the first path segment under the tenant's prefix."
},
"updated_at": {
"type": "string",
"format": "date-time",
"description": "When it was last auto-ingested."
}
}
}Schedule
{
"type": "object",
"description": "A recurring job schedule for a tenant: its kind, cron and source.",
"required": [
"id",
"org_id",
"dataset_id",
"kind",
"params",
"cron",
"enabled",
"source",
"created_at",
"updated_at"
],
"properties": {
"created_at": {
"type": "string",
"format": "date-time",
"description": "When the schedule was created."
},
"cron": {
"type": "string",
"description": "The cron expression."
},
"dataset_id": {
"type": "string",
"description": "The dataset this schedule enqueues for."
},
"enabled": {
"type": "boolean",
"description": "Whether the schedule is active."
},
"id": {
"type": "string",
"description": "The schedule's unique id."
},
"kind": {
"type": "string",
"description": "The job kind the schedule enqueues."
},
"last_enqueued_at": {
"type": [
"string",
"null"
],
"format": "date-time",
"description": "When the schedule last enqueued a job."
},
"org_id": {
"type": "string",
"description": "The tenant this schedule runs for."
},
"params": {
"description": "Kind-specific parameters."
},
"source": {
"type": "string",
"description": "What created the schedule (api, config:correction_pass, system:lake_maintain)."
},
"updated_at": {
"type": "string",
"format": "date-time",
"description": "Wall-clock last-write time (database default; advanced by mutations once the entity migrates)."
}
}
}StagedStewardAction
{
"type": "object",
"description": "A steward action staged for review/apply: its payload, state and outcome.",
"required": [
"id",
"org_id",
"dataset_id",
"action",
"state",
"created_by",
"created_at",
"updated_at"
],
"properties": {
"action": {
"description": "The action payload."
},
"applied_at": {
"type": [
"string",
"null"
],
"format": "date-time",
"description": "When the action was applied, if it has been."
},
"created_at": {
"type": "string",
"format": "date-time",
"description": "When the action was staged."
},
"created_by": {
"type": "string",
"description": "Principal that staged the action."
},
"dataset_id": {
"type": "string",
"description": "The dataset whose lake this action drains into."
},
"error": {
"type": [
"string",
"null"
],
"description": "The failure reason, if the action failed."
},
"id": {
"type": "string",
"description": "The staged action's unique id."
},
"org_id": {
"type": "string",
"description": "The tenant the action applies to."
},
"state": {
"type": "string",
"description": "Whether the action is pending, applied or failed."
},
"updated_at": {
"type": "string",
"format": "date-time",
"description": "Wall-clock last-write time (database default; advanced by mutations once the entity migrates)."
}
}
}Tag
{
"type": "object",
"description": "A tenant's own label for entities and review groups: the vocabulary a steward sorts work by.",
"required": [
"id",
"org_id",
"name",
"kind",
"active",
"created_by",
"created_at",
"updated_at"
],
"properties": {
"active": {
"type": "boolean",
"description": "Whether the tag is in use. Retiring is a soft delete: `taggings` references this row, every foreign key in this schema is NO ACTION, and a hard DELETE would therefore fail for exactly the tags that had been used — which is the bug D11 found in webhooks. Keeping the row also keeps the history legible: what a group was once marked as is part of why it was handled the way it was."
},
"apply_min_role": {
"type": [
"string",
"null"
],
"description": "The minimum role allowed to apply or unapply this tag. Null means the route default (steward). Finer than the route's role check because a tag can name a decision only an admin should be able to mark — the spec's per-tag permission."
},
"created_at": {
"type": "string",
"format": "date-time",
"description": "When the tag was created."
},
"created_by": {
"type": "string",
"description": "The actor that created the tag."
},
"description": {
"type": [
"string",
"null"
],
"description": "What the tag means, for the steward who inherits it. Null when nobody wrote one."
},
"id": {
"type": "string",
"description": "The tag's unique id (UUIDv7, minted by the application)."
},
"kind": {
"type": "string",
"description": "Who the tag belongs to. `user` is the steward's vocabulary; `system` is reserved for tags the platform itself writes (merge, manual_merge, unmatch, link, split) — a system tag cannot be retired through the API, and its name cannot be taken by a user tag, so the two vocabularies can never collide."
},
"name": {
"type": "string",
"description": "The label a steward sees and types. Unique per tenant among active tags, because two tags with one name make a filter ambiguous and a bulk action unsafe."
},
"org_id": {
"type": "string",
"description": "The tenant that owns the tag. A tag is never shared across tenants: it names one tenant's own workflow."
},
"updated_at": {
"type": "string",
"format": "date-time",
"description": "Wall-clock last-write time."
}
}
}Tagging
{
"type": "object",
"description": "One tag applied to one subject: the attachment, kept apart from the tag so retiring a tag does not rewrite what it was applied to.",
"required": [
"id",
"org_id",
"dataset_id",
"tag_id",
"subject_type",
"subject_id",
"created_by",
"created_at",
"updated_at"
],
"properties": {
"created_at": {
"type": "string",
"format": "date-time",
"description": "When the tag was applied."
},
"created_by": {
"type": "string",
"description": "The actor that applied the tag. Kept because tagging is how work is assigned, so who claimed it matters."
},
"dataset_id": {
"type": "string",
"description": "The dataset whose subject this tag is applied to — subject ids are lake-local."
},
"id": {
"type": "string",
"description": "The tagging's unique id (UUIDv7, minted by the application)."
},
"org_id": {
"type": "string",
"description": "The tenant. Denormalised from the tag so every read is scoped by one predicate rather than a join — the same reason every other tenant-scoped relation carries it."
},
"subject_id": {
"type": "string",
"description": "The entity id or review id. Deliberately NOT a foreign key: an entity lives in the lake and a review is rebuilt by every reconcile, so a database-level reference would be to a row this store does not own. A tagging whose subject has gone is harmless — it reads as absent and is cleaned up by nothing, which is the honest cost of tagging something another store owns."
},
"subject_type": {
"type": "string",
"description": "What was tagged: `entity` (a resolved cluster, by its entity id) or `review` (an open review item). Two kinds rather than two tables, because a filter and a bulk action want one list of 'things tagged X' and a union of two relations would make every such read a join."
},
"tag_id": {
"type": "string",
"description": "The tag applied."
},
"updated_at": {
"type": "string",
"format": "date-time",
"description": "Wall-clock last-write time."
}
}
}TaskInstance
{
"type": "object",
"description": "One try of one task of one job (Airflow's task_instance shape): the live try has live = TRUE, archived tries have live NULL and stay in the table as history (batch-orchestration-design §4.2).",
"required": [
"id",
"org_id",
"job_id",
"task_id",
"seq",
"try_number",
"kind",
"state",
"trigger_rule",
"upstream",
"teardown",
"max_tries",
"launches",
"max_launches",
"created_at",
"updated_at"
],
"properties": {
"archived_reason": {
"type": [
"string",
"null"
],
"description": "Why the row stopped being live; NULL while live. retry = archive_try, cleared = a terminal row rotated by clear, restarted = a clear-while-live rotation (complete_restart). Pending rows reset by a clear are not archived (no try was consumed)."
},
"counters": {
"description": "Progress counters, replaced on every heartbeat and at finish."
},
"created_at": {
"type": "string",
"format": "date-time",
"description": "Row created."
},
"dataset_id": {
"type": [
"string",
"null"
],
"description": "Copied from the job at planning (NULL for org-level jobs); the per-dataset pod lock keys on it once the executor is re-scoped."
},
"error_class": {
"type": [
"string",
"null"
],
"description": "er-errors' seven classes plus the executor's four."
},
"error_detail": {
"type": [
"string",
"null"
],
"description": "Chain-flattened text (errfmt::chain), truncated to 2000 chars."
},
"escalated_from": {
"type": [
"string",
"null"
],
"description": "Class of the OOMKilled predecessor try, so a mixed-class run is legible."
},
"exit_code": {
"type": [
"integer",
"null"
],
"format": "int64",
"description": "Container exit code: the pod's own on finish, the watch's observation on record_evidence. Evidence for the row, never a classifier input (§6.5)."
},
"finished_at": {
"type": [
"string",
"null"
],
"format": "date-time",
"description": "Terminal state recorded."
},
"heartbeat_at": {
"type": [
"string",
"null"
],
"format": "date-time",
"description": "Last heartbeat."
},
"id": {
"type": "string",
"description": "er_ids::natural_id('task_instances', [job_id, task_id, try_number]): a pure function of the attempt key, so the Job name is one too."
},
"image_digest": {
"type": [
"string",
"null"
],
"description": "Image digest this try ran, so a deploy mid-run is legible."
},
"input": {
"description": "The work order: pinned upstream references, the RunPlan, params. Written whole by mark_scheduled at every readiness verdict (never merged), by advance_segment for a fused member, and copied by the retry insert; NULL on a none row."
},
"job_id": {
"type": "string",
"description": "The run (jobs.id == run_id)."
},
"k8s_job_name": {
"type": [
"string",
"null"
],
"description": "batch/v1 Job name, `er-t-{20 hex of id}-l{launches}`, of the Job that ran this try; for a fused non-head member, the segment head's Job (advance_segment copies it)."
},
"kind": {
"type": "string",
"description": "Where the body runs: a Kubernetes Job, or a dispatcher-local body under the control-task contract (§3.6)."
},
"launches": {
"type": "integer",
"format": "int64",
"description": "Infrastructure budget consumed by this try: Job creates whose pod never ran user code, plus disruptions while running; 1 for a member advanced inside a running segment pod."
},
"live": {
"type": [
"boolean",
"null"
],
"description": "TRUE on the live try, NULL once archived (NULLs are distinct, so the partial unique index admits one live row per coordinate)."
},
"max_launches": {
"type": "integer",
"format": "int64",
"description": "Infrastructure budget per try."
},
"max_tries": {
"type": "integer",
"format": "int64",
"description": "Cumulative try budget (Airflow max_tries): retries at planning; previous_try_number + retries after a clear. Eligible to retry while try_number <= max_tries."
},
"next_resource_class": {
"type": [
"string",
"null"
],
"description": "Operator override recorded by clear on a restarting row; complete_restart applies it to the successor."
},
"node_name": {
"type": [
"string",
"null"
],
"description": "Node the pod landed on."
},
"not_before": {
"type": [
"string",
"null"
],
"format": "date-time",
"description": "Backoff deadline for up_for_retry; a short capacity wait for scheduled."
},
"org_id": {
"type": "string",
"description": "Tenant."
},
"outcome": {
"type": [
"string",
"null"
],
"description": "Success flavour; no_op is exit 10."
},
"output": {
"description": "The serialized DurableOutput (a LakeRef or Plan), written at finish."
},
"owner_epoch": {
"type": [
"string",
"null"
],
"description": "The dispatcher process epoch (UUIDv7 minted at start) that claimed the launch; adoption rewrites it."
},
"pod_name": {
"type": [
"string",
"null"
],
"description": "Pod that ran this try, from the pod's bound token on first contact; cross-checked by the watch."
},
"pod_uid": {
"type": [
"string",
"null"
],
"description": "Pod UID, recorded from the token's claim; the watch confirms it."
},
"queued_at": {
"type": [
"string",
"null"
],
"format": "date-time",
"description": "Launch claimed (write-ahead, before the create)."
},
"resource_class": {
"type": [
"string",
"null"
],
"description": "Class this try runs at; NULL for a control task. OOM escalation writes a larger class on the next try."
},
"scheduled_at": {
"type": [
"string",
"null"
],
"format": "date-time",
"description": "Readiness fired."
},
"segment": {
"type": [
"string",
"null"
],
"description": "Fusion segment id resolved at planning; NULL for a task that runs alone."
},
"seq": {
"type": "integer",
"format": "int64",
"description": "Topological position from assembly; display and claim order."
},
"snapshot_end": {
"type": [
"integer",
"null"
],
"format": "int64",
"description": "Lake snapshot of the task's last commit: the durable reference downstream pins to."
},
"snapshot_start": {
"type": [
"integer",
"null"
],
"format": "int64",
"description": "Lake snapshot before the task's first commit."
},
"started_at": {
"type": [
"string",
"null"
],
"format": "date-time",
"description": "Pod reported start."
},
"state": {
"type": "string",
"description": "Closed state set (§5). restarting and canceling are the write-ahead markers for clear and cancel of a live row."
},
"task_id": {
"type": "string",
"description": "Task::NAME, stable across renames."
},
"teardown": {
"type": "boolean",
"description": "Claimable while the job is canceling (finish)."
},
"termination_reason": {
"type": [
"string",
"null"
],
"description": "Platform evidence, distinct from error_class, free text: OOMKilled, Evicted, DeadlineExceeded, Unschedulable, no_pod_created, vanished, quota, sigterm, sigkill, fenced, stale_start, structural_mismatch, build_skew, control_plane_unreachable, no_terminal_record, heartbeat_timeout, dispatcher_restart, revoked, and kin."
},
"trace_context": {
"type": [
"string",
"null"
],
"description": "traceparent of this try's span, a child of jobs.trace_context."
},
"trigger_rule": {
"type": "string",
"description": "Copied from the compiled graph at planning so the UI can explain propagation; the graph is the authority."
},
"try_number": {
"type": "integer",
"format": "int64",
"description": "1-based try. A new row per try."
},
"updated_at": {
"type": "string",
"format": "date-time",
"description": "Row updated."
},
"upstream": {
"description": "Upstream task_ids, a UI projection of the compiled edges."
}
}
}Webhook
{
"type": "object",
"description": "A tenant webhook endpoint: its URL, subscribed events and signing secret.",
"required": [
"id",
"org_id",
"url",
"events",
"active",
"created_at",
"updated_at"
],
"properties": {
"active": {
"type": "boolean",
"description": "Whether the webhook is active."
},
"created_at": {
"type": "string",
"format": "date-time",
"description": "When the webhook was registered."
},
"dataset_id": {
"type": [
"string",
"null"
],
"description": "Optional dataset filter: NULL subscribes to every dataset's events."
},
"events": {
"description": "The subscribed event types."
},
"id": {
"type": "string",
"description": "The webhook's unique id."
},
"org_id": {
"type": "string",
"description": "The tenant that owns the webhook."
},
"updated_at": {
"type": "string",
"format": "date-time",
"description": "Wall-clock last-write time (database default; advanced by mutations once the entity migrates)."
},
"url": {
"type": "string",
"description": "The delivery URL."
}
}
}WebhookDelivery
{
"type": "object",
"description": "One attempt-tracked delivery of one event to one subscriber. The event is recorded here BEFORE any network call, so a subscriber that is briefly unreachable gets the event late instead of never.",
"required": [
"id",
"org_id",
"webhook_id",
"event_type",
"payload",
"state",
"attempt",
"max_attempts",
"created_at",
"updated_at"
],
"properties": {
"attempt": {
"type": "integer",
"format": "int64",
"description": "Attempts handed out. Counted when claimed, not when reported, so a drainer that dies still consumes one."
},
"created_at": {
"type": "string",
"format": "date-time",
"description": "When the event was recorded, which is before any delivery was attempted."
},
"dataset_id": {
"type": [
"string",
"null"
],
"description": "The dataset the delivered event came from, when it has one (provenance)."
},
"delivered_at": {
"type": [
"string",
"null"
],
"format": "date-time",
"description": "When a 2xx was received; NULL unless state is delivered."
},
"error": {
"type": [
"string",
"null"
],
"description": "Why the last attempt did not deliver: a transport error, or the outbound-URL guard's refusal."
},
"event_type": {
"type": "string",
"description": "The catalogued event (webhook::EVENT_CATALOG), e.g. job.succeeded."
},
"id": {
"type": "string",
"description": "UUIDv7, minted by the application."
},
"max_attempts": {
"type": "integer",
"format": "int64",
"description": "Attempts before giving up. Six with the backoff below spans about ten minutes."
},
"next_attempt_at": {
"type": [
"string",
"null"
],
"format": "date-time",
"description": "When this becomes claimable. NULL means immediately; set to a backoff in the future after a retryable failure."
},
"org_id": {
"type": "string",
"description": "The tenant whose subscriber this is for; every read is scoped by it."
},
"payload": {
"description": "The exact body to POST. Stored rather than rebuilt so a retry delivers the same bytes the signature was computed over, and so the log shows what was actually sent."
},
"response_code": {
"type": [
"integer",
"null"
],
"format": "int64",
"description": "The subscriber's HTTP status, when the POST completed at all."
},
"state": {
"type": "string",
"description": "pending until a drain settles it; delivered on a 2xx; failed when retries are exhausted or the destination is refused outright."
},
"updated_at": {
"type": "string",
"format": "date-time",
"description": "Last write."
},
"webhook_id": {
"type": "string",
"description": "The subscription being delivered to."
}
}
}