Skip to content
Registry StackDocsv0.34.0

Registry Casework API

View as Markdown

Registry Casework serves source-backed work items and source-neutral review requests. Every call presents a bearer token and the Casework profile selected for that call. Source-backed reads also present the caller’s current source authority. The contract is current and carries no frozen compatibility promise.

Open the Registry Casework API operations for every route, parameter, schema, and reachable problem code. This page holds the authentication, selection, revision, and recovery rules those operations assume.

Every request presents Authorization: Bearer <token> and Registry-Casework-Profile, naming the one profile the caller selected for that call. A profile name is bounded to 128 bytes. Liveness and readiness are the only routes that take neither header, and a source-delivered event authenticates with the configured webhook signature and timestamp headers instead.

Registry-Source-Profile names the separate source authority the caller selected. Source work-item routes require it. A unified review task whose context strategy is source also requires the exact human caller’s source profile and token for current reads. Submitted-context review tasks require no source profile. The two authorities remain separate even when one client instance drives both.

A revisioned mutation carries the item or directory revision the caller displayed in If-Match. A retriable create or mutation carries an Idempotency-Key the caller chooses, bounded to 128 bytes, and Casework never retries one on the caller’s behalf. After a lost response, the attempt recovery routes return the original attempt under the same key, so recovery does not depend on the attempt identifier reaching the caller.

A refusal answers application/problem+json with type, title, status, detail, code, and traceId. The type is the code with each dot replaced by a slash under https://id.registrystack.org/problems/registry-casework/, and detail is the fixed sentence that belongs to the code. No field repeats a submitted value. A refused review submission adds Registry-Casework-Validation-Path, a bounded JSON path, and Registry-Casework-Validation-Reason, one value from a closed set, so a caller can point at an invalid review field without the service echoing it. A refusal that holds a durable attempt adds Registry-Casework-Attempt.

Every Casework problem response carries one code from this closed catalogue, always answered with the HTTP status listed beside it.

For a source-backed decision, request.source-rejected means you must fix the promoted action body, source.record-missing means the bound record is no longer at its registered location, and source.reviewer-not-authorized means you must check the selected source profile and credential. Only work-item.not-offered tells you to refresh the item because the action is stale.

CodeStatusWhen
absence.cover-cycle422A cover assignment would return to an earlier person during a shared period.
absence.invalid-period422An absence period does not end after it starts.
absence.overlap422The period overlaps another absence already recorded for that person.
absence.self-cover422An absence names its own person as cover.
authentication.refused401The bearer credential is missing, invalid, or expired.
clock.recompute-preview-expired410A clock recompute preview was applied after it expired. Create a new preview and review it before applying.
cursor.expired410A page cursor has expired. Start again without a cursor and deduplicate entries by eventId.
cursor.invalid400A page cursor is malformed or was issued for a different request.
idempotency.expired410The stored response for the idempotency key has expired. Reconcile the original operation before choosing a new key.
idempotency.key-reused409An idempotency key was presented for a different request.
operation.not-authorized403The caller's Casework authority does not allow this operation.
precondition.failed412If-Match did not match the current revision of the item or directory.
precondition.required428A mutation that requires the revision the caller loaded was called without it.
profile.not-authorized403The selected Casework profile does not authorize the request.
profile.not-human403An action reserved for a human session was called under another session.
request.body-too-large413The request body exceeds the one MiB limit.
request.invalid400The path, query, or headers did not match the Casework contract.
request.method-not-allowed405The route does not accept that HTTP method.
request.not-found404The requested Casework route does not exist.
request.reason-unsupported422The reason field was sent with an action the selected source does not accept it on, refused before a durable attempt is prepared. The BReg source accepts a reason on every promoted decision and apply.
request.source-rejected422The source refused the promoted action body. Fix the decision request before trying again.
request.unprocessable422The request body does not match the Casework contract. validation names the member and the closed reason.
request.unsupported-media-type415A body without Content-Type: application/json.
review.initiator-excluded403The caller submitted this request and the review stage excludes its initiator. Another reviewer must claim or decide it.
review.initiator-required422The review kind excludes its initiator, so the producer must name the initiator when it submits the request.
review.result-expired410The retained review result is no longer available. Reconcile it through the producer's retained source correlation.
review.submission-conflict409The same producer, source subject, version, and policy were already submitted with different canonical content.
review.task-not-held409The caller tried to decide a review task without holding its current revision.
runtime.failure500Casework could not complete the request.
service.unavailable503Casework storage is unavailable. Retry after the service recovers.
source-profile.not-applicable400The route does not use source authority. Omit the Registry-Source-Profile header.
source-profile.required400The route needs an explicit Registry-Source-Profile header to select source authority.
source.bad-gateway502The source returned a response that does not match its registered contract.
source.not-found404The named source is not registered.
source.record-missing404The bound source record is no longer at the registered location.
source.reviewer-not-authorized403The source refused the selected reviewer profile or credential.
source.signature-invalid400A source event's signature did not verify.
work-item.already-claimed409Another person claimed the item first.
work-item.not-holder409The caller does not hold the item. Claim it first, or ask a supervisor.
work-item.not-offered409The source did not offer that action to this caller.
work-item.not-visible404The source did not show this request to the caller, so Casework shows no item. The caller cannot tell this from an item that does not exist.
work-item.proposal-changed409The proposal changed since the caller read it. The private draft is retained.
work-item.recovery-pending409The result of the caller's last action is unconfirmed. Recover the original attempt; do not decide again.
work-item.source-unavailable503The source is not answering, so Casework cannot confirm the current item or its actions. The private draft is retained.
work-item.superseded409A revised proposal replaced this item. Open the current one.

