Unreleased documentation. These pages follow the main branch and can change before the next release. For supported guidance, use v0.44.0.
Look up here which route a caller uses, which headers it sends, and how a refusal recovers. Every
parameter, schema, and status is in the generated Casework API operations, rendered
from
registry-casework.openapi.json;
the service does not serve that document. API stability states the versioning contract.
Routes
Section titled “Routes”The caller is the role of the access profile the call selects: requester for a producer,
staff and supervisor for reviewers, administrator for the directory owner. A role that a row
does not name is refused with operation.not-authorized.
| Method | Path | Caller | Returns |
|---|---|---|---|
| GET | /health, /ready | Anyone, no token | 200; /ready answers 503 while storage or the audit journal is unavailable |
| GET | /.well-known/jwks.json | Anyone, no token | Keys that verify task assertions |
| GET | /v1/casework | Any profile | The deployed project, without providers, calendars, or clocks for a requester |
| GET | /v1/review-policies, /v1/review-policies/{policy_id} | Any profile | The compiled ReviewPolicy closures the caller may use |
| POST | /v1/review-requests | Requester | 201 with the accepted ReviewRequest, 200 on recovery |
| GET | /v1/review-requests/{request_id} | Requester | The request’s state |
| POST | /v1/review-requests/{request_id}/cancel | Requester | The cancellation |
| GET | /v1/review-requests/{request_id}/result | Requester | 200 with the ReviewResult; bodiless 202 pending, 410 erased |
| GET | /v1/review-results | Requester | A resumable page of settled results |
| GET | /v1/review-requests/{request_id}/history, /clocks | Reviewer or requester | History; clocks |
| POST | /v1/review-requests/{request_id}/notes | Reviewer; requester for requester-audience notes | The entry |
| GET | /v1/review-tasks, /next, /holdings, /own-decisions | Staff, supervisor | ReviewTasks |
| GET | /v1/review-tasks/supervision | Supervisor | Tasks in served queues |
| GET | /v1/review-tasks/{task_id}, /context | Staff, supervisor | The task; its review context |
| POST | /v1/review-tasks/{task_id}/claim, /release | Staff, supervisor | The task |
| POST | /v1/review-tasks/{task_id}/assign | Supervisor serving the queue | The task |
| POST | /v1/review-tasks/{task_id}/delegate | A reviewer whose profile decides the stage | The task |
| GET, PUT, DELETE | /v1/review-tasks/{task_id}/draft | The holder | The private draft; 204 on delete |
| POST | /v1/review-tasks/{task_id}/decisions | The holder | 204 |
| GET | /v1/review-tasks/{task_id}/task-templates | Staff, supervisor | Task grant previews |
| GET, POST | /v1/review-tasks/{task_id}/task-grants | Staff, supervisor | Grants on the task; the approved grant |
| POST | /v1/review-tasks/{task_id}/task-grants/{grant_id}/revoke | Staff, supervisor | The revocation |
| POST | /v1/task-grants/{grant_id}/assertion | The grant’s agent, scope casework:grants:assert | A signed task assertion |
| GET | /v1/task-grants/{grant_id}/status | A service, scope casework:grants:status | Current status |
| GET | /v1/review-accountability/{event_id} | Supervisor | The accountability record |
| GET, PUT | /v1/directory, /v1/directory/teams/{team_id}; POST /v1/directory/bootstrap | Administrator | The directory |
| GET | /v1/directory/targets | By purpose | Nameable people and queues |
| GET, POST, PUT, DELETE | /v1/directory/absences, /{absence_id} | Staff for self, supervisor for team, administrator | Absences |
| POST, GET | /v1/directory/holidays, /{id}/revisions/{revision} | Administrator | Holiday set revisions |
| POST | /v1/directory/clocks/recompute/preview, /apply | Administrator | Preview, then result |
| POST | /v1/directory/caseload/preview, /apply | Supervisor | Preview, then result |
Activation has no HTTP route: caseworkctl apply activates a
package (Deploy Registry Casework).
Headers
Section titled “Headers”| Header | Sent on | Rule |
|---|---|---|
Authorization: Bearer <token> | Every route except /health, /ready, and the key set | A missing, invalid, or expired token is authentication.refused (401) |
Registry-Review-Profile | The five requester routes: submit, read, cancel, result, results feed | Names the access profile; at most 128 bytes of letters, digits, and ., _, :, - |
Registry-Casework-Profile | Every other authenticated route except /v1/task-grants/* | Same bounds; a profile that does not cover the route is profile.not-authorized (403) |
Registry-Source-Profile | Task, history, clock, note, task grant, caseload, and clock recompute routes, by a reviewer | Selects the reviewer’s source profile; work whose context comes from a context provider requires it (source-profile.required) |
If-Match: "<revision>" | Task mutations and directory mutations | The revision you read, quoted; "0" creates a directory entry. Missing is precondition.required (428), stale is precondition.failed (412) |
Idempotency-Key | Every mutation except previews, the two /apply routes, and grant revocation | 1 to 128 printable ASCII bytes, kept with the request body for recovery |
traceparent | Any route, optional | W3C trace context; every response carries one |
A profile selects authority the token already holds and adds no scope. The /v1/task-grants/*
routes take a bare service token: either profile header there is authentication.refused.
Registry-Source-Profile is source-profile.not-applicable on the requester routes, the policy
routes, /v1/directory/targets, task release, and accountability, and from a requester on
history, clocks, and notes. Every response carries Cache-Control: no-store.
Policy pins and retries
Section titled “Policy pins and retries”POST /v1/review-requests names a policy id. Omit version and digest to take the
ReviewPolicy active at admission, or send both to require the identity that
GET /v1/review-policies/{policy_id} returned; a differing pin is review.policy-mismatch. The
ReviewResult repeats the accepted binding with the subject and submissionDigest; the consumer
checks that correlation and authorizes any business change itself.
After a lost response, resend the same Idempotency-Key and the same body: the first submission
answered 201, the resend 200 with the same requestId. A changed body under that key is
idempotency.key-reused, and a fresh key is a fresh operation. A 503 on a mutation does not say
whether the change committed, so recover it the same way before you choose another operation.
Problems
Section titled “Problems”A refusal is application/problem+json with type, title, status, a fixed detail, a closed
code, and a traceId, and echoes nothing you sent. A validation refusal names the field and
the reason in registry-casework-validation-path and registry-casework-validation-reason, plus
the accepted values in registry-casework-validation-allowed when the field takes a closed set;
requester routes spell the first two registry-review-validation-path and
registry-review-validation-reason. Give your operator the traceId, never a token or a body.
The table lists every code the Rust, Node.js, and Python clients recognize. A code outside it comes from a newer service; treat it by its status.
| Code | Status | When |
|---|---|---|
absence.cover-cycle | 422 | Choose cover assignments that do not return to an earlier person during a shared period. |
absence.invalid-period | 422 | Set until later than from. |
absence.overlap | 422 | Adjust the period so this person has no overlapping absence. |
absence.self-cover | 422 | Choose a different staff member as cover. |
authentication.refused | 401 | The bearer credential is missing, invalid, or expired. Sign in again. |
clock.recompute-preview-expired | 410 | Create a new recompute preview and review it before applying. |
cursor.expired | 410 | This cursor has expired. Start again without a cursor and deduplicate entries by eventId. |
cursor.invalid | 400 | The cursor is invalid for this request. |
idempotency.expired | 410 | The stored response for this idempotency key has expired. Reconcile the original operation before choosing a new key. |
idempotency.key-reused | 409 | This idempotency key was used for a different request. |
operation.not-authorized | 403 | Your current Casework authority does not allow this operation. |
precondition.failed | 412 | The item or directory changed since you loaded it. Reload and try again. |
precondition.required | 428 | This mutation requires the revision that you loaded. |
profile.not-authorized | 403 | The selected Casework profile does not authorize this request. |
profile.not-human | 403 | This action is reserved for a human session. |
request.body-too-large | 413 | The request body exceeds the one MiB limit. |
request.invalid | 400 | The Casework request is invalid. |
request.limit-out-of-range | 400 | The limit query parameter must be from 1 to 100, or from 1 to 1000 on the directory absence list. Omit it for the default page size. |
request.method-not-allowed | 405 | This route does not accept that HTTP method. |
request.not-found | 404 | The requested Casework route does not exist. |
request.unprocessable | 422 | The request body does not match the Casework contract. |
request.unsupported-media-type | 415 | Send a JSON request body with Content-Type application/json. |
review.distinct-approver-required | 403 | Each approval in this stage must be supplied by a different reviewer. |
review.initiator-excluded | 403 | You submitted this request, and this review stage excludes the person who submitted it. Another reviewer must take it. |
review.initiator-required | 422 | This review policy excludes the person who submitted the request, so the request must name its initiator. |
review.policy-mismatch | 409 | The expected review policy binding does not match the active policy. |
review.query-too-broad | 422 | Narrow the queue or exact subject query to complete it within the configured read budget. |
review.result-expired | 410 | The retained review result is no longer available. Reconcile through the producer's retained source correlation. |
review.submission-conflict | 409 | The same producer, source subject, version, and policy were already submitted with different canonical content. |
review.task-not-held | 409 | Claim the review task before deciding it, and decide only while the claim remains current. |
runtime.failure | 500 | Casework could not complete the request. |
service.unavailable | 503 | Casework storage is unavailable. Try again after the service recovers. |
source-profile.not-applicable | 400 | Omit the Registry-Source-Profile header for this request. |
source-profile.required | 400 | Send the Registry-Source-Profile header to select the source profile for this request. |
source.bad-gateway | 502 | The source returned a response that does not match its registered contract. |
source.version-mismatch | 502 | Deploy the same Registry Stack version for Casework and its source. |
source.version-unavailable | 502 | The source did not report its engine version. Deploy matching Registry Stack versions. |
Cookies on Registry Stack
We use optional cookies to understand how you use the main Registry Stack website and this documentation. If you contact us, we may link this activity to your enquiry. You can change your choice at any time. Read the privacy policy.
Your browser asks sites not to track you, so optional tracking stays off.
We could not use or save that choice. Optional tracking remains off.