{"openapi": "3.1.0", "info": {"title": "Dyadic Platform API", "version": "1.7.1", "description": "Dyadic's platform API: run the account's agents, plan work and carry it out once approved, and record,\ninvestigate and verify what agents do.\n\nAuthenticate with a Dyadic API key: `Authorization: Bearer dya-...`. Each capability is a switch on the key, off until\nthe account's owner turns it on in the Workspace (API keys):\n\n| Switch | What it allows |\n|---|---|\n| (always) | `POST /runs` with the key's agents and tools |\n| `plans` | make, read, revise, approve, cancel and follow this key's plans (`/plans`); runs with `plan_mode` or `plan_id` |\n| `blackbox_record` | record every call this key makes (runs, chat, responses, decisions, AI gateway requests) in the account's Black Box |\n| `blackbox_write` | send Black Box telemetry (events, OTLP, MCP), triage findings, bookmark events |\n| `blackbox_read` | read, verify, export, compare and simulate (from metadata) the runs this key made |\n| `blackbox_content` | read the content kept for them; exports and simulations with content |\n| `blackbox_manage` | delete or erase the runs this key made; manage this key's own sinks |\n\nA key reads only the runs it made: its own platform runs (`POST /runs`, chat completions) and what it sent; and only\nthe plans it made, itself or through its runs. A run the owner deleted answers **410** `run_deleted`. Errors use OpenAI's error object. Ingestion takes an `Idempotency-Key`.\nRecorded events from an application are `reported`, never `observed`; findings are hypotheses; simulations are never\nevidence. `GET /blackbox/keys` and `POST /blackbox/verify` need no key: anyone may verify a bundle.\n", "contact": {"name": "Dyadic", "url": "https://dyadic.app/"}}, "servers": [{"url": "https://dyadic.app/api/v1", "description": "Production"}], "security": [{"bearerAuth": []}], "tags": [{"name": "Runs"}, {"name": "Plans"}, {"name": "Black Box: recording"}, {"name": "Black Box: runs"}, {"name": "Black Box: live"}, {"name": "Black Box: investigation"}, {"name": "Black Box: findings"}, {"name": "Black Box: evidence"}, {"name": "Black Box: privacy"}, {"name": "Black Box: sinks"}, {"name": "Black Box: MCP"}, {"name": "Meta"}], "paths": {"/runs": {"post": {"tags": ["Runs"], "operationId": "createRun", "summary": "Run an agent", "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RunCompleted"}}}}, "400": {"description": "Invalid request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"description": "Missing or invalid API key", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "The key lacks the permission", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "429": {"description": "Rate limit or quota", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Ask one of the account's agents (by id) or the application's own inline agent to answer a conversation, with the built-in tools it allows and the functions the application runs itself (the run then ends `requires_action`). With `stream: true` the events arrive as Server-Sent Events: `run.started`, `run.recording` (its Black Box record), `status`, `tool.started`, `tool.completed`, `plan.updated` (a plan the run made or moved, as `GET /plans/{id}` returns it), `delta`, `sources`, `image.generated`, `audio.generated`, `requires_action`, `run.completed`. A `traceparent` header joins the caller's W3C trace.\n\nPlans (the key's `plans` switch): `plan_mode: true` investigates read-only and proposes a plan (a draft to approve with `POST /plans/{id}/approve`); every tool that would change something is refused. `plan_id` carries out a plan: refused with error code `plan_not_runnable` unless a Plan Mode plan is approved at its current revision. A run that ends with steps left pauses the plan (`plan.interrupted`); another run with the same `plan_id` resumes it. `conversation_id` scopes the application's plans: a run is told about that conversation's plan under way.", "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RunRequest"}}}}}}, "/plans": {"get": {"tags": ["Plans"], "operationId": "listPlans", "summary": "List this key's plans", "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PlanList"}}}}, "400": {"description": "Invalid request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"description": "Missing or invalid API key", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "The key lacks the permission", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "429": {"description": "Rate limit or quota", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Newest change first, without their history (`events`).\n\nNeeds the key's `plans` switch.", "parameters": [{"name": "conversation", "in": "query", "schema": {"type": "string"}, "description": "Only the plans of this conversation (a run's `conversation_id`)."}, {"name": "status", "in": "query", "schema": {"type": "string", "enum": ["draft", "approved", "running", "paused", "completed", "failed", "cancelled"]}}, {"name": "limit", "in": "query", "schema": {"type": "integer", "minimum": 1, "maximum": 100, "default": 20}}, {"name": "after", "in": "query", "schema": {"type": "string", "format": "uuid"}, "description": "A plan id: the page after it (`last_id`)."}]}, "post": {"tags": ["Plans"], "operationId": "createPlan", "summary": "Make a plan", "responses": {"201": {"description": "Created", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Plan"}}}}, "400": {"description": "Invalid request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"description": "Missing or invalid API key", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "The key lacks the permission", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "429": {"description": "Rate limit or quota", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "`mode: plan` (the default) makes a draft that waits for approval before any run carries it out; `mode: live` makes a plan running from the start (a Visual Plan of work under way). Steps may be strings (numbered in order) or {key, title, detail, depends_on}; up to 60, nested three deep (2.1, 2.1.1).\n\nNeeds the key's `plans` switch.", "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PlanCreate"}}}}}}, "/plans/{id}": {"parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}, "description": "A plan id."}], "get": {"tags": ["Plans"], "operationId": "getPlan", "summary": "A plan, with its recent history", "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Plan"}}}}, "401": {"description": "Missing or invalid API key", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "The key lacks the permission", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Not found (or not this key's)", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "429": {"description": "Rate limit or quota", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Needs the key's `plans` switch."}, "patch": {"tags": ["Plans"], "operationId": "revisePlan", "summary": "Revise a plan", "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Plan"}}}}, "400": {"description": "Invalid request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"description": "Missing or invalid API key", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "The key lacks the permission", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Not found (or not this key's)", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "429": {"description": "Rate limit or quota", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "From the revision you saw (`revision`): refused with **409** `invalid_plan` if the plan moved on since. Steps that keep their key keep their progress. An approved Plan Mode plan goes back to `draft` and is approved again before a run carries it out. A completed or cancelled plan can't be revised.\n\nNeeds the key's `plans` switch.", "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PlanRevision"}}}}}}, "/plans/{id}/approve": {"parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}, "description": "A plan id."}], "post": {"tags": ["Plans"], "operationId": "approvePlan", "summary": "Approve a revision", "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Plan"}}}}, "400": {"description": "Invalid request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"description": "Missing or invalid API key", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "The key lacks the permission", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Not found (or not this key's)", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "429": {"description": "Rate limit or quota", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Approve the revision you reviewed (**409** if the plan was revised since). A draft, paused or approved plan can be approved. Carrying it out is a run: `POST /runs` with `plan_id`.\n\nNeeds the key's `plans` switch.", "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PlanApproval"}}}}}}, "/plans/{id}/cancel": {"parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}, "description": "A plan id."}], "post": {"tags": ["Plans"], "operationId": "cancelPlan", "summary": "Cancel a plan", "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Plan"}}}}, "400": {"description": "Invalid request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"description": "Missing or invalid API key", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "The key lacks the permission", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Not found (or not this key's)", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "429": {"description": "Rate limit or quota", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "No run carries it out after this. A completed or cancelled plan answers 400.\n\nNeeds the key's `plans` switch."}}, "/plans/{id}/steps/{key}": {"parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}, "description": "A plan id."}, {"name": "key", "in": "path", "required": true, "schema": {"type": "string", "pattern": "^\\d{1,3}(\\.\\d{1,3}){0,2}$"}, "description": "A step's key: 2 is a top-level step, 2.1 a step inside it."}], "post": {"tags": ["Plans"], "operationId": "movePlanStep", "summary": "Move a step", "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Plan"}}}}, "400": {"description": "Invalid request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"description": "Missing or invalid API key", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "The key lacks the permission", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Not found (or not this key's)", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "429": {"description": "Rate limit or quota", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Mark a step done by hand, skip it, fail or block it, or put it back to pending. A step with sub-steps follows them (it starts when one starts and completes when all are completed or skipped): move its sub-steps instead (only `failed` and `blocked` apply to it directly). A step can't be completed before the steps it depends on are completed or skipped. Completed without `verified_by` keeps a note that the application marked it, not a run's check. When every step is done the plan is completed.\n\nNeeds the key's `plans` switch.", "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PlanStepMove"}}}}}}, "/plans/{id}/events": {"parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}, "description": "A plan id."}], "get": {"tags": ["Plans"], "operationId": "listPlanEvents", "summary": "A plan's history, or follow it live", "responses": {"200": {"description": "The events (JSON), or Server-Sent Events", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PlanEventList"}}, "text/event-stream": {"schema": {"type": "string"}}}}, "401": {"description": "Missing or invalid API key", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "The key lacks the permission", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Not found (or not this key's)", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "429": {"description": "Rate limit or quota", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "As JSON (the default): the plan's changes after `after`, oldest first. Asked with `Accept: text/event-stream` (or `stream=true`): Server-Sent Events. First `plan.snapshot` (the plan as it is now, no id), then each change as it is saved: `id` the event's id, `event` its type (`plan.created`, `plan.revised`, `plan.edited`, `plan.approved`, `plan.started`, `plan.resumed`, `plan.step`, `plan.interrupted`, `plan.completed`, `plan.cancelled`), `data` the PlanEvent with `plan` (the plan as it is then). `end` ({plan_id, status, last_id}) once the plan is completed, cancelled or failed; `reconnect` ({after}) after 30 minutes. A `: keep-alive` comment every 15 seconds. Reconnect with `Last-Event-ID` (or `after`) to resume after the last event seen: nothing is missed or repeated.\n\nNeeds the key's `plans` switch.", "parameters": [{"name": "after", "in": "query", "schema": {"type": "integer", "minimum": 0}, "description": "The last event id seen."}, {"name": "limit", "in": "query", "schema": {"type": "integer", "minimum": 1, "maximum": 500, "default": 200}, "description": "JSON only."}, {"name": "stream", "in": "query", "schema": {"type": "boolean"}, "description": "Server-Sent Events, as `Accept: text/event-stream` asks."}, {"name": "Last-Event-ID", "in": "header", "schema": {"type": "integer"}, "description": "Resume a stream after this event (takes precedence over `after`)."}]}}, "/openapi.json": {"get": {"tags": ["Meta"], "operationId": "platformOpenAPI", "summary": "This document", "security": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"type": "object"}}}}}}}, "/blackbox/events": {"post": {"tags": ["Black Box: recording"], "operationId": "recordEvents", "summary": "Record a batch of events", "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/BatchResult"}}}}, "400": {"description": "Invalid request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"description": "Missing or invalid API key", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "The key lacks the permission", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "413": {"description": "Body too large", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "422": {"description": "Idempotency-Key reused for another body", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "429": {"description": "Rate limit or quota", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Up to 1,000 events of 64 KB. Bad events are refused one by one; event ids make retries safe.\n\nNeeds the key's `blackbox_write` switch.", "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/EventBatch"}}}}, "parameters": [{"name": "Idempotency-Key", "in": "header", "schema": {"type": "string", "maxLength": 200}}]}}, "/blackbox/otlp/v1/traces": {"post": {"tags": ["Black Box: recording"], "operationId": "recordOtlp", "summary": "Record OpenTelemetry traces", "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"type": "object"}}}}, "400": {"description": "Invalid request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"description": "Missing or invalid API key", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "The key lacks the permission", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "413": {"description": "Body too large", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "429": {"description": "Rate limit or quota", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "OTLP/HTTP, JSON (`application/json`) or protobuf (`application/x-protobuf`), optionally gzipped. GenAI semantic conventions and OpenInference spans map onto events; one run per trace.\n\nNeeds the key's `blackbox_write` switch.", "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object"}}, "application/x-protobuf": {"schema": {"type": "string", "format": "binary"}}}}}}, "/blackbox/overview": {"get": {"tags": ["Black Box: runs"], "operationId": "blackboxOverview", "summary": "This key's runs this week, open findings, gaps", "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"type": "object"}}}}, "401": {"description": "Missing or invalid API key", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "The key lacks the permission", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Not found (or not this key's)", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Needs the key's `blackbox_read` switch."}}, "/blackbox/runs": {"get": {"tags": ["Black Box: runs"], "operationId": "listRuns", "summary": "List this key's runs", "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RunList"}}}}, "401": {"description": "Missing or invalid API key", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "The key lacks the permission", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Not found (or not this key's)", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Needs the key's `blackbox_read` switch.", "parameters": [{"name": "q", "in": "query", "schema": {"type": "string"}}, {"name": "status", "in": "query", "schema": {"type": "string"}}, {"name": "outcome", "in": "query", "schema": {"type": "string"}}, {"name": "agent", "in": "query", "schema": {"type": "string"}}, {"name": "model", "in": "query", "schema": {"type": "string"}}, {"name": "tool", "in": "query", "schema": {"type": "string"}}, {"name": "environment", "in": "query", "schema": {"type": "string"}}, {"name": "source", "in": "query", "schema": {"type": "string"}}, {"name": "since", "in": "query", "schema": {"type": "string"}}, {"name": "until", "in": "query", "schema": {"type": "string"}}, {"name": "severity", "in": "query", "schema": {"type": "string"}}, {"name": "cursor", "in": "query", "schema": {"type": "string"}}, {"name": "key", "in": "query", "schema": {"type": "string"}}, {"name": "limit", "in": "query", "schema": {"type": "integer", "minimum": 1, "maximum": 200}}]}}, "/blackbox/runs/options": {"get": {"tags": ["Black Box: runs"], "operationId": "listRunOptions", "summary": "What this key's runs can be filtered by", "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"type": "object"}}}}, "401": {"description": "Missing or invalid API key", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "The key lacks the permission", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Not found (or not this key's)", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Agents, models and tools in the runs, most used first, and the apps (keys) that made them with each key's color, group and library.\n\nNeeds the key's `blackbox_read` switch."}}, "/blackbox/runs/stream": {"get": {"tags": ["Black Box: live"], "operationId": "watchRuns", "summary": "Follow this key's runs as they change", "responses": {"200": {"description": "Server-Sent Events", "content": {"text/event-stream": {"schema": {"type": "string"}}}}, "401": {"description": "Missing or invalid API key", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "The key lacks the permission", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Not found (or not this key's)", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Events: `ready`, `run` (a run's summary, at most once a second each), `reconnect` after 30 minutes.\n\nNeeds the key's `blackbox_read` switch."}}, "/blackbox/runs/{id}": {"parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}, "description": "A run id."}], "get": {"tags": ["Black Box: runs"], "operationId": "getRun", "summary": "A run", "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Run"}}}}, "401": {"description": "Missing or invalid API key", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "The key lacks the permission", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Not found (or not this key's)", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "410": {"description": "Deleted; the signed deletion record is attached", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Needs the key's `blackbox_read` switch."}, "delete": {"tags": ["Black Box: privacy"], "operationId": "deleteRun", "summary": "Delete a run", "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"type": "object"}}}}, "401": {"description": "Missing or invalid API key", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "The key lacks the permission", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Not found (or not this key's)", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Removes the run; a signed deletion record stays in the account's log.\n\nNeeds the key's `blackbox_manage` switch.", "parameters": [{"name": "reason", "in": "query", "schema": {"type": "string"}}]}}, "/blackbox/runs/{id}/events": {"parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}, "description": "A run id."}], "get": {"tags": ["Black Box: runs"], "operationId": "listRunEvents", "summary": "A run's events", "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"type": "object"}}}}, "401": {"description": "Missing or invalid API key", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "The key lacks the permission", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Not found (or not this key's)", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Needs the key's `blackbox_read` switch.", "parameters": [{"name": "after", "in": "query", "schema": {"type": "integer"}}, {"name": "limit", "in": "query", "schema": {"type": "integer", "maximum": 5000}}, {"name": "types", "in": "query", "schema": {"type": "string"}, "description": "Comma-separated event types."}]}}, "/blackbox/runs/{id}/stream": {"parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}, "description": "A run id."}], "get": {"tags": ["Black Box: live"], "operationId": "streamRun", "summary": "Follow a run as it is recorded", "responses": {"200": {"description": "Server-Sent Events", "content": {"text/event-stream": {"schema": {"type": "string"}}}}, "401": {"description": "Missing or invalid API key", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "The key lacks the permission", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Not found (or not this key's)", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Events: `event` (id = seq, data = the envelope), then `end` (status, outcome), `deleted`, or `reconnect` (resume with Last-Event-ID).\n\nNeeds the key's `blackbox_read` switch.", "parameters": [{"name": "after", "in": "query", "schema": {"type": "integer"}}]}}, "/blackbox/runs/{id}/graph": {"parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}, "description": "A run id."}], "get": {"tags": ["Black Box: investigation"], "operationId": "getRunGraph", "summary": "Reconstruction: spans, causal edges, timeline, outcome, gaps", "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"type": "object"}}}}, "401": {"description": "Missing or invalid API key", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "The key lacks the permission", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Not found (or not this key's)", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Needs the key's `blackbox_read` switch."}}, "/blackbox/runs/{id}/lineage": {"parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}, "description": "A run id."}], "get": {"tags": ["Black Box: investigation"], "operationId": "getRunLineage", "summary": "The file versions a run made, each with the plan steps under way", "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"type": "object"}}}}, "401": {"description": "Missing or invalid API key", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "The key lacks the permission", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Not found (or not this key's)", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Each version: `path`, `sha256` (null: removed), `previous`, `span` (the tool call), `during` (the plan steps under way when that call was made: observed, never a claim that the step caused it) and `basis` (`observed`, or `unknown` for a version made outside a recorded tool call), and `content_kept` / `previous_kept` (false once that version's contents are past their keeping: its record stays); `steps` lists the plan steps the run moved; `unfinished`, once the run has ended, the calls it wrote ahead and never reported back (each may or may not have happened; `versioned` when the call made a file version).\n\nNeeds the key's `blackbox_content` switch."}}, "/blackbox/runs/{id}/content": {"parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}, "description": "A run id."}], "post": {"tags": ["Black Box: runs"], "operationId": "getRunContent", "summary": "The content kept for a run", "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"type": "object"}}}}, "401": {"description": "Missing or invalid API key", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "The key lacks the permission", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Not found (or not this key's)", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Needs the key's `blackbox_content` switch.", "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"refs": {"type": "array", "items": {"type": "string"}}}}}}}}}, "/blackbox/runs/{id}/verify": {"parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}, "description": "A run id."}], "get": {"tags": ["Black Box: evidence"], "operationId": "verifyRun", "summary": "Verify a run's chain and signatures", "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/VerifyReport"}}}}, "401": {"description": "Missing or invalid API key", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "The key lacks the permission", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Not found (or not this key's)", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Needs the key's `blackbox_read` switch."}}, "/blackbox/runs/{id}/checkpoints": {"parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}, "description": "A run id."}], "get": {"tags": ["Black Box: evidence"], "operationId": "getRunCheckpoints", "summary": "A run's signed checkpoints and its anchor", "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"type": "object"}}}}, "401": {"description": "Missing or invalid API key", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "The key lacks the permission", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Not found (or not this key's)", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Needs the key's `blackbox_read` switch."}}, "/blackbox/runs/{id}/export": {"parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}, "description": "A run id."}], "get": {"tags": ["Black Box: evidence"], "operationId": "exportRun", "summary": "An evidence bundle", "responses": {"200": {"description": "The bundle (JSON), or a zip with verify.py", "content": {"application/json": {"schema": {"type": "object"}}, "application/zip": {"schema": {"type": "string", "format": "binary"}}}}, "401": {"description": "Missing or invalid API key", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "The key lacks the permission", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Not found (or not this key's)", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Needs the key's `blackbox_read` switch.", "parameters": [{"name": "format", "in": "query", "schema": {"type": "string", "enum": ["json", "zip"]}}, {"name": "content", "in": "query", "schema": {"type": "boolean"}, "description": "Needs `blackbox_content` too."}]}, "post": {"tags": ["Black Box: evidence"], "operationId": "exportRunPost", "summary": "An evidence bundle (options in the body)", "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"type": "object"}}}}, "401": {"description": "Missing or invalid API key", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "The key lacks the permission", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Not found (or not this key's)", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Needs the key's `blackbox_read` switch.", "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"format": {"type": "string", "enum": ["json", "zip"]}, "content": {"type": "boolean"}}}}}}}}, "/blackbox/runs/{id}/otlp": {"parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}, "description": "A run id."}], "get": {"tags": ["Black Box: evidence"], "operationId": "exportRunOtlp", "summary": "A run as OTLP/JSON (GenAI conventions, OpenInference)", "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"type": "object"}}}}, "401": {"description": "Missing or invalid API key", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "The key lacks the permission", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Not found (or not this key's)", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Needs the key's `blackbox_read` switch.", "parameters": [{"name": "content", "in": "query", "schema": {"type": "boolean"}, "description": "Needs `blackbox_content` too."}]}}, "/blackbox/runs/{id}/simulate": {"parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}, "description": "A run id."}], "post": {"tags": ["Black Box: investigation"], "operationId": "simulateRun", "summary": "Reconstruct, simulate or fork a run (never evidence)", "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"type": "object"}}}}, "401": {"description": "Missing or invalid API key", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "The key lacks the permission", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Not found (or not this key's)", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "`simulate` and `counterfactual` need `blackbox_content` too. Nothing real runs.\n\nNeeds the key's `blackbox_read` switch.", "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SimulationRequest"}}}}}}, "/blackbox/runs/{id}/erase": {"parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}, "description": "A run id."}], "post": {"tags": ["Black Box: privacy"], "operationId": "eraseRunContent", "summary": "Erase a run's content (its key is destroyed)", "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"type": "object"}}}}, "401": {"description": "Missing or invalid API key", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "The key lacks the permission", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Not found (or not this key's)", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Needs the key's `blackbox_manage` switch.", "parameters": [{"name": "reason", "in": "query", "schema": {"type": "string"}}]}}, "/blackbox/runs/{id}/bookmarks": {"parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}, "description": "A run id."}], "get": {"tags": ["Black Box: investigation"], "operationId": "listBookmarks", "summary": "A run's bookmarks", "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"type": "object"}}}}, "401": {"description": "Missing or invalid API key", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "The key lacks the permission", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Not found (or not this key's)", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Needs the key's `blackbox_read` switch."}, "post": {"tags": ["Black Box: investigation"], "operationId": "addBookmark", "summary": "Bookmark an event", "responses": {"201": {"description": "OK", "content": {"application/json": {"schema": {"type": "object"}}}}, "400": {"description": "Invalid request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"description": "Missing or invalid API key", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "The key lacks the permission", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Not found (or not this key's)", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Needs the key's `blackbox_write` switch.", "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "required": ["seq"], "properties": {"seq": {"type": "integer"}, "note": {"type": "string", "maxLength": 2000}}}}}}}}, "/blackbox/bookmarks/{bid}": {"parameters": [{"name": "bid", "in": "path", "required": true, "schema": {"type": "integer"}}], "delete": {"tags": ["Black Box: investigation"], "operationId": "deleteBookmark", "summary": "Delete one of this key's bookmarks", "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"type": "object"}}}}, "401": {"description": "Missing or invalid API key", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "The key lacks the permission", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Not found (or not this key's)", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Needs the key's `blackbox_write` switch."}}, "/blackbox/diff": {"get": {"tags": ["Black Box: investigation"], "operationId": "diffRuns", "summary": "Where two runs part", "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"type": "object"}}}}, "401": {"description": "Missing or invalid API key", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "The key lacks the permission", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Not found (or not this key's)", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Needs the key's `blackbox_read` switch.", "parameters": [{"name": "a", "in": "query", "schema": {"type": "string", "format": "uuid"}}, {"name": "b", "in": "query", "schema": {"type": "string", "format": "uuid"}}]}}, "/blackbox/findings": {"get": {"tags": ["Black Box: findings"], "operationId": "listFindings", "summary": "What the detection rules noticed", "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"type": "object"}}}}, "401": {"description": "Missing or invalid API key", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "The key lacks the permission", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Not found (or not this key's)", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Needs the key's `blackbox_read` switch.", "parameters": [{"name": "run_id", "in": "query", "schema": {"type": "string", "format": "uuid"}}, {"name": "status", "in": "query", "schema": {"type": "string", "enum": ["open", "dismissed", "confirmed", "all"]}}, {"name": "severity", "in": "query", "schema": {"type": "string", "enum": ["info", "low", "medium", "high", "critical"]}}, {"name": "rule", "in": "query", "schema": {"type": "string"}}, {"name": "limit", "in": "query", "schema": {"type": "integer", "maximum": 500}}]}}, "/blackbox/findings/{fid}": {"parameters": [{"name": "fid", "in": "path", "required": true, "schema": {"type": "integer"}}], "patch": {"tags": ["Black Box: findings"], "operationId": "triageFinding", "summary": "Confirm or dismiss a finding", "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"type": "object"}}}}, "401": {"description": "Missing or invalid API key", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "The key lacks the permission", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Not found (or not this key's)", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Needs the key's `blackbox_write` switch.", "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "required": ["status"], "properties": {"status": {"type": "string", "enum": ["open", "confirmed", "dismissed"]}, "note": {"type": "string", "maxLength": 2000}}}}}}}}, "/blackbox/rules": {"get": {"tags": ["Black Box: findings"], "operationId": "listRules", "summary": "The detection rules and the account's settings", "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"type": "object"}}}}, "401": {"description": "Missing or invalid API key", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "The key lacks the permission", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Not found (or not this key's)", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Needs the key's `blackbox_read` switch."}}, "/blackbox/rules/preview": {"post": {"tags": ["Black Box: findings"], "operationId": "previewRules", "summary": "What other rule settings would raise on recent runs", "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"type": "object"}}}}, "401": {"description": "Missing or invalid API key", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "The key lacks the permission", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Not found (or not this key's)", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Needs the key's `blackbox_read` switch.", "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"rules": {"type": "object"}, "runs": {"type": "integer", "maximum": 300}, "days": {"type": "integer", "maximum": 365}}}}}}}}, "/blackbox/settings": {"get": {"tags": ["Black Box: runs"], "operationId": "getRecordingSettings", "summary": "What the account keeps, and for how long", "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"type": "object"}}}}, "401": {"description": "Missing or invalid API key", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "The key lacks the permission", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Not found (or not this key's)", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Needs the key's `blackbox_read` switch."}}, "/blackbox/sinks": {"get": {"tags": ["Black Box: sinks"], "operationId": "listSinks", "summary": "This key's sinks", "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"type": "object"}}}}, "401": {"description": "Missing or invalid API key", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "The key lacks the permission", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Not found (or not this key's)", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Needs the key's `blackbox_manage` switch."}, "post": {"tags": ["Black Box: sinks"], "operationId": "createSink", "summary": "Add a webhook or an OpenTelemetry export", "responses": {"201": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Sink"}}}}, "400": {"description": "Invalid request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"description": "Missing or invalid API key", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "The key lacks the permission", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "A webhook's `secret` is returned once. Webhooks follow Standard Webhooks (webhook-id, webhook-timestamp, webhook-signature). An export with content needs `blackbox_content`.\n\nNeeds the key's `blackbox_manage` switch.", "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SinkRequest"}}}}}}, "/blackbox/sinks/{sid}": {"parameters": [{"name": "sid", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}], "get": {"tags": ["Black Box: sinks"], "operationId": "getSink", "summary": "A sink", "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Sink"}}}}, "401": {"description": "Missing or invalid API key", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "The key lacks the permission", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Not found (or not this key's)", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Needs the key's `blackbox_manage` switch."}, "patch": {"tags": ["Black Box: sinks"], "operationId": "updateSink", "summary": "Change a sink", "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Sink"}}}}, "401": {"description": "Missing or invalid API key", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "The key lacks the permission", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Not found (or not this key's)", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Needs the key's `blackbox_manage` switch.", "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SinkRequest"}}}}}, "delete": {"tags": ["Black Box: sinks"], "operationId": "deleteSink", "summary": "Remove a sink", "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"type": "object"}}}}, "401": {"description": "Missing or invalid API key", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "The key lacks the permission", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Not found (or not this key's)", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Needs the key's `blackbox_manage` switch."}}, "/blackbox/sinks/{sid}/test": {"parameters": [{"name": "sid", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}], "post": {"tags": ["Black Box: sinks"], "operationId": "testSink", "summary": "Send a ping", "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"type": "object"}}}}, "401": {"description": "Missing or invalid API key", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "The key lacks the permission", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Not found (or not this key's)", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Needs the key's `blackbox_manage` switch."}}, "/blackbox/sinks/{sid}/rotate": {"parameters": [{"name": "sid", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}], "post": {"tags": ["Black Box: sinks"], "operationId": "rotateSinkSecret", "summary": "A new webhook secret (shown once)", "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"type": "object"}}}}, "401": {"description": "Missing or invalid API key", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "The key lacks the permission", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Not found (or not this key's)", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Needs the key's `blackbox_manage` switch."}}, "/blackbox/sinks/{sid}/deliveries": {"parameters": [{"name": "sid", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}], "get": {"tags": ["Black Box: sinks"], "operationId": "listDeliveries", "summary": "Recent deliveries", "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"type": "object"}}}}, "401": {"description": "Missing or invalid API key", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "The key lacks the permission", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Not found (or not this key's)", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Needs the key's `blackbox_manage` switch."}}, "/blackbox/deliveries/{did}/retry": {"parameters": [{"name": "did", "in": "path", "required": true, "schema": {"type": "integer"}}], "post": {"tags": ["Black Box: sinks"], "operationId": "retryDelivery", "summary": "Send a delivery again", "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"type": "object"}}}}, "401": {"description": "Missing or invalid API key", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "The key lacks the permission", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Not found (or not this key's)", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Needs the key's `blackbox_manage` switch."}}, "/blackbox/keys": {"get": {"tags": ["Black Box: evidence"], "operationId": "blackboxKeys", "summary": "The public signing keys", "security": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"type": "object"}}}}}}}, "/blackbox/verify": {"post": {"tags": ["Black Box: evidence"], "operationId": "verifyBundle", "summary": "Verify a bundle", "security": [], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object"}}}}, "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/VerifyReport"}}}}, "429": {"description": "Rate limit or quota", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "The same check as the bundle's own verify.py, against the published keys."}}, "/blackbox/mcp": {"post": {"tags": ["Black Box: MCP"], "operationId": "blackboxMcp", "summary": "MCP (Streamable HTTP)", "description": "Protocol 2025-06-18. Tools, resources (blackbox://runs/{id}, subscribable) and prompts, offered by the key's switches. `initialize` returns an Mcp-Session-Id.", "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object"}}}}, "responses": {"200": {"description": "JSON-RPC response (JSON, or SSE with progress)"}, "202": {"description": "Notification accepted"}}}, "get": {"tags": ["Black Box: MCP"], "operationId": "blackboxMcpStream", "summary": "The session's server messages (SSE)", "responses": {"200": {"description": "Server-Sent Events", "content": {"text/event-stream": {"schema": {"type": "string"}}}}}}, "delete": {"tags": ["Black Box: MCP"], "operationId": "blackboxMcpEnd", "summary": "End the session", "responses": {"204": {"description": "Ended"}}}}}, "components": {"securitySchemes": {"bearerAuth": {"type": "http", "scheme": "bearer", "bearerFormat": "dya-..."}}, "schemas": {"Error": {"type": "object", "properties": {"error": {"type": "object", "properties": {"message": {"type": "string"}, "type": {"type": "string"}, "param": {"type": ["string", "null"]}, "code": {"type": ["string", "null"]}}}}}, "RunRequest": {"type": "object", "required": ["agent", "messages"], "properties": {"agent": {"oneOf": [{"type": "string", "description": "One of the account's agents."}, {"type": "object", "description": "The application's own agent: name, instructions, behaviour, models."}]}, "messages": {"type": "array", "items": {"type": "object", "properties": {"role": {"type": "string"}, "content": {}}}}, "builtin_tools": {"type": "array", "items": {"type": "string"}, "description": "data.web_search, data.web_fetch, image.generate, vision.describe_image, audio.speak, audio.transcribe, and plans.propose, plans.step, plans.get (with the `plans` switch; a run with `plan_mode` or `plan_id` has them anyway). plans.propose without `plan_mode` makes a plan running from the start."}, "functions": {"type": "array", "items": {"type": "object"}}, "end_user": {"type": "string"}, "conversation_id": {"type": "string", "description": "The application's own conversation id; also the scope of its plans (`conversation`)."}, "stream": {"type": "boolean"}, "max_tokens": {"type": "integer"}, "temperature": {"type": "number"}, "think": {"type": "boolean"}, "effort": {"type": "string", "enum": ["low", "medium", "high", "max"], "description": "How hard the model reasons on each step: low (no reasoning, the default), medium, high or max."}, "research": {"type": "string", "enum": ["auto", "off", "deep"]}, "max_cost_usd": {"type": "number"}, "followups": {"type": "boolean"}, "plan_mode": {"type": "boolean", "default": false, "description": "Plan Mode: investigate read-only and propose a plan (plans.propose) for approval; nothing that changes anything runs. Needs the `plans` switch; not with `plan_id`."}, "plan_id": {"type": "string", "format": "uuid", "description": "Carry out this plan of the key's, picking up where it left off: a Plan Mode plan only once approved at its current revision (else the run fails with `plan_not_runnable`). Needs the `plans` switch."}}}, "RunCompleted": {"type": "object", "properties": {"type": {"const": "run.completed"}, "object": {"const": "run"}, "run_id": {"type": "string"}, "status": {"type": "string", "enum": ["completed", "requires_action", "incomplete", "failed"]}, "agent": {"type": "string"}, "output_text": {"type": "string"}, "function_calls": {"type": "array", "items": {"type": "object"}}, "messages": {"type": "array", "items": {"type": "object"}}, "tools": {"type": "array", "items": {"type": "string"}}, "model": {"type": "string"}, "models": {"type": "array", "items": {"type": "string"}}, "operation_id": {"type": "string"}, "blackbox": {"type": "object", "description": "Where this run is recorded: read it with GET /blackbox/runs/{run_id}.", "properties": {"run_id": {"type": "string"}, "trace_id": {"type": "string"}}}, "plans": {"type": "array", "description": "The plans this run made or moved, as it left them (only when it touched any).", "items": {"type": "object", "properties": {"id": {"type": "string", "format": "uuid"}, "title": {"type": "string"}, "status": {"type": "string", "enum": ["draft", "approved", "running", "paused", "completed", "failed", "cancelled"]}, "revision": {"type": "integer"}}}}}}, "RunPlanUpdated": {"type": "object", "description": "A streamed run's event when it made or moved a plan.", "properties": {"type": {"const": "plan.updated"}, "plan": {"$ref": "#/components/schemas/Plan"}}}, "PlanStepInput": {"oneOf": [{"type": "string", "description": "A step's title; keys are numbered in order."}, {"type": "object", "required": ["title"], "properties": {"key": {"type": "string", "pattern": "^\\d{1,3}(\\.\\d{1,3}){0,2}$", "description": "1, 2, or 2.1 for a step inside 2; numbered in order when left out."}, "title": {"type": "string", "maxLength": 200}, "detail": {"type": "string", "maxLength": 2000, "description": "How it will be done and checked."}, "depends_on": {"oneOf": [{"type": "array", "items": {"type": "string"}, "maxItems": 20}, {"type": "string", "description": "Comma-separated keys."}], "description": "Keys of steps that must be completed or skipped first."}}}]}, "PlanCreate": {"type": "object", "required": ["title", "steps"], "properties": {"title": {"type": "string", "maxLength": 200}, "summary": {"type": "string", "maxLength": 4000}, "steps": {"type": "array", "minItems": 1, "maxItems": 60, "items": {"$ref": "#/components/schemas/PlanStepInput"}}, "mode": {"type": "string", "enum": ["plan", "live"], "default": "plan", "description": "plan: a draft that waits for approval; live: running from the start."}, "conversation": {"type": "string", "maxLength": 200, "description": "The application's conversation it belongs to."}, "metadata": {"type": "object", "maxProperties": 16, "propertyNames": {"maxLength": 64}, "additionalProperties": {"type": "string", "maxLength": 512}}}}, "PlanRevision": {"type": "object", "required": ["revision"], "properties": {"revision": {"type": "integer", "description": "The revision you revised (409 if the plan moved on since)."}, "title": {"type": "string", "maxLength": 200}, "summary": {"type": "string", "maxLength": 4000}, "steps": {"type": "array", "minItems": 1, "maxItems": 60, "items": {"$ref": "#/components/schemas/PlanStepInput"}, "description": "The whole list; steps keeping their key keep their progress."}, "metadata": {"type": "object", "maxProperties": 16, "additionalProperties": {"type": "string", "maxLength": 512}, "description": "Replaces the plan's metadata when given."}}}, "PlanApproval": {"type": "object", "required": ["revision"], "properties": {"revision": {"type": "integer", "description": "The revision you reviewed and approve."}}}, "PlanStepMove": {"type": "object", "required": ["status"], "properties": {"status": {"type": "string", "enum": ["pending", "in_progress", "completed", "failed", "blocked", "skipped"]}, "note": {"type": "string", "maxLength": 1000}, "verified_by": {"type": "string", "maxLength": 1000, "description": "The check that shows it's done."}}}, "PlanStep": {"type": "object", "properties": {"key": {"type": "string"}, "parent": {"type": "string", "description": "The key of the step it sits in; empty at the top."}, "title": {"type": "string"}, "detail": {"type": "string"}, "status": {"type": "string", "enum": ["pending", "in_progress", "completed", "failed", "blocked", "skipped"]}, "depends_on": {"type": "array", "items": {"type": "string"}}, "verified_by": {"type": "string", "description": "How completion was checked (a run must say it)."}, "note": {"type": "string"}, "evidence": {"type": "array", "items": {"type": "object"}, "description": "The latest tool calls that moved it, with the run's operation id."}, "started_at": {"type": ["string", "null"], "format": "date-time"}, "finished_at": {"type": ["string", "null"], "format": "date-time"}, "updated_at": {"type": ["string", "null"], "format": "date-time"}}}, "PlanEvent": {"type": "object", "properties": {"id": {"type": "integer", "description": "In order: a stream resumes after the last one it saw."}, "object": {"const": "plan.event"}, "plan_id": {"type": "string", "format": "uuid"}, "kind": {"type": "string", "enum": ["created", "revised", "edited", "approved", "started", "resumed", "step", "interrupted", "completed", "cancelled"]}, "type": {"type": "string", "description": "plan.<kind>"}, "step": {"type": ["string", "null"]}, "status": {"type": ["string", "null"]}, "detail": {"type": "object"}, "actor": {"type": "string", "description": "iris (an agent in a run), owner (the Workspace) or application (an API key)."}, "operation_id": {"type": ["string", "null"], "description": "The run that made the change (its Black Box record)."}, "at": {"type": "string", "format": "date-time"}, "plan": {"$ref": "#/components/schemas/Plan", "description": "On the event stream only: the plan as it is after this change."}}}, "Plan": {"type": "object", "properties": {"id": {"type": "string", "format": "uuid"}, "object": {"const": "plan"}, "chat_id": {"type": ["string", "null"], "description": "A Workspace conversation's plan; null for an application's."}, "api_key_id": {"type": ["string", "null"]}, "conversation": {"type": "string"}, "metadata": {"type": "object", "additionalProperties": {"type": "string"}}, "title": {"type": "string"}, "summary": {"type": "string"}, "origin": {"type": "string", "enum": ["plan", "live"], "description": "plan: from Plan Mode, approved before it runs; live: made as the work runs."}, "status": {"type": "string", "enum": ["draft", "approved", "running", "paused", "completed", "failed", "cancelled"]}, "revision": {"type": "integer"}, "approved_revision": {"type": ["integer", "null"]}, "approved_at": {"type": ["string", "null"], "format": "date-time"}, "created_at": {"type": "string", "format": "date-time"}, "updated_at": {"type": "string", "format": "date-time"}, "progress": {"type": "object", "description": "Over the steps with no sub-steps.", "properties": {"done": {"type": "integer"}, "total": {"type": "integer"}, "percent": {"type": "integer"}, "failed": {"type": "integer"}, "blocked": {"type": "integer"}}}, "steps": {"type": "array", "items": {"$ref": "#/components/schemas/PlanStep"}}, "events": {"type": "array", "items": {"$ref": "#/components/schemas/PlanEvent"}, "description": "Its recent history (up to 60), oldest first; not in lists."}}}, "PlanList": {"type": "object", "properties": {"object": {"const": "list"}, "data": {"type": "array", "items": {"$ref": "#/components/schemas/Plan"}}, "has_more": {"type": "boolean"}, "first_id": {"type": ["string", "null"]}, "last_id": {"type": ["string", "null"]}}}, "PlanEventList": {"type": "object", "properties": {"object": {"const": "list"}, "data": {"type": "array", "items": {"$ref": "#/components/schemas/PlanEvent"}}, "has_more": {"type": "boolean"}, "last_id": {"type": ["integer", "null"]}}}, "EventBatch": {"type": "object", "required": ["run", "events"], "properties": {"run": {"type": "object", "properties": {"id": {"type": "string", "format": "uuid"}, "trace_id": {"type": "string"}, "parent": {"type": "string", "description": "A W3C traceparent."}, "agent": {"type": "object", "properties": {"id": {"type": "string"}, "name": {"type": "string"}}}, "title": {"type": "string"}, "environment": {"type": "string", "enum": ["production", "staging", "development", "test"]}, "root_span_id": {"type": "string"}}}, "events": {"type": "array", "maxItems": 1000, "items": {"$ref": "#/components/schemas/Event"}}, "sent_at": {"type": "string", "format": "date-time"}}}, "Event": {"type": "object", "required": ["id", "type", "time"], "properties": {"id": {"type": "string"}, "type": {"type": "string", "description": "run.*, agent.*, model.*, tool.*, approval.*, policy.decision, effect.observed, outcome.*, note, x.<app>.<what>"}, "status": {"type": "string"}, "name": {"type": "string"}, "time": {"type": "string", "format": "date-time"}, "seq": {"type": "integer", "description": "The producer's own sequence number (exposes lost events)."}, "span_id": {"type": "string"}, "parent_span_id": {"type": "string"}, "agent": {"type": "string"}, "actor": {"type": "string"}, "attrs": {"type": "object"}, "content": {"type": "object", "description": "Kept only where the account keeps that kind."}, "basis": {"type": "string", "enum": ["reported", "inferred"]}}}, "BatchResult": {"type": "object", "properties": {"object": {"const": "blackbox.batch"}, "run_id": {"type": "string"}, "trace_id": {"type": "string"}, "accepted": {"type": "integer"}, "duplicates": {"type": "integer"}, "rejected": {"type": "array", "items": {"type": "object", "properties": {"index": {"type": "integer"}, "reason": {"type": "string"}}}}, "head": {"type": "object"}, "status": {"type": "string"}, "ended": {"type": "boolean"}}}, "Run": {"type": "object", "properties": {"id": {"type": "string"}, "title": {"type": "string"}, "status": {"type": "string"}, "outcome": {"type": "string", "enum": ["unknown", "not_applicable", "unverified", "contradicted", "verified", "blocked", "no_effects", "failed"]}, "environment": {"type": "string"}, "source": {"type": "string"}, "started_at": {"type": "string"}, "ended_at": {"type": ["string", "null"]}, "events": {"type": "integer"}, "signed_through": {"type": "integer"}, "findings": {"type": "integer"}, "max_severity": {"type": ["string", "null"]}, "models": {"type": "array", "items": {"type": "string"}}, "tools": {"type": "array", "items": {"type": "string"}}, "trace_id": {"type": "string"}, "archived_at": {"type": ["string", "null"]}, "content_erased_at": {"type": ["string", "null"]}}}, "RunList": {"type": "object", "properties": {"runs": {"type": "array", "items": {"$ref": "#/components/schemas/Run"}}, "next": {"type": ["string", "null"]}}}, "VerifyReport": {"type": "object", "properties": {"ok": {"type": "boolean"}, "events": {"type": "integer"}, "signed_through": {"type": "integer"}, "trusted_keys": {"type": "boolean"}, "checks": {"type": "array", "items": {"type": "object"}}, "errors": {"type": "array", "items": {"type": "string"}}, "warnings": {"type": "array", "items": {"type": "string"}}, "limitations": {"type": "array", "items": {"type": "string"}}}}, "SimulationRequest": {"type": "object", "required": ["mode"], "properties": {"mode": {"type": "string", "enum": ["reconstruct", "simulate", "counterfactual"]}, "policy": {"type": "object"}, "tool_results": {"type": "object"}, "model": {"type": "string"}, "continue_with_model": {"type": "boolean"}, "max_steps": {"type": "integer"}, "max_cost_usd": {"type": "number", "maximum": 5}}}, "SinkRequest": {"type": "object", "properties": {"kind": {"type": "string", "enum": ["webhook", "otlp"]}, "url": {"type": "string", "format": "uri"}, "name": {"type": "string"}, "events": {"type": "array", "items": {"type": "string", "enum": ["finding.created", "run.completed", "run.failed", "run.cancelled", "run.interrupted", "run.abandoned", "run.requires_action"]}}, "min_severity": {"type": "string", "enum": ["info", "low", "medium", "high", "critical"]}, "environments": {"type": "array", "items": {"type": "string"}}, "protocol": {"type": "string", "enum": ["http/json", "http/protobuf"]}, "content": {"type": "boolean"}, "enabled": {"type": "boolean"}, "headers": {"type": "object", "additionalProperties": {"type": "string"}, "maxProperties": 10}}}, "Sink": {"type": "object", "properties": {"id": {"type": "string"}, "kind": {"type": "string"}, "url": {"type": "string"}, "events": {"type": "array", "items": {"type": "string"}}, "header_names": {"type": "array", "items": {"type": "string"}}, "enabled": {"type": "boolean"}, "failures": {"type": "integer"}, "last_success_at": {"type": ["string", "null"]}, "last_error": {"type": "string"}, "secret": {"type": "string", "description": "Only when created or rotated."}}}}}}