The served routes group into these families. Authority is checked per route and per item, so membership in a family grants nothing on its own.

FamilyBase pathsCallers
Service description/v1/caseworkAny authenticated profile
Work items and holdings/v1/work-items, /v1/holdingsStaff and Supervisor
Review requests and results/v1/review-requests, /v1/review-resultsAdmitted producer
Review tasks and context/v1/review-tasksStaff and Supervisor
Review kinds and accountability/v1/review-kinds, /v1/review-accountability/{eventId}Authenticated profiles; accountability remains Supervisor-only
Directory and absences/v1/directory, /v1/directory/absencesAdministrator, with own or supervised absences for Staff and Supervisor
Caseload movement/v1/directory/caseloadSupervisor
Clocks and holidays/v1/directory/clocks, /v1/directory/holidaysAdministrator
Source events/events/sources/{sourceId}The configured source, by signature
Liveness and readiness/health, /readyAny caller, without a token

GET /v1/review-requests/{requestId}/history pages minimized classified events. Human reviewers see reviewer-audience events under current task authority. The bound producer sees only requester-audience events and never sees private reasons, drafts, or raw reviewer identities. A person selecting the producer’s initiatorProfile sees the same requester-audience events, only for a request that names them as its initiator; every other request is not found. Source-context task lists, reads, context, and history remain concealed when the human caller’s current source read is revoked or unavailable.

  • Staff works eligible items and may delegate an item it holds.
  • Supervisor controls assignment and caseload for currently led teams, reads holdings, and resolves retained review accountability for served queues.
  • Administrator manages directory teams, holiday revisions, and clock recomputation without gaining item payload access.
  • Requester is admitted as a producer only through an exact reviewProducers identity binding. It creates and follows only requests inside that binding and cannot claim or decide work. A person selecting a producer’s initiatorProfile reads only the history of a request naming them as its initiator.

Review result feeds expose stable event identifiers and terminal results without reviewer identity or private reasons. The separate accountability read returns raw issuer-qualified actor identity and private reason only to an authorized Supervisor, records that read in the audit journal, and stops returning the record after accountability expiry. A reviewer who loses a decide response reads the task again instead: GET /v1/review-tasks/{taskId} on a decided task carries decidedByCaller, true only when the current caller recorded that decision, and names no other reviewer. The member is absent from a task in any other state and from the task list.

The implementation is the source of truth, and the generated document is the published form of it. The product generator builds the OpenAPI document from Rust-owned DTOs, problem codes, route inventory, extraction rules, and operation contracts, and declares the API version v1alpha1. The product check regenerates the document and refuses byte drift. A running Casework process serves the routes in that document, and does not serve the document itself.

The problem code table is generated from maintained data checked against the runtime catalogue by the product test suite. The route families table, the header rules, and the profile list are maintained by hand against the cited source.