Skip to content

HTTP API / Quality

Quality API ​

27 operations. Paths are relative to the API host (http://localhost:5080 in local development). Every operation accepts an OIDC bearer token (Authorization: Bearer …) or a workspace API key (X-Api-Key: keel_live_…); errors are RFC 9457 Problem Details with a code (error codes). Permissions: matrix.

MethodPathSummary
POST/api/v1/workspaces/{workspaceId}/quality/assets:runRun every active rule on a table and its columns (one job per rule).
POST/api/v1/workspaces/{workspaceId}/quality/custom-sql:validateCheck custom rule SQL: one read-only SELECT/WITH query (no DDL/DML, one statement).
GET/api/v1/workspaces/{workspaceId}/quality/dashboardThe Data quality page: dimension scorecard, open incidents (with chart series and threshold) and the rule results table.
GET/api/v1/workspaces/{workspaceId}/quality/incidentsIncidents, open first (open=true: Open and Acknowledged only).
GET/api/v1/workspaces/{workspaceId}/quality/incidents/{incidentId}An incident with the rule's recent series against its threshold and the affected metrics.
POST/api/v1/workspaces/{workspaceId}/quality/incidents/{incidentId}:acknowledgeAcknowledge an open incident: it is assigned to you.
POST/api/v1/workspaces/{workspaceId}/quality/incidents/{incidentId}:resolveResolve an incident by hand (it also resolves itself after consecutive passing runs).
GET/api/v1/workspaces/{workspaceId}/quality/models/{modelId}/metrics/{metric}/trustA metric's trust score with its breakdown (upstream data, coverage, governance, freshness).
GET/api/v1/workspaces/{workspaceId}/quality/resultsThe rule results table of the dashboard, paged (failures first, then severity, latest run, name).
GET/api/v1/workspaces/{workspaceId}/quality/rule-targetThe rule editor's view of a table: metrics whose trust a failing rule lowers, and its load cadence from stored results (no source query).
GET/api/v1/workspaces/{workspaceId}/quality/rulesQuality rules with their latest result (filter by status, type, dimension, severity, asset, outcome).
POST/api/v1/workspaces/{workspaceId}/quality/rulesDefine a rule (active at once). Custom SQL must be one read-only query returning the failing rows.
POST/api/v1/workspaces/{workspaceId}/quality/rules:backtestReplay a draft rule's threshold over the table's stored results (latest run per day); nothing is run on the source or saved.
POST/api/v1/workspaces/{workspaceId}/quality/rules:bulkAccept or reject many suggested rules: listed ids, or every one at or above minConfidence.
POST/api/v1/workspaces/{workspaceId}/quality/rules:importImport dbt tests (schema YAML) or Great Expectations suites (JSON), as files or a zip, as rule proposals (origin Imported, file:line evidence) on the scanned tables of a source; checks that do not map are reported. Govern.
POST/api/v1/workspaces/{workspaceId}/quality/rules:suggestSuggest rules from the source's latest scan (also runs after every successful scan).
GET/api/v1/workspaces/{workspaceId}/quality/rules/{ruleId}One rule with its parameters, evidence and latest result.
PUT/api/v1/workspaces/{workspaceId}/quality/rules/{ruleId}Edit a rule's thresholds, severity, dimension, schedule or wording (audited).
POST/api/v1/workspaces/{workspaceId}/quality/rules/{ruleId}:acceptAccept a suggested rule: it becomes active and runs on its schedule.
POST/api/v1/workspaces/{workspaceId}/quality/rules/{ruleId}:pausePause an active rule (no scheduled runs; excluded from scores).
POST/api/v1/workspaces/{workspaceId}/quality/rules/{ruleId}:rejectReject a suggested rule (optionally with a reason); rescans never re-suggest it.
POST/api/v1/workspaces/{workspaceId}/quality/rules/{ruleId}:resumeResume a paused rule.
POST/api/v1/workspaces/{workspaceId}/quality/rules/{ruleId}:runRun a rule now on its source (Re-run check); poll the job, then read the rule's runs.
GET/api/v1/workspaces/{workspaceId}/quality/runsRuns, newest first (optionally of one rule). Failing keys carry key columns only.
GET/api/v1/workspaces/{workspaceId}/quality/runs/{runId}One run with its measured value and up to 50 failing rows' keys.
GET/api/v1/workspaces/{workspaceId}/quality/scorecardScorecard (0–100 per DQ dimension, overall, daily trend). asset: workspace | source:{id} | table:{source}/{schema}/{table} | column:{source}/{schema}/{table}/{column} | entity:{model}/{entity} | metric:{model}/{metric} | domain:{name}.
GET/api/v1/workspaces/{workspaceId}/quality/trustStored metric trust scores (updated when an upstream run completes).

RunQualityRulesForAsset ​

http
POST /api/v1/workspaces/{workspaceId}/quality/assets:run

Run every active rule on a table and its columns (one job per rule).

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes

Request body (application/json): RunAssetRequest

FieldTypeNotes
dataSourceIduuid
schemastring
tablestring
StatusDescriptionBody
200OKRunsAcceptedDto

Response 200: RunsAcceptedDto

FieldTypeNotes
rulesint32
runsRunAcceptedDto[]

ValidateQualitySql ​

http
POST /api/v1/workspaces/{workspaceId}/quality/custom-sql:validate

Check custom rule SQL: one read-only SELECT/WITH query (no DDL/DML, one statement).

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes

Request body (application/json): ValidateSqlRequest

FieldTypeNotes
sqlstring
StatusDescriptionBody
200OKSqlValidationDto

Response 200: SqlValidationDto

FieldTypeNotes
problemsstring[]
validboolean

GetQualityDashboard ​

http
GET /api/v1/workspaces/{workspaceId}/quality/dashboard

The Data quality page: dimension scorecard, open incidents (with chart series and threshold) and the rule results table.

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
StatusDescriptionBody
200OKQualityDashboardDto

Response 200: QualityDashboardDto

FieldTypeNotes
activeRulesint32
dimensionsDimensionScoreDto[]
openIncidentCountint32
openIncidentsIncidentDto[]
overallnumber?
resultsRuleResultDto[]
sourcesint32
suggestedRulesint32
totalResultsint32
trendTrendPointDto[]

ListQualityIncidents ​

http
GET /api/v1/workspaces/{workspaceId}/quality/incidents

Incidents, open first (open=true: Open and Acknowledged only).

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
statusqueryIncidentStatusno
openquerybooleanno
pagequeryint32no
pageSizequeryint32no
StatusDescriptionBody
200OKPagedResultOfIncidentSummaryDto

Response 200: PagedResultOfIncidentSummaryDto

FieldTypeNotes
hasNextboolean
itemsIncidentSummaryDto[]
pageint32
pageSizeint32
totalCountint64

GetQualityIncident ​

http
GET /api/v1/workspaces/{workspaceId}/quality/incidents/{incidentId}

An incident with the rule's recent series against its threshold and the affected metrics.

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
incidentIdpathuuidyes
StatusDescriptionBody
200OKIncidentDto

Response 200: IncidentDto

FieldTypeNotes
affectedMetricsMetricRefDto[]
incidentIncidentSummaryDto
recentRunsQualityRunDto[]
seriesSeriesPointDto[]
thresholdnumber?
unitstring?

AcknowledgeQualityIncident ​

http
POST /api/v1/workspaces/{workspaceId}/quality/incidents/{incidentId}:acknowledge

Acknowledge an open incident: it is assigned to you.

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
incidentIdpathuuidyes
StatusDescriptionBody
204No Content—

ResolveQualityIncident ​

http
POST /api/v1/workspaces/{workspaceId}/quality/incidents/{incidentId}:resolve

Resolve an incident by hand (it also resolves itself after consecutive passing runs).

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
incidentIdpathuuidyes

Request body (application/json): ResolveIncidentRequest

FieldTypeNotes
notestring?
StatusDescriptionBody
204No Content—

GetMetricTrustScore ​

http
GET /api/v1/workspaces/{workspaceId}/quality/models/{modelId}/metrics/{metric}/trust

A metric's trust score with its breakdown (upstream data, coverage, governance, freshness).

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
modelIdpathuuidyes
metricpathstringyes
StatusDescriptionBody
200OKTrustScoreDto

Response 200: TrustScoreDto

FieldTypeNotes
bandstring
businessNamestring?
cappedboolean
computedAtdate-time
coveragenumber
failingCriticalboolean
failingRulesFailingRuleDto[]
freshnessnumber
freshnessLagHoursnumber?
freshnessMeasuredboolean
governanceGovernanceDto
metricstring
modelIduuid
modelNamestring
scoreint32
upstreamUpstreamScoreDto[]
upstreamDatanumber
upstreamMeasuredboolean

ListQualityRuleResults ​

http
GET /api/v1/workspaces/{workspaceId}/quality/results

The rule results table of the dashboard, paged (failures first, then severity, latest run, name).

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
pagequeryint32no
pageSizequeryint32no
StatusDescriptionBody
200OKPagedResultOfRuleResultDto

Response 200: PagedResultOfRuleResultDto

FieldTypeNotes
hasNextboolean
itemsRuleResultDto[]
pageint32
pageSizeint32
totalCountint64

GetQualityRuleTarget ​

http
GET /api/v1/workspaces/{workspaceId}/quality/rule-target

The rule editor's view of a table: metrics whose trust a failing rule lowers, and its load cadence from stored results (no source query).

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
dataSourceIdqueryuuidyes
schemaquerystringyes
tablequerystringyes
daysqueryint32no
StatusDescriptionBody
200OKRuleTargetDto

Response 200: RuleTargetDto

FieldTypeNotes
dependentMetricsint32
loadIntervalHoursnumber?
loadsint32
rowsPerLoadint64?
runsint32
typicalLoadTimeUtcstring?

ListQualityRules ​

http
GET /api/v1/workspaces/{workspaceId}/quality/rules

Quality rules with their latest result (filter by status, type, dimension, severity, asset, outcome).

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
statusqueryRuleStatusno
typequeryRuleTypeno
dimensionqueryQualityDimensionno
severityqueryRuleSeverityno
sourceIdqueryuuidno
schemaquerystringno
tablequerystringno
outcomequeryRunOutcomeno
searchquerystringno
pagequeryint32no
pageSizequeryint32no
StatusDescriptionBody
200OKPagedResultOfQualityRuleDto

Response 200: PagedResultOfQualityRuleDto

FieldTypeNotes
hasNextboolean
itemsQualityRuleDto[]
pageint32
pageSizeint32
totalCountint64

CreateQualityRule ​

http
POST /api/v1/workspaces/{workspaceId}/quality/rules

Define a rule (active at once). Custom SQL must be one read-only query returning the failing rows.

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes

Request body (application/json): CreateRuleRequest

FieldTypeNotes
columnstring?
dataSourceIduuid
descriptionstring?
dimensionQualityDimension?Defaults to the rule type's dimension (docs/07 §2).
namestring
parametersRuleParameters?
schedulestring?Five-field cron in UTC (e.g. 0 2 * * *); null = on demand only.
schemastring
severityRuleSeverityOne of Info, Warning, Critical
tablestring
typeRuleTypeOne of NotNull, Unique, AcceptedValues, Range, NonNegative, Regex, ReferentialIntegrity, Freshness, RowCountDelta, VolumeAnomaly, DistributionDrift, CustomSql
StatusDescriptionBody
201CreatedCreatedResponse

Response 201: CreatedResponse

FieldTypeNotes
iduuid

BacktestQualityRule ​

http
POST /api/v1/workspaces/{workspaceId}/quality/rules:backtest

Replay a draft rule's threshold over the table's stored results (latest run per day); nothing is run on the source or saved.

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes

Request body (application/json): BacktestRuleRequest

FieldTypeNotes
columnstring?
dataSourceIduuid
daysint32?
parametersRuleParameters?
schemastring
tablestring
typeRuleTypeOne of NotNull, Unique, AcceptedValues, Range, NonNegative, Regex, ReferentialIntegrity, Freshness, RowCountDelta, VolumeAnomaly, DistributionDrift, CustomSql
StatusDescriptionBody
200OKRuleBacktestDto

Response 200: RuleBacktestDto

FieldTypeNotes
daysint32
latestnumber?
latestDaystring?
latestViolatedboolean?
pointsBacktestPointDto[]
runsint32
supportedboolean
thresholdnumber?
typicalnumber?
unitstring?
wouldFailint32

BulkDecideQualityRules ​

http
POST /api/v1/workspaces/{workspaceId}/quality/rules:bulk

Accept or reject many suggested rules: listed ids, or every one at or above minConfidence.

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes

Request body (application/json): BulkRuleDecisionRequest

FieldTypeNotes
actionRuleDecisionOne of Accept, Reject, Pause, Resume
idsuuid[]?
minConfidencenumber?
reasonstring?
StatusDescriptionBody
200OKBulkDecisionDto

Response 200: BulkDecisionDto

FieldTypeNotes
decidedint32
skippedint32

ImportQualityChecks ​

http
POST /api/v1/workspaces/{workspaceId}/quality/rules:import

Import dbt tests (schema YAML) or Great Expectations suites (JSON), as files or a zip, as rule proposals (origin Imported, file:line evidence) on the scanned tables of a source; checks that do not map are reported. Govern.

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes

Request body (multipart/form-data): object

StatusDescriptionBody
200OKQualityCheckImportDto

Response 200: QualityCheckImportDto

FieldTypeNotes
checksint32
createdint32
dataSourceIduuid
existingint32
formatstring
issuesCheckImportIssueDto[]
refreshedint32
rulesImportedRuleDto[]
unchangedint32
unmappedUnmappedCheckDto[]

SuggestQualityRules ​

http
POST /api/v1/workspaces/{workspaceId}/quality/rules:suggest

Suggest rules from the source's latest scan (also runs after every successful scan).

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes

Request body (application/json): SuggestRulesRequest

FieldTypeNotes
dataSourceIduuid
StatusDescriptionBody
202AcceptedSuggestionsAcceptedDto

Response 202: SuggestionsAcceptedDto

FieldTypeNotes
jobIduuid
snapshotIduuid

GetQualityRule ​

http
GET /api/v1/workspaces/{workspaceId}/quality/rules/{ruleId}

One rule with its parameters, evidence and latest result.

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
ruleIdpathuuidyes
StatusDescriptionBody
200OKQualityRuleDto

Response 200: QualityRuleDto

FieldTypeNotes
assetstring
columnstring?
confidencenumber
createdAtdate-time
dataSourceIduuid
decidedAtdate-time?
decidedBystring?
decisionReasonstring?
descriptionstring?
dimensionQualityDimensionOne of Completeness, Uniqueness, Validity, Integrity, Timeliness, Consistency, Reasonableness
evidenceQualityEvidenceDto[]
iduuid
lastOutcomeRunOutcome?
lastRunAtdate-time?
lastSummarystring?
namestring
openIncidentIduuid?
originOriginOne of Discovered, Inferred, LlmSuggested, UserDefined, Imported
parametersRuleParameters
schedulestring?
schemastring
severityRuleSeverityOne of Info, Warning, Critical
statusRuleStatusOne of Proposed, Active, Paused, Rejected
tablestring
typeRuleTypeOne of NotNull, Unique, AcceptedValues, Range, NonNegative, Regex, ReferentialIntegrity, Freshness, RowCountDelta, VolumeAnomaly, DistributionDrift, CustomSql

UpdateQualityRule ​

http
PUT /api/v1/workspaces/{workspaceId}/quality/rules/{ruleId}

Edit a rule's thresholds, severity, dimension, schedule or wording (audited).

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
ruleIdpathuuidyes

Request body (application/json): UpdateRuleRequest

FieldTypeNotes
descriptionstring?
dimensionQualityDimensionOne of Completeness, Uniqueness, Validity, Integrity, Timeliness, Consistency, Reasonableness
namestring
parametersRuleParameters?
schedulestring?
severityRuleSeverityOne of Info, Warning, Critical
StatusDescriptionBody
204No Content—

AcceptQualityRule ​

http
POST /api/v1/workspaces/{workspaceId}/quality/rules/{ruleId}:accept

Accept a suggested rule: it becomes active and runs on its schedule.

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
ruleIdpathuuidyes
StatusDescriptionBody
204No Content—

PauseQualityRule ​

http
POST /api/v1/workspaces/{workspaceId}/quality/rules/{ruleId}:pause

Pause an active rule (no scheduled runs; excluded from scores).

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
ruleIdpathuuidyes
StatusDescriptionBody
204No Content—

RejectQualityRule ​

http
POST /api/v1/workspaces/{workspaceId}/quality/rules/{ruleId}:reject

Reject a suggested rule (optionally with a reason); rescans never re-suggest it.

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
ruleIdpathuuidyes

Request body (application/json): RejectRuleRequest

FieldTypeNotes
reasonstring?
StatusDescriptionBody
204No Content—

ResumeQualityRule ​

http
POST /api/v1/workspaces/{workspaceId}/quality/rules/{ruleId}:resume

Resume a paused rule.

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
ruleIdpathuuidyes
StatusDescriptionBody
204No Content—

RunQualityRule ​

http
POST /api/v1/workspaces/{workspaceId}/quality/rules/{ruleId}:run

Run a rule now on its source (Re-run check); poll the job, then read the rule's runs.

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
ruleIdpathuuidyes
StatusDescriptionBody
202AcceptedRunAcceptedDto

Response 202: RunAcceptedDto

FieldTypeNotes
jobIduuid
ruleIduuid

ListQualityRuns ​

http
GET /api/v1/workspaces/{workspaceId}/quality/runs

Runs, newest first (optionally of one rule). Failing keys carry key columns only.

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
ruleIdqueryuuidno
outcomequeryRunOutcomeno
sincequerydate-timeno
pagequeryint32no
pageSizequeryint32no
StatusDescriptionBody
200OKPagedResultOfQualityRunDto

Response 200: PagedResultOfQualityRunDto

FieldTypeNotes
hasNextboolean
itemsQualityRunDto[]
pageint32
pageSizeint32
totalCountint64

GetQualityRun ​

http
GET /api/v1/workspaces/{workspaceId}/quality/runs/{runId}

One run with its measured value and up to 50 failing rows' keys.

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
runIdpathuuidyes
StatusDescriptionBody
200OKQualityRunDto

Response 200: QualityRunDto

FieldTypeNotes
assetstring
dimensionQualityDimensionOne of Completeness, Uniqueness, Validity, Integrity, Timeliness, Consistency, Reasonableness
durationMsint64
failingCountint64?
failingKeysobject[]
finishedAtdate-time
iduuid
keyColumnsstring[]
messagestring?
observedValuenumber?
outcomeRunOutcomeOne of Pass, Warn, Fail, Error,
rowCountint64?
ruleIduuid
ruleNamestring
ruleTypeRuleTypeOne of NotNull, Unique, AcceptedValues, Range, NonNegative, Regex, ReferentialIntegrity, Freshness, RowCountDelta, VolumeAnomaly, DistributionDrift, CustomSql
scheduledFordate-time?
severityRuleSeverityOne of Info, Warning, Critical
startedAtdate-time
summarystring
thresholdnumber?
triggerQualityRunTriggerOne of Manual, Schedule, Asset
unitstring?

GetQualityScorecard ​

http
GET /api/v1/workspaces/{workspaceId}/quality/scorecard

Scorecard (0–100 per DQ dimension, overall, daily trend). asset: workspace | source:{id} | table:{source}/{schema}/{table} | column:{source}/{schema}/{table}/{column} | entity:{model}/{entity} | metric:{model}/{metric} | domain:{name}.

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
assetquerystringno
StatusDescriptionBody
200OKScorecardDto

Response 200: ScorecardDto

FieldTypeNotes
assetstring
dimensionsDimensionScoreDto[]
failingint32
kindstring
labelstring
measuredint32
rulesint32
scorenumber?
tablesstring[]
trendTrendPointDto[]

ListMetricTrustScores ​

http
GET /api/v1/workspaces/{workspaceId}/quality/trust

Stored metric trust scores (updated when an upstream run completes).

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
modelIdqueryuuidno
StatusDescriptionBody
200OKMetricTrustDto[]

Anchor Keel is a working product name: one platform, a shared core and licensed modules (Keel Semantic, Keel Migrate). Documentation built from the repository — facts are derived from code, ADRs and the decisions log.