Skip to content

HTTP API / Review

Review API ​

10 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
PUT/api/v1/workspaces/{workspaceId}/classifications/columns/{proposalId}Edit a column classification; the edit survives rescans.
PUT/api/v1/workspaces/{workspaceId}/classifications/tables/{proposalId}Edit a table classification; the edit survives rescans.
GET/api/v1/workspaces/{workspaceId}/proposalsThe Review queue: undecided proposals (plus those decided since decidedSince), counts per kind, High count.
POST/api/v1/workspaces/{workspaceId}/proposals:bulkAccept or reject many proposals: listed ids, or every undecided one matching a filter.
GET/api/v1/workspaces/{workspaceId}/proposals/{proposalId}One proposal with its evidence (F04 GetRelationshipEvidence).
POST/api/v1/workspaces/{workspaceId}/proposals/{proposalId}:acceptAccept a proposal. Accepting a table classification also accepts its undecided non-sensitive columns.
POST/api/v1/workspaces/{workspaceId}/proposals/{proposalId}:rejectReject a proposal (optionally with a reason). Rejections are remembered across scans.
POST/api/v1/workspaces/{workspaceId}/proposals/{proposalId}:undoReturn an accepted or rejected proposal to the queue.
GET/api/v1/workspaces/{workspaceId}/proposals/summaryHow many proposals wait for review (nav badge).
POST/api/v1/workspaces/{workspaceId}/sources/{sourceId}/relationshipsDeclare a join Keel did not find (user-defined, accepted).

EditColumnClassification ​

http
PUT /api/v1/workspaces/{workspaceId}/classifications/columns/{proposalId}

Edit a column classification; the edit survives rescans.

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
proposalIdpathuuidyes

Request body (application/json): EditColumnClassificationRequest

FieldTypeNotes
additivityAdditivity?
businessNamestring
defaultAggregationAggregationOne of None, Sum, Avg, Count, CountDistinct, Min, Max
descriptionstring?
piiCategoryPiiCategory?
roleColumnRoleOne of Key, Measure, Attribute, Time, Technical
semanticTypeSemanticTypeOne of Identifier, ForeignKey, Name, Email, Phone, Address, Country, Currency, Money, Percent, Quantity, Count, Date, Timestamp, Year, Month, Boolean, Category, Status, FreeText, Url, IpAddress, Geo, Json, Hash, Unknown
sensitivitySensitivityOne of Public, Internal, Confidential, Restricted
StatusDescriptionBody
204No Content—

EditTableClassification ​

http
PUT /api/v1/workspaces/{workspaceId}/classifications/tables/{proposalId}

Edit a table classification; the edit survives rescans.

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
proposalIdpathuuidyes

Request body (application/json): EditTableClassificationRequest

FieldTypeNotes
businessNamestring
descriptionstring?
domainstring?
grainstring[]?
roleTableRoleOne of Fact, Dimension, Bridge, Snapshot, SlowlyChangingDimension, Aggregate, Staging, LogEvent, Lookup, Unknown,
StatusDescriptionBody
204No Content—

ListProposals ​

http
GET /api/v1/workspaces/{workspaceId}/proposals

The Review queue: undecided proposals (plus those decided since decidedSince), counts per kind, High count.

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
kindqueryReviewKindno
sourceIdqueryuuidno
minConfidencequerynumberno
decidedSincequerydate-timeno
limitqueryint32no
StatusDescriptionBody
200OKReviewQueueDto

Response 200: ReviewQueueDto

FieldTypeNotes
countsReviewKindCountDto[]
highPendingint32
itemsProposalDto[]
totalint32

BulkReviewProposals ​

http
POST /api/v1/workspaces/{workspaceId}/proposals:bulk

Accept or reject many proposals: listed ids, or every undecided one matching a filter.

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes

Request body (application/json): BulkReviewRequest

FieldTypeNotes
actionProposalDecisionOne of Accept, Reject, Undo
idsuuid[]?
kindReviewKind?
minConfidencenumber?
reasonstring?
sourceIduuid?
StatusDescriptionBody
200OKBulkReviewResult

Response 200: BulkReviewResult

FieldTypeNotes
decidedint32
skippedint32

GetProposal ​

http
GET /api/v1/workspaces/{workspaceId}/proposals/{proposalId}

One proposal with its evidence (F04 GetRelationshipEvidence).

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
proposalIdpathuuidyes
StatusDescriptionBody
200OKProposalDto

Response 200: ProposalDto

FieldTypeNotes
bandstring
confidencenumber
dataSourceIduuid
dataSourceNamestring
decidedAtdate-time?
decidedBystring?
decisionReasonstring?
effectstring
evidenceEvidenceDto[]
iduuid
kindReviewKindOne of Join, Classify, Pii
originOriginOne of Discovered, Inferred, LlmSuggested, UserDefined, Imported
originLabelstring
proposedAtdate-time
statusProposalStatusOne of Proposed, Accepted, Rejected, Superseded
titlestring
whystring

AcceptProposal ​

http
POST /api/v1/workspaces/{workspaceId}/proposals/{proposalId}:accept

Accept a proposal. Accepting a table classification also accepts its undecided non-sensitive columns.

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
proposalIdpathuuidyes
StatusDescriptionBody
204No Content—

RejectProposal ​

http
POST /api/v1/workspaces/{workspaceId}/proposals/{proposalId}:reject

Reject a proposal (optionally with a reason). Rejections are remembered across scans.

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
proposalIdpathuuidyes

Request body (application/json): RejectProposalRequest?

StatusDescriptionBody
204No Content—

UndoProposalDecision ​

http
POST /api/v1/workspaces/{workspaceId}/proposals/{proposalId}:undo

Return an accepted or rejected proposal to the queue.

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
proposalIdpathuuidyes
StatusDescriptionBody
204No Content—

GetReviewSummary ​

http
GET /api/v1/workspaces/{workspaceId}/proposals/summary

How many proposals wait for review (nav badge).

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
StatusDescriptionBody
200OKReviewSummaryDto

Response 200: ReviewSummaryDto

FieldTypeNotes
pendingint32

AssertRelationship ​

http
POST /api/v1/workspaces/{workspaceId}/sources/{sourceId}/relationships

Declare a join Keel did not find (user-defined, accepted).

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
sourceIdpathuuidyes

Request body (application/json): AssertRelationshipRequest

FieldTypeNotes
cardinalityCardinalityOne of ManyToOne, OneToOne, ManyToMany
fromColumnsstring[]
fromSchemastring
fromTablestring
toColumnsstring[]
toSchemastring
toTablestring
StatusDescriptionBody
201CreatedCreatedResponse

Response 201: CreatedResponse

FieldTypeNotes
iduuid

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.