Unified Interaction Requests API (adapter-agnostic) — OpenAPI 1.0.0
<!-- GENERATED by scripts/render-platform-map-api-docs.mjs — do not hand-edit; edit apps/agent-bff/openapi/<spec>.json and re-run. --> Scope: The published reference for Unified Interaction Requests API (adapter-agnostic). 9 paths — the measured spec-vs-implementation coverage lives in the complete API inventory. Status: rendered 2026-11-09 from the OpenAPI source for Unified Interaction Requests API (adapter-agnostic) — regenerate with node scripts/render-platform-map-api-docs.mjs. See also: the OpenAPI spec index.
Servers
| URL | Notes |
|---|---|
| https://dev.agent.jijibora.online | Dokku DEV Agent BFF |
| https://uat.agent.jijibora.online | Dokku UAT Agent BFF |
| http://127.0.0.1:3030 | Local laptop only — not for public codegen |
Tags
| Tag | Summary |
|---|---|
| requests-lifecycle | Create, list, read, fork, and tree interaction requests |
| requests-governance | Governed transitions, participants, and links |
| requests-voyage | Outbox voyage projection by correlation |
Paths — 9 paths / 10 operations
| Method | Path | Operation ID | Summary |
|---|---|---|---|
| POST | /v1/requests | createInteractionRequest | Create an interaction request |
| GET | /v1/requests | listInteractionRequests | List requests |
| GET | /v1/requests/{requestId} | getInteractionRequest | Read one request (projection + links, no vendor fields) |
| POST | /v1/requests/{requestId}/transition | transitionInteractionRequest | Governed transition |
| POST | /v1/requests/{requestId}/messages | appendRequestMessage | Append an interaction message |
| POST | /v1/requests/{requestId}/assign | assignRequestParticipant | Assign a participant |
| POST | /v1/requests/{requestId}/fork | forkInteractionRequest | Create a child request |
| GET | /v1/requests/{requestId}/tree | getRequestTree | Read the fork tree |
| POST | /v1/requests/{requestId}/links | attachRequestLink | Attach a linked record (claim, order, sourcing, entity, incident) |
| GET | /v1/requests/{requestId}/events | getRequestEvents | Outbox voyage projection for the request |
Operations
POST /v1/requests
Summary: Create an interaction request Description: Creates a canonical claim-backed request. cns_type selects the scenario shape (request/support, request/emergency, request/commerce, request/community, request/claim_assist, request/gov). Emergency scenarios require the emergency profile fields.
Tags: requests-lifecycle Operation ID: createInteractionRequest Request body:
Content type: application/json
| Field | Type | Notes |
|---|---|---|
| cns_type | string | |
| cns_version | string | |
| scope_id | string | |
| tenant_slug | string | |
| requester_id | string | |
| owner_id | string | |
| correlation_id | string | Voyage across forks and downstream; minted deterministically when omitted |
| parent_request_id | string | Set by fork; null on roots |
| fork_kind | string enum: none, mutual_aid, multi_agency, subtask, escalation, commerce_split | |
| intent | object | |
| intent.summary | string | |
| intent.desired_outcome | string | |
| intent.quantum | string | |
| priority | string enum: low, normal, high, critical | |
| severity | string | |
| urgency | string | Emergency profile: required for request/emergency |
| certainty | string | Emergency profile: required for request/emergency |
| event_codes | string[] | |
| geo | object | S2 cell, polygon, or circle for area alerts and dispatch |
| geo.s2_cell | string | |
| geo.polygon | number[] | |
| geo.radius_km | number | |
| onset | string (date-time) | |
| expires | string (date-time) | |
| thread_ref | string | Opaque chat/thread handle — never a vendor ticket id as primary key |
| integration_refs | object[] | Opaque external references (adapter_class from the allowlist; never a product brand) |
| integration_refs.adapter_class | string enum: workbench, commerce, fleet, housing, erp, payments, identity_registry, content_authority,… | |
| integration_refs.external_ref | string |
Responses:
| Status | Meaning |
|---|---|
| 201 | Request created; returns request_id plus its canonical claim binding |
| 400 | cns_type/requester_id/intent missing, or emergency profile incomplete |
GET /v1/requests
Summary: List requests
Tags: requests-lifecycle Operation ID: listInteractionRequests
Parameters:
| Name | In | Required | Type | Notes |
|---|---|---|---|---|
| scope_id | query | no | string | |
| state | query | no | string | |
| cns_type | query | no | string | |
| correlation_id | query | no | string |
Responses:
| Status | Meaning |
|---|---|
| 200 | Projection list (possibly empty) |
GET /v1/requests/{requestId}
Summary: Read one request (projection + links, no vendor fields)
Tags: requests-lifecycle Operation ID: getInteractionRequest
Parameters:
| Name | In | Required | Type | Notes |
|---|---|---|---|---|
| requestId | path | yes | string |
Responses:
| Status | Meaning |
|---|---|
| 200 | Scrubbed projection (indexability/query profile enforced) |
| 404 | request_not_found |
POST /v1/requests/{requestId}/transition
Summary: Governed transition Description: Transitions are governed where packs require gates/quorum and always emit an outbox event. Lifecycle: received, triaged/qualified, in_progress, waiting, forked, resolved/fulfilled/failed/cancelled/breached, closed.
Tags: requests-governance Operation ID: transitionInteractionRequest
Parameters:
| Name | In | Required | Type | Notes |
|---|---|---|---|---|
| requestId | path | yes | string |
Request body:
Content type: application/json
| Field | Type | Notes |
|---|---|---|
| to_state | string | |
| actor_id | string | |
| notes | string |
Responses:
| Status | Meaning |
|---|---|
| 200 | Transition applied |
| 404 | request_not_found |
| 422 | Governed gate/quorum refused the transition |
POST /v1/requests/{requestId}/messages
Summary: Append an interaction message
Tags: requests-governance Operation ID: appendRequestMessage
Parameters:
| Name | In | Required | Type | Notes |
|---|---|---|---|---|
| requestId | path | yes | string |
Request body:
Content type: application/json
| Field | Type | Notes |
|---|---|---|
| author_id | string | |
| body | string | |
| thread_ref | string |
Responses:
| Status | Meaning |
|---|---|
| 201 | Message appended |
| 404 | request_not_found |
POST /v1/requests/{requestId}/assign
Summary: Assign a participant
Tags: requests-governance Operation ID: assignRequestParticipant
Parameters:
| Name | In | Required | Type | Notes |
|---|---|---|---|---|
| requestId | path | yes | string |
Request body:
Content type: application/json
| Field | Type | Notes |
|---|---|---|
| participant_id | string | |
| role | string | |
| scope_id | string |
Responses:
| Status | Meaning |
|---|---|
| 200 | Participant assigned |
| 404 | request_not_found |
POST /v1/requests/{requestId}/fork
Summary: Create a child request Description: Children inherit correlation_id; parent_request_id + fork_kind are set. Child scope cannot widen the parent ceiling.
Tags: requests-lifecycle Operation ID: forkInteractionRequest
Parameters:
| Name | In | Required | Type | Notes |
|---|---|---|---|---|
| requestId | path | yes | string |
Request body:
Content type: application/json
| Field | Type | Notes |
|---|---|---|
| fork_kind | string enum: mutual_aid, multi_agency, subtask, escalation, commerce_split | |
| scope_id | string | |
| intent | object |
Responses:
| Status | Meaning |
|---|---|
| 201 | Child request created |
| 404 | request_not_found |
| 422 | Child scope would widen the parent ceiling |
GET /v1/requests/{requestId}/tree
Summary: Read the fork tree
Tags: requests-lifecycle Operation ID: getRequestTree
Parameters:
| Name | In | Required | Type | Notes |
|---|---|---|---|---|
| requestId | path | yes | string |
Responses:
| Status | Meaning |
|---|---|
| 200 | Parent/children tree |
| 404 | request_not_found |
POST /v1/requests/{requestId}/links
Summary: Attach a linked record (claim, order, sourcing, entity, incident)
Tags: requests-governance Operation ID: attachRequestLink
Parameters:
| Name | In | Required | Type | Notes |
|---|---|---|---|---|
| requestId | path | yes | string |
Request body:
Content type: application/json
| Field | Type | Notes |
|---|---|---|
| claim_id | string | |
| order_id | string | |
| sourcing_requirement_id | string | |
| entity_id | string | |
| incident_id | string | |
| health_lease_ref | string | |
| resources | string[] |
Responses:
| Status | Meaning |
|---|---|
| 200 | Link attached |
| 404 | request_not_found |
GET /v1/requests/{requestId}/events
Summary: Outbox voyage projection for the request
Tags: requests-voyage Operation ID: getRequestEvents
Parameters:
| Name | In | Required | Type | Notes |
|---|---|---|---|---|
| requestId | path | yes | string |
Responses:
| Status | Meaning |
|---|---|
| 200 | Voyage events (empty when nothing emitted) |
| 404 | request_not_found |
Full specification — verbatim source of truth
{
"openapi": "3.1.0",
"info": {
"title": "Unified Interaction Requests API (adapter-agnostic)",
"version": "1.0.0",
"description": "One governed request spine for support, emergency, commerce, community, and claim assistance — across all adapters. Public responses are vendor-neutral: external systems appear only as opaque integration_refs with an opaque adapter_class from the allowlist (workbench, commerce, fleet, housing, erp, payments, identity_registry, content_authority, credential_board, safety, notify, psap). Requests are canonical claims under cns://claim/type/request/... ; transitions are governed (gates/quorum where packs require) and always emit outbox events. Emergency requests carry the emergency profile (urgency, certainty, event codes, geo, onset, expires) and may derive open emergency standards by derivation without forking the IR schema. Soft≠LIVE: LIVE governed execution is never invented by this desk."
},
"servers": [
{
"url": "https://dev.agent.jijibora.online",
"description": "Dokku DEV Agent BFF"
},
{
"url": "https://uat.agent.jijibora.online",
"description": "Dokku UAT Agent BFF"
},
{
"url": "http://127.0.0.1:3030",
"description": "Local laptop only — not for public codegen"
}
],
"tags": [
{
"name": "requests-lifecycle",
"description": "Create, list, read, fork, and tree interaction requests"
},
{
"name": "requests-governance",
"description": "Governed transitions, participants, and links"
},
{
"name": "requests-voyage",
"description": "Outbox voyage projection by correlation"
}
],
"paths": {
"/v1/requests": {
"post": {
"tags": [
"requests-lifecycle"
],
"summary": "Create an interaction request",
"description": "Creates a canonical claim-backed request. cns_type selects the scenario shape (request/support, request/emergency, request/commerce, request/community, request/claim_assist, request/gov). Emergency scenarios require the emergency profile fields.",
"operationId": "createInteractionRequest",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"cns_type",
"requester_id",
"intent"
],
"properties": {
"cns_type": {
"type": "string",
"example": "cns://claim/type/request/emergency"
},
"cns_version": {
"type": "string",
"example": "1.0.0"
},
"scope_id": {
"type": "string",
"example": "scope:county:ops"
},
"tenant_slug": {
"type": "string",
"example": "county-ops"
},
"requester_id": {
"type": "string",
"example": "person:citizen_4812"
},
"owner_id": {
"type": "string",
"example": "org:county_ops"
},
"correlation_id": {
"type": "string",
"description": "Voyage across forks and downstream; minted deterministically when omitted"
},
"parent_request_id": {
"type": "string",
"description": "Set by fork; null on roots"
},
"fork_kind": {
"type": "string",
"enum": [
"none",
"mutual_aid",
"multi_agency",
"subtask",
"escalation",
"commerce_split"
]
},
"intent": {
"type": "object",
"properties": {
"summary": {
"type": "string"
},
"desired_outcome": {
"type": "string"
},
"quantum": {
"type": "string"
}
}
},
"priority": {
"type": "string",
"enum": [
"low",
"normal",
"high",
"critical"
]
},
"severity": {
"type": "string"
},
"urgency": {
"type": "string",
"description": "Emergency profile: required for request/emergency"
},
"certainty": {
"type": "string",
"description": "Emergency profile: required for request/emergency"
},
"event_codes": {
"type": "array",
"items": {
"type": "string"
}
},
"geo": {
"type": "object",
"description": "S2 cell, polygon, or circle for area alerts and dispatch",
"properties": {
"s2_cell": {
"type": "string"
},
"polygon": {
"type": "array",
"items": {
"type": "number"
}
},
"radius_km": {
"type": "number"
}
}
},
"onset": {
"type": "string",
"format": "date-time"
},
"expires": {
"type": "string",
"format": "date-time"
},
"thread_ref": {
"type": "string",
"description": "Opaque chat/thread handle — never a vendor ticket id as primary key"
},
"integration_refs": {
"type": "array",
"description": "Opaque external references (adapter_class from the allowlist; never a product brand)",
"items": {
"type": "object",
"required": [
"adapter_class",
"external_ref"
],
"properties": {
"adapter_class": {
"type": "string",
"enum": [
"workbench",
"commerce",
"fleet",
"housing",
"erp",
"payments",
"identity_registry",
"content_authority",
"credential_board",
"safety",
"notify",
"psap"
]
},
"external_ref": {
"type": "string"
}
}
}
}
}
}
}
}
},
"responses": {
"201": {
"description": "Request created; returns request_id plus its canonical claim binding"
},
"400": {
"description": "cns_type/requester_id/intent missing, or emergency profile incomplete"
}
}
},
"get": {
"tags": [
"requests-lifecycle"
],
"summary": "List requests",
"operationId": "listInteractionRequests",
"parameters": [
{
"name": "scope_id",
"in": "query",
"schema": {
"type": "string"
}
},
{
"name": "state",
"in": "query",
"schema": {
"type": "string"
}
},
{
"name": "cns_type",
"in": "query",
"schema": {
"type": "string"
}
},
{
"name": "correlation_id",
"in": "query",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Projection list (possibly empty)"
}
}
}
},
"/v1/requests/{requestId}": {
"get": {
"tags": [
"requests-lifecycle"
],
"summary": "Read one request (projection + links, no vendor fields)",
"operationId": "getInteractionRequest",
"parameters": [
{
"name": "requestId",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Scrubbed projection (indexability/query profile enforced)"
},
"404": {
"description": "request_not_found"
}
}
}
},
"/v1/requests/{requestId}/transition": {
"post": {
"tags": [
"requests-governance"
],
"summary": "Governed transition",
"description": "Transitions are governed where packs require gates/quorum and always emit an outbox event. Lifecycle: received, triaged/qualified, in_progress, waiting, forked, resolved/fulfilled/failed/cancelled/breached, closed.",
"operationId": "transitionInteractionRequest",
"parameters": [
{
"name": "requestId",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"to_state"
],
"properties": {
"to_state": {
"type": "string",
"example": "triaged"
},
"actor_id": {
"type": "string"
},
"notes": {
"type": "string"
}
}
}
}
}
},
"responses": {
"200": {
"description": "Transition applied"
},
"404": {
"description": "request_not_found"
},
"422": {
"description": "Governed gate/quorum refused the transition"
}
}
}
},
"/v1/requests/{requestId}/messages": {
"post": {
"tags": [
"requests-governance"
],
"summary": "Append an interaction message",
"operationId": "appendRequestMessage",
"parameters": [
{
"name": "requestId",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"author_id",
"body"
],
"properties": {
"author_id": {
"type": "string"
},
"body": {
"type": "string"
},
"thread_ref": {
"type": "string"
}
}
}
}
}
},
"responses": {
"201": {
"description": "Message appended"
},
"404": {
"description": "request_not_found"
}
}
}
},
"/v1/requests/{requestId}/assign": {
"post": {
"tags": [
"requests-governance"
],
"summary": "Assign a participant",
"operationId": "assignRequestParticipant",
"parameters": [
{
"name": "requestId",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"participant_id",
"role"
],
"properties": {
"participant_id": {
"type": "string"
},
"role": {
"type": "string",
"example": "responder"
},
"scope_id": {
"type": "string"
}
}
}
}
}
},
"responses": {
"200": {
"description": "Participant assigned"
},
"404": {
"description": "request_not_found"
}
}
}
},
"/v1/requests/{requestId}/fork": {
"post": {
"tags": [
"requests-lifecycle"
],
"summary": "Create a child request",
"description": "Children inherit correlation_id; parent_request_id + fork_kind are set. Child scope cannot widen the parent ceiling.",
"operationId": "forkInteractionRequest",
"parameters": [
{
"name": "requestId",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"fork_kind",
"scope_id"
],
"properties": {
"fork_kind": {
"type": "string",
"enum": [
"mutual_aid",
"multi_agency",
"subtask",
"escalation",
"commerce_split"
]
},
"scope_id": {
"type": "string"
},
"intent": {
"type": "object"
}
}
}
}
}
},
"responses": {
"201": {
"description": "Child request created"
},
"404": {
"description": "request_not_found"
},
"422": {
"description": "Child scope would widen the parent ceiling"
}
}
}
},
"/v1/requests/{requestId}/tree": {
"get": {
"tags": [
"requests-lifecycle"
],
"summary": "Read the fork tree",
"operationId": "getRequestTree",
"parameters": [
{
"name": "requestId",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Parent/children tree"
},
"404": {
"description": "request_not_found"
}
}
}
},
"/v1/requests/{requestId}/links": {
"post": {
"tags": [
"requests-governance"
],
"summary": "Attach a linked record (claim, order, sourcing, entity, incident)",
"operationId": "attachRequestLink",
"parameters": [
{
"name": "requestId",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"claim_id": {
"type": "string"
},
"order_id": {
"type": "string"
},
"sourcing_requirement_id": {
"type": "string"
},
"entity_id": {
"type": "string"
},
"incident_id": {
"type": "string"
},
"health_lease_ref": {
"type": "string"
},
"resources": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
}
},
"responses": {
"200": {
"description": "Link attached"
},
"404": {
"description": "request_not_found"
}
}
}
},
"/v1/requests/{requestId}/events": {
"get": {
"tags": [
"requests-voyage"
],
"summary": "Outbox voyage projection for the request",
"operationId": "getRequestEvents",
"parameters": [
{
"name": "requestId",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Voyage events (empty when nothing emitted)"
},
"404": {
"description": "request_not_found"
}
}
}
}
},
"x-emergency-profile": {
"description": "Optional emergency profile on request/emergency (plan 40 §1.1): urgency, certainty, event_codes[], geo, onset, expires. Emergency standards are derived from the canonical IR, never forked as the schema.",
"derives": [
"open emergency alert profile",
"distribution envelope",
"situation report",
"tracking profile",
"location profile"
]
},
"x-adapter-classes": {
"allowlist": [
"workbench",
"commerce",
"fleet",
"housing",
"erp",
"payments",
"identity_registry",
"content_authority",
"credential_board",
"safety",
"notify",
"psap"
],
"note": "Opaque adapter classes only (plan 40 §9). Adapter brands stay internal; public docs never enumerate product names."
}
}