#API reference
Generated from the live API’s OpenAPI spec. Every field below is enforced by the route’s zod schema, so this reference cannot drift. All requests are authenticated with Authorization: Bearer <api-key>. Base URL: https://api.ratifia.com.
Try requests interactively in the API explorer, or grab the machine-readable /openapi.json for Postman / Insomnia / codegen. It carries the full nested schemas (e.g. the policy defaults and decision context shapes) that the tables below summarize.
#Approvers
#POST /v1/approvers/
Register an approver
Admin-initiated registration. Creates a person with declared channels/methods; email/inbox are auto-verified, the rest land pending until the approver self-verifies. Idempotent per (org, email).
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
email | string | yes | |
name | string | no | |
clerkUserId | string | no | |
channels | object[] | no | |
methods | object[] | no |
#GET /v1/approvers/
List approvers
All approver identities for the org, with channel + method verification state.
#GET /v1/approvers/{id}
Get an approver
Parameters:
| Param | In | Required | Type |
|---|---|---|---|
id | path | yes | string |
#POST /v1/approvers/{id}/verify
Verify an approver capability
Self-serve completion: mark a declared channel or surface verified (or failed), persisting the proven endpoint/ref. Real per-channel proof (OTP, Slack lookup, DocuSign mapping) plugs in here.
Parameters:
| Param | In | Required | Type |
|---|---|---|---|
id | path | yes | string |
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
channel | email | slack | discord | phone | sms | webhook | no | |
surface | inbox | slack | discord | docusign | email | api | no | |
endpoint | string | no | |
resolvedRef | string | no | |
status | verified | failed | no |
#POST /v1/approvers/{id}/disable
Disable an approver
Soft-disable. The approver stops binding any surface and is never routed a decision. Policies naming them still resolve, but report as unsatisfiable, returned in warnings. Reversible via /enable. Idempotent.
Parameters:
| Param | In | Required | Type |
|---|---|---|---|
id | path | yes | string |
#POST /v1/approvers/{id}/enable
Re-enable a disabled approver
Clears the disable. Registration deliberately does not do this, because bringing someone back is an explicit act. Idempotent.
Parameters:
| Param | In | Required | Type |
|---|---|---|---|
id | path | yes | string |
#Decisions
#GET /v1/decisions/
List decisions (reviewer inbox)
List decisions for the org, newest first. Filter by status and assignee email for the reviewer inbox.
Parameters:
| Param | In | Required | Type |
|---|---|---|---|
status | query | no | PENDING | APPROVED | REJECTED | EXPIRED | CANCELLED |
assignee | query | no | string |
workflowRef | query | no | string |
limit | query | no | integer |
offset | query | no | integer |
#GET /v1/decisions/workflows
Distinct workflows for the inbox filter
Parameters:
| Param | In | Required | Type |
|---|---|---|---|
assignee | query | no | string |
#GET /v1/decisions/{id}
Get a decision with its quorum tally
Parameters:
| Param | In | Required | Type |
|---|---|---|---|
id | path | yes | string |
#POST /v1/decisions/{id}/evidence
Attach immutable evidence to a decision
Append material the decision is being made ON — a Slack thread, an email, a policy doc. Append-only: evidence is never edited or deleted, and can only be attached while the decision is PENDING. Once it resolves the set is sealed, so what you see is exactly what the approver could see. Re-attaching identical content is a no-op.
Parameters:
| Param | In | Required | Type |
|---|---|---|---|
id | path | yes | string |
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
kind | slack_thread | email | document | link | note | yes | |
title | string | no | |
sourceSystem | string | no | |
sourceUrl | string | no | |
sourceRef | object | no | |
body | string | no | |
bodyFormat | text | markdown | no | |
payload | object | no | |
capturedAt | string | no |
#GET /v1/decisions/{id}/evidence
List a decision’s evidence, oldest first
Parameters:
| Param | In | Required | Type |
|---|---|---|---|
id | path | yes | string |
#PUT /v1/decisions/{id}/output
Save the reviewer’s refined draft (conversational refinement)
Persist an edited version of a refinable decision’s proposed output. On approve, the engine resumes with the refined draft (refinedOutput ?? proposedOutput). Only allowed while the decision is PENDING and carries a proposedOutput.
Parameters:
| Param | In | Required | Type |
|---|---|---|---|
id | path | yes | string |
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
title | string | no | |
format | text | markdown | no | |
content | string | yes |
#POST /v1/decisions/{id}/refine
Refine the draft with the org’s own model (BYO)
Apply the reviewer’s feedback to the current draft using the org’s configured LLM (Settings → Refine with AI). Returns the revised draft and appends the turn to the refinement log. Does not commit: the reviewer saves via PUT /output, then approves.
Parameters:
| Param | In | Required | Type |
|---|---|---|---|
id | path | yes | string |
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
feedback | string | yes |
#POST /v1/decisions/{id}/decide
Approve or reject a decision
Record a vote. Under quorum the decision resolves only when the approval/rejection threshold is met; reject-wins by default. On resolution Ratifia fires the engine resume event.
Parameters:
| Param | In | Required | Type |
|---|---|---|---|
id | path | yes | string |
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
decision | approve | reject | yes | |
note | string | no | |
responseValue | one of | no |
#Directory
#GET /v1/directory/actor
Resolve an internal actor id to a display label
Parameters:
| Param | In | Required | Type |
|---|---|---|---|
ref | query | yes | string |
#Notifications
#GET /v1/contact-methods/
Get my contact methods
#PUT /v1/contact-methods/
Update my contact methods
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
email | string | no | |
sms | string | no | |
slack | string | no | |
pushEnabled | boolean | no |
#POST /v1/push-devices/
Register this device for push
Idempotent on (user, token), so it is safe to call on every launch. The client should do exactly that, because push tokens rotate on reinstall and restore. Re-registering a revoked device reactivates it.
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
token | string | yes | |
platform | ios | android | yes | |
deviceName | string | no |
#GET /v1/push-devices/
List my registered devices
#DELETE /v1/push-devices/{id}
Revoke one of my devices
Soft-revoke. Call on sign-out, otherwise the next person to sign in on that handset keeps receiving the previous user’s notifications.
Parameters:
| Param | In | Required | Type |
|---|---|---|---|
id | path | yes | string |
#Policies
#GET /v1/policies/
List approval policies
All approval policies for the org, each with its usage: pending decisions under it and when it was last used (FN-256).
#POST /v1/policies/
Create (or upsert) an approval policy
Create an org-scoped approval policy: who approves (approver group + quorum) and the surface the verdict is recorded on. Idempotent upsert keyed by (org, key). key is the immutable slug code references; name and description are editable labels. A body with only name is read as key = name. Rejects unsatisfiable policies with 422.
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
name | string | no | |
description | string | no | |
defaults | object | no | |
key | string | no |
#GET /v1/policies/{key}
Get an approval policy by key
Parameters:
| Param | In | Required | Type |
|---|---|---|---|
key | path | yes | string |
#PUT /v1/policies/{key}
Update an approval policy
Replace an existing policy’s defaults, and optionally its name and description. The key never changes: to use a different key, create a new policy. 404 if it does not exist. Rejects unsatisfiable policies with 422.
Parameters:
| Param | In | Required | Type |
|---|---|---|---|
key | path | yes | string |
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
name | string | no | |
description | string | no | |
defaults | object | no |
#DELETE /v1/policies/{key}
Delete an approval policy
Refused with 409 policy_in_use while the policy has pending decisions or was used in the last 30 days, because code likely still references its key and would start failing with unknown_policy. Pass force=true to delete anyway; the override is audited.
Parameters:
| Param | In | Required | Type |
|---|---|---|---|
force | query | no | true | false |
key | path | yes | string |
#Runs
#POST /v1/runs/
Trigger a workflow run
Fire the external engine event for a registered workflow. Ratifia seeds no run/step rows; the engine owns execution and Ratifia tracks the decisions requested on the run.
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
workflowId | string | yes | |
input | object | no | |
idempotencyKey | string | no | |
timeoutSec | integer | no |
#Worker
#POST /v1/worker/register
Register (upsert) a workflow definition
SDK/worker self-registration. Idempotent upsert keyed by workflow id for the API key’s org.
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
id | string | yes | |
name | string | no | |
version | integer | no | |
engine | bundled | inngest | temporal | trigger | no | |
steps | object[] | yes |
#POST /v1/worker/decisions
Open a HITL decision (decision-first model)
Called by an engine adapter (e.g. flowplane.awaitApproval) to request a human decision for an external-engine run. The policy gate may resolve "not required", in which case approvalNeeded=false and no decision is created.
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
engine | bundled | inngest | temporal | trigger | mcp | api | no | |
externalRunId | string | yes | |
stepRef | string | yes | |
workflowRef | string | no | |
assigneeEmail | string | no | |
policy | string | no | |
required | boolean | no | |
context | object | no | |
proposedOutput | object | no | |
responseSpec | one of | no | |
docusign | object | no | |
timeoutSec | integer | no | |
exclusive | boolean | no | |
factsHash | string | no |
#GET /v1/worker/decisions
List decisions (API-key scope): the agent's inbox
Parameters:
| Param | In | Required | Type |
|---|---|---|---|
status | query | no | PENDING | APPROVED | REJECTED | EXPIRED | CANCELLED |
limit | query | no | integer |
#GET /v1/worker/decisions/{id}
Get a decision status (API-key scope): poll a park-and-resume verdict
Parameters:
| Param | In | Required | Type |
|---|---|---|---|
id | path | yes | string |
#GET /v1/worker/decisions/{id}/verify
Verify an approval before acting on it (API-key scope)
Read-only check that a decision authorizes an action right now: APPROVED, facts hash matches, optional workflow/step match, and not already consumed. Always returns 200 with valid and, when invalid, a reason: not_found, not_approved, facts_mismatch, workflow_mismatch, step_mismatch, or consumed. Use consume to spend the approval.
Parameters:
| Param | In | Required | Type |
|---|---|---|---|
factsHash | query | no | string |
workflowRef | query | no | string |
stepRef | query | no | string |
id | path | yes | string |
#POST /v1/worker/decisions/{id}/consume
Consume an approval: authorize exactly one action (API-key scope)
Atomically marks an APPROVED decision as spent by one action. Succeeds once per decision; a retry with the same consumer key returns consumed=true with alreadyConsumed=true, while a different consumer is refused with reason consumed. Refused with the same reasons as verify when the approval does not authorize the action.
Parameters:
| Param | In | Required | Type |
|---|---|---|---|
id | path | yes | string |
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
factsHash | string | no | |
workflowRef | string | no | |
stepRef | string | no | |
consumer | string | yes |
#POST /v1/worker/decisions/{id}/cancel
Cancel a pending decision (API-key scope)
Withdraw a decision the agent no longer needs. Only PENDING decisions cancel; an already-resolved one returns cancelled=false with its current status.
Parameters:
| Param | In | Required | Type |
|---|---|---|---|
id | path | yes | string |
#POST /v1/worker/policies/check
Check that policy keys exist and can reach quorum (API-key scope)
Preflight for CI. For each key: ok, missing, or unsatisfiable (with the reason and any approvers who still need verifying). ok is true only if every key is ok.
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
keys | string[] | yes |
#POST /v1/worker/policies
Upsert a named approval policy
Declare an org-scoped approval policy as code: who approves (assignee, approver group, quorum) and the surface. Idempotent upsert keyed by (org, key); key is the immutable slug decisions reference, name and description are editable labels. A body with only name is read as key = name.
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
name | string | no | |
description | string | no | |
defaults | object | no | |
key | string | no |