{"openapi":"3.1.0","info":{"title":"AI Agent Framework","description":"Standalone multitenant AI agent + RAG service. Plug in and go.","version":"0.1.0"},"paths":{"/metrics":{"get":{"summary":"Metrics","description":"Endpoint that serves Prometheus metrics.","operationId":"metrics_metrics_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/health":{"get":{"tags":["health"],"summary":"Health","description":"Alive — and whether anything is still being waited on.\n\nIt used to answer `{\"status\": \"ok\"}` and nothing else, which made it useless for the\none question a deploy has to ask: not \"are you up\" but \"is anyone still waiting on\nyou\". So a rolling deploy stopped this process with streams open, `/health` said `ok`\non the way past, and thirteen turns died in an afternoon (OBE-58).\n\n`in_flight` is what the deploy waits for. `draining` says this process has been asked\nto stop and is no longer accepting connections — it is still serving what it accepted,\nwhich is the whole point.","operationId":"health_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Health Health Get"}}}}}}},"/ready":{"get":{"tags":["health"],"summary":"Ready","operationId":"ready_ready_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Ready Ready Get"}}}}}}},"/auth/token":{"post":{"tags":["auth"],"summary":"Issue Token","operationId":"issue_token_auth_token_post","parameters":[{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/tenants":{"post":{"tags":["tenants"],"summary":"Create Tenant","operationId":"create_tenant_tenants_post","parameters":[{"name":"X-Admin-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantCreated"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["tenants"],"summary":"List Tenants","operationId":"list_tenants_tenants_get","parameters":[{"name":"X-Admin-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TenantOut"},"title":"Response List Tenants Tenants Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/tenants/{tenant_id}":{"patch":{"tags":["tenants"],"summary":"Update Tenant Settings","description":"Merge keys into a tenant's settings_json. The control plane uses this to set\nper-tenant LLM routing (``litellm_key``, ``default_model``) after provisioning.","operationId":"update_tenant_settings_tenants__tenant_id__patch","parameters":[{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Tenant Id"}},{"name":"X-Admin-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantSettingsUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["tenants"],"summary":"Delete Tenant","description":"Erase a tenant: its rows, its vectors, its raw bytes, and the work it had running.\n\nThis is what a customer deleting a project actually asks for, and the reason it lives\non the data plane is that the control plane can only reach the row that *points* at a\ntenant. Deleting only that leaves the corpus, the conversations and the uploaded files\nin place, indefinitely, on the product whose pitch is isolation per customer.\n\nOrder matters and is not incidental: the sandboxes and the schedules are read from the\nrows, so they have to be dealt with *before* the rows go. Everything outside Postgres\nis best-effort and reported — a Temporal that is down must not leave a tenant\nundeletable — but the row purge is not, because a half-deleted tenant is one the\ndashboard no longer lists and whose data still answers queries.","operationId":"delete_tenant_tenants__tenant_id__delete","parameters":[{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Tenant Id"}},{"name":"X-Admin-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantDeleted"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/tenants/{tenant_id}/webhook-secret":{"get":{"tags":["tenants"],"summary":"Read Webhook Secret","description":"The key that signs `turn.stopped` and scheduled-webhook deliveries.\n\nIt has existed since tenants existed and nothing ever returned it, so the docs told\nintegrators to verify a signature with a secret they had no way to obtain. (For a\nwhile that was academic — `turn.stopped` was going out unsigned.)\n\nReadable rather than shown-once because the customer's own configuration holds it, the\nsame argument the trigger URL makes: a value someone else has to keep is not a value we\ncan show once and forget.","operationId":"read_webhook_secret_tenants__tenant_id__webhook_secret_get","parameters":[{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Tenant Id"}},{"name":"X-Admin-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookSecret"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/tenants/{tenant_id}/webhook-secret/rotate":{"post":{"tags":["tenants"],"summary":"Rotate Webhook Secret","description":"Issue a new signing key.\n\nNo dual-signature window here, unlike webhook tools: this key signs what WE send, so\nthe customer updates their verifier and the next delivery uses the new key. There is no\nin-flight request holding the old one — the worst case is one delivery failing\nverification, which a receiver retries.","operationId":"rotate_webhook_secret_tenants__tenant_id__webhook_secret_rotate_post","parameters":[{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Tenant Id"}},{"name":"X-Admin-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookSecret"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/tools/deliveries":{"get":{"tags":["tools"],"summary":"Webhook Deliveries","description":"Recent calls to this project's webhook tools, newest first.\n\nA handler that starts failing is otherwise only visible inside one turn's tool\nresult. This is the operational view: when, which tool, what came back, how long.\nAdmin/service credentials only — it spans every end-user of the project.\n\n\"Admin\" means `ctx.is_admin`, not \"holds no capability claim\". The gate used to be\n`capabilities is not None`, which admits ONLY an unrestricted service principal — so\nan end-user token carrying `roles: [\"admin\"]`, which sees every session in the tenant\nand may call `audit.forget`, was refused this. Between that and the data plane not\naccepting a control-plane `pk_…` key, the route had no caller a customer could\nactually produce: a published, documented endpoint that answered 403 or 401 to\neverything. The control-plane view (`GET /api/projects/:id/webhook-tools/deliveries`)\nis the other way in and is documented now too.","operationId":"webhook_deliveries_tools_deliveries_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":100,"title":"Limit"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"type":"object"},"title":"Response Webhook Deliveries Tools Deliveries Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/tools":{"get":{"tags":["tools"],"summary":"List Tools","operationId":"list_tools_tools_get","parameters":[{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response List Tools Tools Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/tools/mcp/probe":{"post":{"tags":["tools"],"summary":"Probe Mcp Server","description":"Ask whether one MCP server works, without storing anything about it.\n\n`mcp add` answered `201` for a server that cannot work while the very next call — the\nlisting — already knew why and said so well: *\"answered a web page\"* for a docs URL\nsomebody pasted, the resolver's own words for a host that does not exist, the SSRF\nguard's for a blocked address. The check existed; only its timing was wrong, so the\nfirst evidence a customer got was a turn where the agent had fewer tools than expected\n(OBE-275).\n\nA ROUTE OF ITS OWN rather than register-then-check. The listing's verdict comes from the\ntenant's stored settings, so the obvious fix is to write the server, ask, and unwrite it\non a bad answer — which leaves a window where a broken server is live for another\nrequest, and an unwrite that can fail on its own. `load_tenant_mcp` takes a spec rather\nthan settings, so this asks about a server nothing has stored yet.\n\nTHE SAME LOADER, so the sentence is the listing's sentence. A second opinion about what\na broken server is would be a second thing to keep in agreement, which is the shape\nevery recurring defect here has had.\n\nDEGRADES. A loader that says nothing about this server, or falls over, answers `ok` —\nrefusing on an unknown would turn a transient into an inability to configure, which is\nhow OBE-267 was settled one surface over.","operationId":"probe_mcp_server_tools_mcp_probe_post","parameters":[{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/McpProbeRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/McpProbeResult"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/capabilities":{"get":{"tags":["capabilities"],"summary":"Describe Capabilities","operationId":"describe_capabilities_capabilities_get","parameters":[{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Describe Capabilities Capabilities Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/chat":{"post":{"tags":["chat"],"summary":"Chat","operationId":"chat_chat_post","parameters":[{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/chat/stream":{"post":{"tags":["chat"],"summary":"Chat Stream","description":"Server-Sent Events stream of the turn.\n\nEmits `start` (with `run_id`), `token` deltas, `tool_start`/`tool_end`, and a\nterminal `done` (carrying final content + any `requires_action` client tool\ncalls). Each frame has an `id:`; the response also returns `X-Run-Id`.\n\n**Reconnect:** if the connection drops, generation continues server-side.\nReconnect via `GET /chat/stream/{run_id}` with `Last-Event-ID` (or\n`?last_event_id=`) to replay missed frames and resume live. If the run has\nalready finished, fetch the final message from the session history.","operationId":"chat_stream_chat_stream_post","parameters":[{"name":"Last-Event-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last-Event-Id"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/chat/stream/{run_id}":{"get":{"tags":["chat"],"summary":"Chat Stream Resume","description":"Resume a previously started stream: replays events after Last-Event-ID,\nthen continues live until the run finishes.\n\nA run whose events this process no longer holds — it finished more than\n`runs._RETAIN_SECONDS` ago, or the process that was generating it restarted — still\nanswers 200 with one terminal `error` frame naming the conversation and why. Only an\nid nothing has a record of is a 404. See `_resume_without_events`.","operationId":"chat_stream_resume_chat_stream__run_id__get","parameters":[{"name":"run_id","in":"path","required":true,"schema":{"type":"string","title":"Run Id"}},{"name":"last_event_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Last Event Id"}},{"name":"Last-Event-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last-Event-Id"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/chat/stream/{run_id}/steer":{"post":{"tags":["chat"],"summary":"Chat Stream Steer","description":"Send a message into a turn that is still running.\n\nThe message is picked up at the agent's next step boundary — after whatever tool\nis in flight finishes — and appended as a normal user message, so the model reads\nit as the user speaking rather than as a system instruction it should rank above\nthe workspace's own rules. Cancelling a half-finished tool call to react a moment\nsooner would leave a tool call nothing answered, which poisons the session.\n\nNot steering? Just wait for the turn and send a normal message. This exists for\nthe case where waiting means letting the agent finish work you already know is\nwrong.","operationId":"chat_stream_steer_chat_stream__run_id__steer_post","parameters":[{"name":"run_id","in":"path","required":true,"schema":{"type":"string","title":"Run Id"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SteerRequest"}}}},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Chat Stream Steer Chat Stream  Run Id  Steer Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/chat/stream/{run_id}/cancel":{"post":{"tags":["chat"],"summary":"Chat Stream Cancel","description":"Cancel a streaming run's server-side generation (stops model spend).\n\nIdempotent, and that now extends to a run this process no longer holds: nothing is\ngenerating, which is precisely what the caller asked for, so it reports success. A\n404 there made a user pressing stop during a deploy see an error for having got what\nthey wanted.","operationId":"chat_stream_cancel_chat_stream__run_id__cancel_post","parameters":[{"name":"run_id","in":"path","required":true,"schema":{"type":"string","title":"Run Id"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Chat Stream Cancel Chat Stream  Run Id  Cancel Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/chat/sessions":{"get":{"tags":["chat"],"summary":"List Sessions","description":"Conversations this token may see, newest first.\n\nA PAGE, and it says so. This returned a bare array, so a project with 137 sessions\nanswered `sessions.list()` with 100 rows and nothing — not a field, not a header —\ndistinguishing that from a project that has exactly 100. A list endpoint returning an\narray reads as \"here is the set\"; this one meant \"here is a page\", and the only way to\ndiscover the difference was to keep asking until a page came back short (OBE-73).\n\n`has_more` and `next_offset` rather than a `total`: the count is the expensive half — a\nsecond query on every sidebar render — and \"is there another page\" is the question a\ncaller actually has. One spare row answers it.\n\nA **subagent's** working conversation is excluded unless `include_subagents` is set.\nIt is a conversation like any other — that is what gives a delegate a transcript, a\nplan and a context budget — but it is not one anybody had: `subagents.md` says \"the\nonly part of it anyone else needs is `result` at the end\", and this route was handing\nthe whole thing over. A chat sidebar built from it, which is what the recipes tell you\nto build, grew a row per delegate — three per turn on a project with\n`maxConcurrent: 3` — each titled with the orchestration prompt that started it.\n\nExcluded rather than hidden: `parent_session_id` comes back on every row, so a client\nthat asks for them can tell them apart, and a debugger can get from a delegate to the\nturn that delegated it.\n\nPaged, with a default. This returned *everything* — an admin-roled token on a\nproject with some history got 171 rows in one response and a project with a year of\nthem would get tens of thousands, in a single unbounded query, to render a sidebar\nthat shows twenty. Bounded by `limit`/`offset`; ordering is stable enough to page\nthrough because `updated_at` is tie-broken by `id`.\n\nFiltered server-side, and it has to be: the answer to \"which conversations failed\"\nis a handful of rows out of thousands, and a client that has to page through the\nthousands to find them is a client that gives up. `q` matches an id, a title or a\nuser; `model` and `status` read the rollup each turn leaves on the session.","operationId":"list_sessions_chat_sessions_get","parameters":[{"name":"user_ref","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Ref"}},{"name":"q","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Q"}},{"name":"model","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Model"}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},{"name":"since","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Since"}},{"name":"until","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Until"}},{"name":"include_subagents","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Include Subagents"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":100,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Offset"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionPage"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/chat/sessions/models":{"get":{"tags":["chat"],"summary":"Session Models","description":"Models these conversations have actually run on.\n\nSo the filter offers what is in the data rather than what the project has registered:\na project that switched default last month has months of traces on a model that is no\nlonger in its list, and those are exactly the ones somebody goes looking for.","operationId":"session_models_chat_sessions_models_get","parameters":[{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"type":"string"},"title":"Response Session Models Chat Sessions Models Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/chat/sessions/{session_id}/messages":{"get":{"tags":["chat"],"summary":"Session Messages","operationId":"session_messages_chat_sessions__session_id__messages_get","parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Session Id"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/MessageOut"},"title":"Response Session Messages Chat Sessions  Session Id  Messages Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/chat/sessions/{session_id}/browser/frame":{"post":{"tags":["chat"],"summary":"Browser Frame","description":"What the handed-over page looks like right now.\n\nPolled by the UI while the user has control. Cropped to whatever region the agent\nhanded over, plus any challenge that has popped up over it since — which is why\nthis is re-read rather than sent once: the thing a person has to act on often only\nappears after their first click.","operationId":"browser_frame_chat_sessions__session_id__browser_frame_post","parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Session Id"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BrowserFrameRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BrowserFrame"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/chat/sessions/{session_id}/browser/check":{"post":{"tags":["chat"],"summary":"Browser Handoff Check","description":"Has the person finished with the page they were handed?\n\nAsked after they let go of the mouse, so a hand-off can end itself instead of\nmaking someone who has just solved a bot check then report that they solved it —\nto a system that is looking straight at the answer.\n\nA **separate** small model does the looking: the turn's own context is large and\nthis runs repeatedly. It can only reply with one of four fixed words, which is what\nmakes it safe to show a challenge to — see `handoff_watch`.\n\nRate-limited server-side, so a client calling it on every mouse-up cannot turn a\ngesture into a bill.","operationId":"browser_handoff_check_chat_sessions__session_id__browser_check_post","parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Session Id"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HandoffCheck"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/chat/sessions/{session_id}/browser/stream":{"get":{"tags":["chat"],"summary":"Browser Stream","description":"The handed-over page, live.\n\nFrames are pushed as Chrome repaints instead of fetched one at a time. The polled\nendpoint above gave a viewer roughly one frame a second, which is enough to watch a\npage and not enough to act on one — a slider puzzle at that rate cannot be\ncompleted, so the interactive half of a hand-off was unusable rather than slow.\n\nRead-only hand-offs stream too. Watching is the whole point of one; it is *input*\nthat is refused.","operationId":"browser_stream_chat_sessions__session_id__browser_stream_get","parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Session Id"}},{"name":"selector","in":"query","required":false,"schema":{"type":"string","default":"","title":"Selector"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/chat/sessions/{session_id}/browser/input":{"post":{"tags":["chat"],"summary":"Browser Input","description":"Replay one thing the user did into the page, and return the result.\n\nReturning the new frame rather than an acknowledgement is deliberate: a person\nclicking a picture needs to see the click land, and a separate poll would show it\nup to a second later, which reads as the click not having worked.","operationId":"browser_input_chat_sessions__session_id__browser_input_post","parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Session Id"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BrowserInput"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BrowserFrame"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/chat/sessions/{session_id}/followups":{"post":{"tags":["chat"],"summary":"Session Followups","description":"A few things the user might say next, phrased as the user.\n\nDeliberately its own endpoint rather than part of the turn: a turn that waited on\na suggestion would make the user wait for something they never asked for. Call it\nafter `done` and render the buttons a beat later.\n\nNothing here reaches the agent. A clicked suggestion arrives as an ordinary\nmessage, and nothing is persisted — an agent that knew it wrote the question would\nanswer the one it meant instead of the one that was asked.","operationId":"session_followups_chat_sessions__session_id__followups_post","parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Session Id"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FollowupsRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FollowupsOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/chat/sessions/{session_id}/recap":{"post":{"tags":["chat"],"summary":"Session Recap","description":"Where the conversation got to, in a sentence or two.\n\nFor a user coming back after a while — the client decides when that is, since only\nit knows the tab has been idle. Not the same thing as context compaction: that\nsummarizes FOR the model and is replayed to it, this is for the person and the\nagent never sees it.","operationId":"session_recap_chat_sessions__session_id__recap_post","parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Session Id"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecapOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/chat/sessions/{session_id}/todos":{"get":{"tags":["chat"],"summary":"Session Todos","description":"The agent's plan for this conversation.\n\nA turn returns the list when it touched it; this is how a UI shows the plan on a\npage load, or while the agent is between turns. Same access check as the history\nendpoint — the plan describes the work, so it is no less private than the chat.","operationId":"session_todos_chat_sessions__session_id__todos_get","parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Session Id"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TodoItem"},"title":"Response Session Todos Chat Sessions  Session Id  Todos Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/chat/sessions/{session_id}/events":{"get":{"tags":["chat"],"summary":"Session Events","description":"Live messages appended to a session, as SSE.\n\nA turn the caller streams itself arrives on that stream. This is for everything\nelse: a scheduled task firing, or another device writing to the same session. Pass\n``after`` (a message id) to be sent anything newer first, so a reconnect has no gap.\n\nEvery message is re-read through the same access check as the history endpoint, so\na notification can never reveal what a plain GET would refuse.","operationId":"session_events_chat_sessions__session_id__events_get","parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Session Id"}},{"name":"after","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"After"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/chat/sessions/{session_id}/run":{"get":{"tags":["chat"],"summary":"Active Run","description":"Which run is still generating on this conversation, so a new client can attach.\n\nResuming a stream has always worked; finding the run to resume did not. A run id was\nreturned on the POST and held in the memory of the tab that made it, so a reload — the\ncase users actually hit — lost it, and `sessions/{id}/messages` shows nothing useful\nbecause the assistant's reply is not stored until the turn ends. The answer was an\nempty bubble until generation finished.\n\nOwnership is checked on the SESSION, so this cannot be used to discover that a run id\nexists on somebody else's conversation.\n\nIn-memory, and therefore per process: with several API workers behind a load balancer\nthis answers for the worker that took the request. That is the same constraint the\nresume endpoint itself has always had — but it must not be a SILENT one, so a negative\nanswer carries `authoritative` and a caller can tell \"nothing is running\" from \"not\nhere, possibly elsewhere\". Route by run id (or pin a session to a worker) to make it\nreliable at more than one worker.","operationId":"active_run_chat_sessions__session_id__run_get","parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Session Id"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActiveRun"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/chat/outcomes":{"get":{"tags":["chat"],"summary":"Turn Outcomes","description":"Whether turns on this project are succeeding, and what the last failure said.\n\n**Admin or service only.** It is a statement about the project rather than about any\none conversation, and an end-user token has no business reading how the tenant as a\nwhole is doing.\n\nDeliberately says nothing about what to DO. Whether the platform should ever refuse a\nclient that cannot succeed, and whether a failing turn should carry a back-off hint,\nare product decisions that change what a customer experiences on a bad day (OBE-119).\nThis is the half nobody disagrees about: the state was already recorded and could not\nbe read.","operationId":"turn_outcomes_chat_outcomes_get","parameters":[{"name":"window_hours","in":"query","required":false,"schema":{"type":"integer","maximum":168,"minimum":1,"default":24,"title":"Window Hours"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TurnOutcomes"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/chat/sessions/{session_id}":{"patch":{"tags":["chat"],"summary":"Rename Session","description":"Rename a conversation, or clear its name.\n\nNeeds no capability: a title is the client's own label for a conversation it already\nowns, and `auto_title` governs whether we spend a model call writing one — not whether\nthe owner may name their own chat. Setting one before the first turn is also how a\nclient opts out of generation entirely.","operationId":"rename_session_chat_sessions__session_id__patch","parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Session Id"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenameRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["chat"],"summary":"Delete Session","operationId":"delete_session_chat_sessions__session_id__delete","parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Session Id"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/chat/sessions/{session_id}/fork":{"post":{"tags":["chat"],"summary":"Fork Session","description":"Create a new chat by copying an existing one up to (and including) a message.\nLets a user branch a conversation from any point.","operationId":"fork_session_chat_sessions__session_id__fork_post","parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Session Id"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForkRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/audit":{"get":{"tags":["governance"],"summary":"List Audit","operationId":"list_audit_audit_get","parameters":[{"name":"action","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Action"}},{"name":"subject","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Subject"}},{"name":"document","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Document"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":1000,"default":100,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditPage"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/audit/forget":{"post":{"tags":["governance"],"summary":"Forget","description":"Right-to-be-forgotten: purge a subject's documents, chat sessions/messages,\nsandboxes, and vectors (documents + memories + wikis) within the tenant.","operationId":"forget_audit_forget_post","parameters":[{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForgetRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForgetResult"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/memory":{"get":{"tags":["memory"],"summary":"List Items","operationId":"list_items_memory_get","parameters":[{"name":"kind","in":"query","required":false,"schema":{"type":"string","description":"memory | wiki","default":"memory","title":"Kind"},"description":"memory | wiki"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":1000,"default":200,"title":"Limit"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/KnowledgeItem"},"title":"Response List Items Memory Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/memory/{item_id}":{"delete":{"tags":["memory"],"summary":"Delete Item","description":"Remove a memory or wiki page.\n\nDeliberately restricted to the owner or an admin: a shared wiki page is read by the\nwhole project, so deleting one is not something any end-user token should do.","operationId":"delete_item_memory__item_id__delete","parameters":[{"name":"item_id","in":"path","required":true,"schema":{"type":"string","title":"Item Id"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/plugins":{"post":{"tags":["plugins"],"summary":"Upload Plugin","operationId":"upload_plugin_plugins_post","parameters":[{"name":"visibility","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"private (yours) | tenant (everyone in the project). Defaults to tenant for a service key and private for an end-user token.","title":"Visibility"},"description":"private (yours) | tenant (everyone in the project). Defaults to tenant for a service key and private for an end-user token."},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_upload_plugin_plugins_post"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PluginOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["plugins"],"summary":"List Plugins","operationId":"list_plugins_plugins_get","parameters":[{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PluginOut"},"title":"Response List Plugins Plugins Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/plugins/{plugin_id}":{"delete":{"tags":["plugins"],"summary":"Delete Plugin","operationId":"delete_plugin_plugins__plugin_id__delete","parameters":[{"name":"plugin_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Plugin Id"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/documents":{"post":{"tags":["documents"],"summary":"Upload Document","operationId":"upload_document_documents_post","parameters":[{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_upload_document_documents_post"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["documents"],"summary":"List Documents","description":"The documents this token may see, newest first.\n\nA PAGE, and it says so. This returned a bare unbounded array — the shape `/chat/sessions`\nhad before OBE-73 — on the one collection that only ever grows: 302 documents was 181,628\nbytes on every call, and a 10k corpus would be ~6MB on a route a dashboard opens with\n(OBE-190). A bare array also asserts completeness by omission, so a client could not tell\na whole corpus from as much of it as it happened to get.\n\n`limit` and `offset` are BOUNDED at the schema, not clamped in the handler: `?limit=0`,\n`?limit=-1` and `?limit=abc` are 422s naming the bound rather than 200s that quietly mean\nsomething else. That is the same treatment every request number got in OBE-175, applied\nto a query parameter — which is where it had never been applied at all.","operationId":"list_documents_documents_get","parameters":[{"name":"tag","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tag"}},{"name":"status_filter","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status Filter"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":100,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"name":"with_total","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"With Total"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentPage"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/documents/{document_id}":{"get":{"tags":["documents"],"summary":"Get Document","operationId":"get_document_documents__document_id__get","parameters":[{"name":"document_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Document Id"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["documents"],"summary":"Update Document","description":"Update tags / visibility / ACL. Syncs the change into the vector payload so\nretrieval authorization stays consistent.","operationId":"update_document_documents__document_id__patch","parameters":[{"name":"document_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Document Id"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentPatch"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["documents"],"summary":"Delete Document","operationId":"delete_document_documents__document_id__delete","parameters":[{"name":"document_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Document Id"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/documents/{document_id}/reingest":{"post":{"tags":["documents"],"summary":"Reingest Document","description":"Re-run ingestion (e.g. after a parser/embedding-model change, or to retry a\nfailed one). Drops old vectors and reprocesses the stored file.","operationId":"reingest_document_documents__document_id__reingest_post","parameters":[{"name":"document_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Document Id"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/documents/{document_id}/chunks":{"get":{"tags":["documents"],"summary":"Document Chunks","description":"Inspect the stored chunks for a document.","operationId":"document_chunks_documents__document_id__chunks_get","parameters":[{"name":"document_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Document Id"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ChunkOut"},"title":"Response Document Chunks Documents  Document Id  Chunks Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/documents/presign-upload":{"post":{"tags":["documents"],"summary":"Presign Upload","operationId":"presign_upload_documents_presign_upload_post","parameters":[{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PresignUploadRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PresignUploadResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/documents/{document_id}/presign-parts":{"post":{"tags":["documents"],"summary":"Presign Parts","operationId":"presign_parts_documents__document_id__presign_parts_post","parameters":[{"name":"document_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Document Id"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PresignPartsRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PresignPartsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/documents/{document_id}/complete-upload":{"post":{"tags":["documents"],"summary":"Complete Upload","operationId":"complete_upload_documents__document_id__complete_upload_post","parameters":[{"name":"document_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Document Id"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompleteUploadRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/documents/{document_id}/abort-upload":{"post":{"tags":["documents"],"summary":"Abort Upload","operationId":"abort_upload_documents__document_id__abort_upload_post","parameters":[{"name":"document_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Document Id"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AbortUploadRequest"}}}},"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/documents/{document_id}/download-url":{"get":{"tags":["documents"],"summary":"Download Url","operationId":"download_url_documents__document_id__download_url_get","parameters":[{"name":"document_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Document Id"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DownloadUrlResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/documents/retrieve":{"post":{"tags":["documents"],"summary":"Retrieve","operationId":"retrieve_documents_retrieve_post","parameters":[{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetrieveRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/RetrievedChunkOut"},"title":"Response Retrieve Documents Retrieve Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/tasks":{"post":{"tags":["tasks"],"summary":"Create","operationId":"create_tasks_post","parameters":[{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaskCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaskOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["tasks"],"summary":"Index","operationId":"index_tasks_get","parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TaskOut"},"title":"Response Index Tasks Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/tasks/{task_id}":{"get":{"tags":["tasks"],"summary":"Show","operationId":"show_tasks__task_id__get","parameters":[{"name":"task_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Task Id"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaskOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/tasks/{task_id}/cancel":{"post":{"tags":["tasks"],"summary":"Cancel","operationId":"cancel_tasks__task_id__cancel_post","parameters":[{"name":"task_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Task Id"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaskOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/triggers":{"post":{"tags":["triggers"],"summary":"Create Trigger","operationId":"create_trigger_triggers_post","parameters":[{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TriggerCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TriggerOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["triggers"],"summary":"List Triggers","operationId":"list_triggers_triggers_get","parameters":[{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TriggerOut"},"title":"Response List Triggers Triggers Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/triggers/{trigger_id}":{"delete":{"tags":["triggers"],"summary":"Delete Trigger","operationId":"delete_trigger_triggers__trigger_id__delete","parameters":[{"name":"trigger_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Trigger Id"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/triggers/{trigger_id}/rotate":{"post":{"tags":["triggers"],"summary":"Rotate Trigger","description":"Give this trigger a new URL, keeping the old one alive for 24 hours.\n\nThe path is the credential, so a URL that has leaked can only be dealt with by\nchanging it — and changing it breaks the sending system at the moment of the change.\nThe window is what makes rotating something a customer will actually do: rotate,\ntell the other system its new address, and nothing is dropped in between.","operationId":"rotate_trigger_triggers__trigger_id__rotate_post","parameters":[{"name":"trigger_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Trigger Id"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TriggerOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/triggers/{slug}":{"post":{"tags":["triggers"],"summary":"Fire Trigger","description":"Called by the other system. No token — see the module docstring.","operationId":"fire_trigger_triggers__slug__post","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}},{"name":"X-Signature","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Signature"}},{"name":"X-Event-Id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Event-Id"}},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Idempotency-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Fire Trigger Triggers  Slug  Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/computers/host":{"get":{"tags":["computer"],"summary":"Describe Host","description":"What this deployment's sandboxes can do, so a client can hide what it doesn't\nhave (port exposure in particular) instead of offering a button that 501s.","operationId":"describe_host_computers_host_get","parameters":[{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Describe Host Computers Host Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/computers/sessions":{"post":{"tags":["computer"],"summary":"Create Sandbox Session","operationId":"create_sandbox_session_computers_sessions_post","parameters":[{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComputerSessionCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComputerSessionOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["computer"],"summary":"List Sandbox Sessions","operationId":"list_sandbox_sessions_computers_sessions_get","parameters":[{"name":"include_stopped","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Include Stopped"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ComputerSessionOut"},"title":"Response List Sandbox Sessions Computers Sessions Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/computers/sessions/{session_id}":{"get":{"tags":["computer"],"summary":"Get Sandbox Session","operationId":"get_sandbox_session_computers_sessions__session_id__get","parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Session Id"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComputerSessionOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["computer"],"summary":"Delete Sandbox Session","operationId":"delete_sandbox_session_computers_sessions__session_id__delete","parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Session Id"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/computers/sessions/{session_id}/pause":{"post":{"tags":["computer"],"summary":"Pause Sandbox Session","operationId":"pause_sandbox_session_computers_sessions__session_id__pause_post","parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Session Id"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComputerSessionOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/computers/sessions/{session_id}/resume":{"post":{"tags":["computer"],"summary":"Resume Sandbox Session","operationId":"resume_sandbox_session_computers_sessions__session_id__resume_post","parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Session Id"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComputerSessionOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/computers/sessions/{session_id}/files":{"post":{"tags":["computer"],"summary":"Upload To Sandbox","description":"Push a file straight into a sandbox (any type). Bytes go host → sandbox without\npassing through the model's context.","operationId":"upload_to_sandbox_computers_sessions__session_id__files_post","parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Session Id"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_upload_to_sandbox_computers_sessions__session_id__files_post"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Upload To Sandbox Computers Sessions  Session Id  Files Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["computer"],"summary":"Download From Sandbox","description":"Stream a file out of a sandbox.","operationId":"download_from_sandbox_computers_sessions__session_id__files_get","parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Session Id"}},{"name":"path","in":"query","required":true,"schema":{"type":"string","title":"Path"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/computers/sessions/{session_id}/exec":{"post":{"tags":["computer"],"summary":"Exec In Sandbox","description":"Run a command directly (the customer's own backend driving the sandbox).\n\nSame guardrails as the agent's tool, and the same ceiling: workspace-confined cwd,\na hard timeout, output clipped, and an audit entry.","operationId":"exec_in_sandbox_computers_sessions__session_id__exec_post","parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Session Id"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComputerExecRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComputerExecResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/voice/frontend":{"get":{"tags":["voice"],"summary":"Frontend Info","description":"What this deployment's speech frontend can do.\n\nPublished so a client offers the voices that exist rather than a hard-coded list. Asking\nfor one the host does not have fails at call setup, which is a much worse place for a\ncustomer to find out than a dropdown.","operationId":"frontend_info_voice_frontend_get","parameters":[{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VoiceFrontendOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/voice/sessions":{"post":{"tags":["voice"],"summary":"Open Call","description":"Open a call.\n\nThe chat session is resolved (or created) here rather than on the first turn, so the\ncaller's transcript has somewhere to land from the first word — and so a client can show\nthe conversation while the call is still going.","operationId":"open_call_voice_sessions_post","parameters":[{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VoiceSessionRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VoiceSessionOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["voice"],"summary":"List Calls","description":"Every call this token can see. A supervisor watching a floor sees the project's;\nan end-user sees their own — the same segment-aware check every other resource uses.","operationId":"list_calls_voice_sessions_get","parameters":[{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"type":"object"},"title":"Response List Calls Voice Sessions Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/voice/sessions/{call_id}":{"get":{"tags":["voice"],"summary":"Get Call","description":"Enough to reconnect. A page reload, or a second screen attaching to watch.","operationId":"get_call_voice_sessions__call_id__get","parameters":[{"name":"call_id","in":"path","required":true,"schema":{"type":"string","title":"Call Id"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VoiceSessionOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["voice"],"summary":"End Call","operationId":"end_call_voice_sessions__call_id__delete","parameters":[{"name":"call_id","in":"path","required":true,"schema":{"type":"string","title":"Call Id"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/voice/sessions/{call_id}/state":{"get":{"tags":["voice"],"summary":"Call State","operationId":"call_state_voice_sessions__call_id__state_get","parameters":[{"name":"call_id","in":"path","required":true,"schema":{"type":"string","title":"Call Id"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Call State Voice Sessions  Call Id  State Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/voice/sessions/{call_id}/bench":{"get":{"tags":["voice"],"summary":"Call Bench","description":"The latencies and the counts for this call.\n\nBoth, always. Splitting them into two endpoints is how a report ends up quoting a median\nresponse time with no dropped-turn rate beside it — and a latency average over the turns\nthat produced audio improves as the system gets worse.","operationId":"call_bench_voice_sessions__call_id__bench_get","parameters":[{"name":"call_id","in":"path","required":true,"schema":{"type":"string","title":"Call Id"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Call Bench Voice Sessions  Call Id  Bench Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/voice/sessions/{call_id}/events":{"get":{"tags":["voice"],"summary":"Call Events","description":"Everything that has happened on this call so far.\n\nA replay rather than a stream: the live stream is the WebSocket, and a second live\nchannel would be a second thing to keep in sync. This is what a client fetches on\nattaching, so a trace panel opened mid-call is not empty.","operationId":"call_events_voice_sessions__call_id__events_get","parameters":[{"name":"call_id","in":"path","required":true,"schema":{"type":"string","title":"Call Id"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Call Events Voice Sessions  Call Id  Events Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/voice/sessions/{call_id}/hold":{"post":{"tags":["voice"],"summary":"Hold Call","description":"Put the caller on hold from the application's side.\n\nHere as well as being a tool the agent can call, because the decision is sometimes the\napplication's: an app that has just triggered a workflow it knows takes half a minute\nshould not have to hope the model works that out.","operationId":"hold_call_voice_sessions__call_id__hold_post","parameters":[{"name":"call_id","in":"path","required":true,"schema":{"type":"string","title":"Call Id"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VoiceHoldRequest"}}}},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Hold Call Voice Sessions  Call Id  Hold Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/voice/sessions/{call_id}/resume":{"post":{"tags":["voice"],"summary":"Resume Call","operationId":"resume_call_voice_sessions__call_id__resume_post","parameters":[{"name":"call_id","in":"path","required":true,"schema":{"type":"string","title":"Call Id"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VoiceResumeRequest"}}}},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Resume Call Voice Sessions  Call Id  Resume Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/voice/sessions/{call_id}/transfer":{"post":{"tags":["voice"],"summary":"Transfer Call","description":"Hand the caller to a person.\n\nThe capability is checked here **and** inside the session. Twice on purpose: the 403 is\nthe honest answer to an API call, and the session's own refusal is what stops a tool the\nmodel reached for from escalating a call the token may not escalate — two different\ncallers, one rule.","operationId":"transfer_call_voice_sessions__call_id__transfer_post","parameters":[{"name":"call_id","in":"path","required":true,"schema":{"type":"string","title":"Call Id"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VoiceTransferRequest"}}}},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Transfer Call Voice Sessions  Call Id  Transfer Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/voice/sessions/{call_id}/context":{"post":{"tags":["voice"],"summary":"Inject Context","description":"Facts the frontend should know and not necessarily say.\n\nReports whether it landed rather than answering 202 regardless. A frontend that cannot be\nconditioned would otherwise leave the application believing the agent knows the caller's\naccount tier, and the symptom is an agent behaving generically for a customer the system\nknows is enterprise, with nothing anywhere saying why.","operationId":"inject_context_voice_sessions__call_id__context_post","parameters":[{"name":"call_id","in":"path","required":true,"schema":{"type":"string","title":"Call Id"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VoiceContextRequest"}}}},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Inject Context Voice Sessions  Call Id  Context Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/voice/sessions/{call_id}/speech":{"post":{"tags":["voice"],"summary":"Inject Speech","description":"A line the application wants said, in the frontend's voice.\n\nThe other half of `POST .../context`: that one is \"know this\", this one is \"say this\". For\nwhat only the application knows in the moment — a card that was just declined, an\nappointment that has moved, a line compliance requires on every call.\n\nNot for an answer. An answer is a delegation: it goes through the reasoner, gets a bridge\nwhile it is being composed, and is measured. Text pushed through here skips all three, so a\nclient using it to answer questions has built a worse version of the thing it is calling.\n\nReports what happened rather than 202-ing regardless. On hold, mid-transfer, or against a\nfrontend that cannot be forced, \"spoken\" is the wrong answer — and an application told its\ndisclosure was read when it was not has no way to discover otherwise.","operationId":"inject_speech_voice_sessions__call_id__speech_post","parameters":[{"name":"call_id","in":"path","required":true,"schema":{"type":"string","title":"Call Id"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VoiceSpeechRequest"}}}},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Inject Speech Voice Sessions  Call Id  Speech Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/":{"get":{"summary":"Root","operationId":"root__get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Root  Get"}}}}}}}},"components":{"schemas":{"AbortUploadRequest":{"properties":{"upload_id":{"type":"string","title":"Upload Id"}},"type":"object","required":["upload_id"],"title":"AbortUploadRequest"},"ActiveRun":{"properties":{"run_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Run Id"},"last_event_id":{"type":"integer","title":"Last Event Id","default":0},"authoritative":{"type":"boolean","title":"Authoritative","default":true},"attachable":{"type":"boolean","title":"Attachable","default":true},"status":{"type":"string","title":"Status","default":"idle"}},"type":"object","title":"ActiveRun","description":"The turn still generating on a conversation, if there is one."},"AgentQuestion":{"properties":{"id":{"type":"string","title":"Id"},"header":{"type":"string","title":"Header"},"question":{"type":"string","title":"Question"},"options":{"items":{"$ref":"#/components/schemas/QuestionOption"},"type":"array","title":"Options"},"multi_select":{"type":"boolean","title":"Multi Select","default":false},"allow_other":{"type":"boolean","title":"Allow Other","default":true}},"type":"object","required":["id","header","question"],"title":"AgentQuestion","description":"One decision the agent put to the user."},"ApprovalDecision":{"properties":{"tool_call_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tool Call Id"},"approved":{"type":"boolean","title":"Approved"},"note":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Note"}},"type":"object","required":["approved"],"title":"ApprovalDecision","description":"A person's answer to one paused approval — the model's, or a gated tool call's."},"Attachment":{"properties":{"id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Id"},"kind":{"type":"string","title":"Kind"},"url":{"type":"string","title":"Url"},"mime_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mime Type"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"format":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Format"},"size":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Size"},"to_sandbox":{"type":"boolean","title":"To Sandbox","default":false}},"type":"object","required":["kind","url"],"title":"Attachment","description":"A non-text part of a message (any modality the model supports).\n\n``kind`` is the modality: image | audio | video | file. ``url`` is a data: URI\n(base64) or an https URL. Input attachments ride on ChatRequest; model-produced\noutputs come back on ChatResponse. Each kind is gated by an ``input:<kind>`` /\n``output:<kind>`` capability."},"AuditEntry":{"properties":{"id":{"type":"string","title":"Id"},"subject":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Subject"},"action":{"type":"string","title":"Action"},"resource_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Resource Type"},"resource_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Resource Id"},"metadata":{"type":"object","title":"Metadata"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","subject","action","resource_type","resource_id","metadata","created_at"],"title":"AuditEntry"},"AuditPage":{"properties":{"items":{"items":{"$ref":"#/components/schemas/AuditEntry"},"type":"array","title":"Items"},"has_more":{"type":"boolean","title":"Has More","default":false},"next_offset":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Next Offset"}},"type":"object","required":["items"],"title":"AuditPage","description":"One page of the trail, and whether there is another.\n\nThe same envelope `DocumentPage` uses, for the reason OBE-190 gives one collection\nover: *\"a bare array asserts completeness by omission — nothing in it distinguishes\n'here is the set' from 'here is as much of it as you got'\"*.\n\nThat matters more here than anywhere else. A caller reading an audit trail is asking\nwhat happened, and silently receiving the most recent hundred of a thousand rows\nanswers a different question in the same shape — on the one collection whose whole\npurpose is being checkable after the fact (OBE-273)."},"Body_upload_document_documents_post":{"properties":{"file":{"type":"string","format":"binary","title":"File"},"tags":{"type":"string","title":"Tags","default":""},"visibility":{"type":"string","title":"Visibility","default":"private"},"visibility_scope":{"type":"string","title":"Visibility Scope","default":""},"acl_roles":{"type":"string","title":"Acl Roles","default":""},"acl_groups":{"type":"string","title":"Acl Groups","default":""}},"type":"object","required":["file"],"title":"Body_upload_document_documents_post"},"Body_upload_plugin_plugins_post":{"properties":{"file":{"anyOf":[{"type":"string","format":"binary"},{"type":"null"}],"title":"File","description":"A plugin .zip, a zipped folder of skills, or a single SKILL.md."},"files":{"items":{"type":"string","format":"binary"},"type":"array","title":"Files","description":"A folder's files, each named by its path relative to the folder. This is what a browser directory picker produces; no archive is needed."}},"type":"object","title":"Body_upload_plugin_plugins_post"},"Body_upload_to_sandbox_computers_sessions__session_id__files_post":{"properties":{"file":{"type":"string","format":"binary","title":"File"},"dest":{"type":"string","title":"Dest","default":""}},"type":"object","required":["file"],"title":"Body_upload_to_sandbox_computers_sessions__session_id__files_post"},"BrowserFrame":{"properties":{"url":{"type":"string","title":"Url","default":""},"title":{"type":"string","title":"Title","default":""},"image":{"type":"string","title":"Image","default":""},"width":{"type":"integer","title":"Width","default":0},"height":{"type":"integer","title":"Height","default":0},"origin":{"additionalProperties":{"type":"integer"},"type":"object","title":"Origin"},"clipped":{"type":"boolean","title":"Clipped","default":false},"matched":{"type":"boolean","title":"Matched","default":false},"region":{"type":"string","title":"Region","description":"selector | detected | viewport","default":"viewport"}},"type":"object","title":"BrowserFrame","description":"A picture of the handed-over page, and what a click on it means.\n\n``origin`` is where the crop was taken from. A click is sent back in image space\ntogether with the origin it was taken at, so a frame that moved between render and\nclick cannot silently displace it."},"BrowserFrameRequest":{"properties":{"selector":{"type":"string","title":"Selector","default":""}},"type":"object","title":"BrowserFrameRequest"},"BrowserInput":{"properties":{"selector":{"type":"string","title":"Selector","default":""},"type":{"type":"string","title":"Type","description":"click | pointer_down | pointer_move | pointer_up | drag | wheel | type | key | scroll"},"x":{"type":"integer","title":"X","default":0},"y":{"type":"integer","title":"Y","default":0},"origin":{"additionalProperties":{"type":"integer"},"type":"object","title":"Origin"},"text":{"type":"string","title":"Text","default":""},"key":{"type":"string","title":"Key","default":"Enter"},"pixels":{"type":"integer","title":"Pixels","default":400},"modifiers":{"items":{"type":"string"},"type":"array","title":"Modifiers"},"button":{"type":"string","title":"Button","description":"left | right | middle | back | forward","default":"left"},"clicks":{"type":"integer","minimum":1.0,"title":"Clicks","default":1},"to":{"additionalProperties":{"type":"integer"},"type":"object","title":"To"},"hold_ms":{"type":"integer","minimum":0.0,"title":"Hold Ms","default":0},"steps":{"type":"integer","minimum":1.0,"title":"Steps","default":24},"delta_x":{"type":"integer","title":"Delta X","default":0},"delta_y":{"type":"integer","title":"Delta Y","default":0},"want_frame":{"type":"boolean","title":"Want Frame","default":true}},"type":"object","required":["type"],"title":"BrowserInput","description":"One thing the user did, relayed into the page.\n\nThe pointer kinds are what make a hand-off able to do more than tap. Press, move,\nrelease is a drag — which is what a slider puzzle asks for, and what most bot checks\nnow use — and the page sees the real gesture because it is the real gesture."},"ChatRequest":{"properties":{"session_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Session Id"},"message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Message","description":"User message for a new turn."},"messages":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Messages","description":"Additional user messages for this turn, in order. Stored separately; the agent replies once to all of them."},"attachments":{"anyOf":[{"items":{"$ref":"#/components/schemas/Attachment"},"type":"array"},{"type":"null"}],"title":"Attachments","description":"Multimodal inputs (images/audio/video/files) for this turn."},"output_modalities":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Output Modalities"},"tool_results":{"anyOf":[{"items":{"$ref":"#/components/schemas/ClientToolResult"},"type":"array"},{"type":"null"}],"title":"Tool Results"},"handoff_done":{"type":"boolean","title":"Handoff Done","default":false},"question_answers":{"anyOf":[{"items":{"$ref":"#/components/schemas/QuestionAnswer"},"type":"array"},{"type":"null"}],"title":"Question Answers"},"approval_decisions":{"anyOf":[{"items":{"$ref":"#/components/schemas/ApprovalDecision"},"type":"array"},{"type":"null"}],"title":"Approval Decisions"},"client_tools":{"anyOf":[{"items":{"type":"object"},"type":"array"},{"type":"null"}],"title":"Client Tools"},"mcp_servers":{"anyOf":[{"items":{"type":"object"},"type":"array"},{"type":"null"}],"title":"Mcp Servers"},"allowed_tools":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Allowed Tools","description":"Allow-list of server tool names (None = all)."},"document_ids":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Document Ids"},"tags":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Tags"},"enable_rag":{"type":"boolean","title":"Enable Rag","default":true},"enable_scheduling":{"type":"boolean","title":"Enable Scheduling","default":true},"enable_memory":{"type":"boolean","title":"Enable Memory","default":true},"enable_web_search":{"type":"boolean","title":"Enable Web Search","default":true},"enable_action_space":{"type":"boolean","title":"Enable Action Space","default":true},"enable_todo":{"type":"boolean","title":"Enable Todo","default":true},"enable_ask_user":{"type":"boolean","title":"Enable Ask User","default":true},"enable_browser":{"type":"boolean","title":"Enable Browser","default":true},"enable_subagents":{"type":"boolean","title":"Enable Subagents","default":true},"enable_approvals":{"type":"boolean","title":"Enable Approvals","default":true},"enable_auto_title":{"type":"boolean","title":"Enable Auto Title","default":true},"title_from":{"type":"string","enum":["prompt","response"],"title":"Title From","default":"prompt"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"ui_tools":{"anyOf":[{"items":{"type":"object"},"type":"array"},{"type":"null"}],"title":"Ui Tools"},"enable_webhook_tools":{"type":"boolean","title":"Enable Webhook Tools","default":true},"enable_voice_control":{"type":"boolean","title":"Enable Voice Control","default":true},"enable_plugins":{"type":"boolean","title":"Enable Plugins","default":true},"plugins":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Plugins"},"enable_computer":{"type":"boolean","title":"Enable Computer","default":true},"computer_session_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Computer Session Id"},"model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Model"},"system_prompt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"System Prompt"},"temperature":{"type":"number","maximum":2.0,"minimum":0.0,"title":"Temperature","default":0.2},"reasoning_effort":{"anyOf":[{"type":"string","enum":["minimal","low","medium","high"]},{"type":"null"}],"title":"Reasoning Effort"},"user_ref":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Ref"}},"type":"object","title":"ChatRequest"},"ChatResponse":{"properties":{"session_id":{"type":"string","format":"uuid","title":"Session Id"},"content":{"type":"string","title":"Content"},"requires_action":{"type":"boolean","title":"Requires Action","default":false},"tool_calls":{"items":{"$ref":"#/components/schemas/PendingToolCall"},"type":"array","title":"Tool Calls"},"questions":{"items":{"$ref":"#/components/schemas/PendingQuestions"},"type":"array","title":"Questions"},"approvals":{"items":{"$ref":"#/components/schemas/PendingApproval"},"type":"array","title":"Approvals"},"ui":{"items":{"$ref":"#/components/schemas/UiRender"},"type":"array","title":"Ui"},"todos":{"items":{"$ref":"#/components/schemas/TodoItem"},"type":"array","title":"Todos"},"subagents":{"items":{"$ref":"#/components/schemas/SubagentOut"},"type":"array","title":"Subagents"},"handoff":{"anyOf":[{"$ref":"#/components/schemas/HandoffOut"},{"type":"null"}]},"context":{"anyOf":[{"$ref":"#/components/schemas/ContextReport"},{"type":"null"}]},"citations":{"items":{"$ref":"#/components/schemas/Citation"},"type":"array","title":"Citations"},"claims":{"items":{"type":"object"},"type":"array","title":"Claims"},"attribution":{"type":"string","title":"Attribution","default":"none"},"attachments":{"items":{"$ref":"#/components/schemas/Attachment"},"type":"array","title":"Attachments","description":"Model-produced non-text outputs (images/audio/...)."},"guard_flags":{"items":{"type":"string"},"type":"array","title":"Guard Flags"},"warnings":{"items":{"type":"string"},"type":"array","title":"Warnings"},"model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Model"},"model_tier":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Model Tier"},"reasoning":{"type":"string","title":"Reasoning","default":""},"finish_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Finish Reason"},"steered":{"items":{"type":"string"},"type":"array","title":"Steered"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"}},"type":"object","required":["session_id","content"],"title":"ChatResponse"},"ChunkOut":{"properties":{"chunk_index":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Chunk Index"},"page":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Page"},"text":{"type":"string","title":"Text"}},"type":"object","required":["text"],"title":"ChunkOut"},"Citation":{"properties":{"marker":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Marker"},"kind":{"type":"string","title":"Kind","default":"document"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Url"},"quote":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Quote"},"used":{"type":"boolean","title":"Used","default":false},"document_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Document Id"},"chunk_index":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Chunk Index"},"filename":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Filename"},"page":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Page"},"score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Score"},"tool":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tool"},"stale":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Stale"},"screenshot":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Screenshot"}},"type":"object","title":"Citation","description":"One thing this turn was shown that a sentence can be attributed to.\n\n**One list, one numbering, whatever it came from.** There were five mechanisms and only\nthe first of them could be footnoted: a document passage got a number, a web page and an\nMCP result went to a separate `sources` list that no claim could point at, a memory was\ndeliberately not evidence, and a sandbox computation was grounding for the guardrail and\ninvisible to the reader. So the only answer a client could render footnotes for was one\nthat came out of the corpus — while the product's own pitch is an agent that also\nsearches the web, remembers, reaches other systems and computes.\n\nProvenance is `kind`, not a different shape and not a different array. Render `title`,\n`quote` and `url`; branch on `kind` only for the extras you want (a page number, a\nscore, the tool's name)."},"ClientToolResult":{"properties":{"tool_call_id":{"type":"string","title":"Tool Call Id"},"content":{"type":"string","title":"Content"}},"type":"object","required":["tool_call_id","content"],"title":"ClientToolResult"},"CompleteUploadRequest":{"properties":{"upload_id":{"type":"string","title":"Upload Id"},"parts":{"items":{"$ref":"#/components/schemas/CompletedPart"},"type":"array","title":"Parts"}},"type":"object","required":["upload_id","parts"],"title":"CompleteUploadRequest"},"CompletedPart":{"properties":{"part_number":{"type":"integer","title":"Part Number"},"etag":{"type":"string","title":"Etag"}},"type":"object","required":["part_number","etag"],"title":"CompletedPart"},"ComputerExecRequest":{"properties":{"command":{"type":"string","title":"Command"},"cwd":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cwd"},"timeout_s":{"anyOf":[{"type":"integer","minimum":1.0},{"type":"null"}],"title":"Timeout S"},"stdin":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Stdin"}},"type":"object","required":["command"],"title":"ComputerExecRequest"},"ComputerExecResponse":{"properties":{"stdout":{"type":"string","title":"Stdout","default":""},"stderr":{"type":"string","title":"Stderr","default":""},"exit_code":{"type":"integer","title":"Exit Code","default":0},"truncated":{"type":"boolean","title":"Truncated","default":false},"timed_out":{"type":"boolean","title":"Timed Out","default":false},"duration_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Duration Ms"}},"type":"object","title":"ComputerExecResponse"},"ComputerSessionCreate":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"chat_session_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Chat Session Id"}},"type":"object","title":"ComputerSessionCreate"},"ComputerSessionOut":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"provider":{"type":"string","title":"Provider"},"external_id":{"type":"string","title":"External Id"},"status":{"type":"string","title":"Status"},"workdir":{"type":"string","title":"Workdir"},"chat_session_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Chat Session Id"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"},"last_used_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Used At"},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expires At"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","provider","external_id","status","workdir","created_at"],"title":"ComputerSessionOut"},"ContextReport":{"properties":{"strategy":{"type":"string","title":"Strategy"},"tokens_before":{"type":"integer","title":"Tokens Before"},"tokens_after":{"type":"integer","title":"Tokens After"},"budget":{"type":"integer","title":"Budget"},"dropped":{"type":"integer","title":"Dropped","default":0},"truncated":{"type":"integer","title":"Truncated","default":0},"summarized":{"type":"boolean","title":"Summarized","default":false}},"type":"object","required":["strategy","tokens_before","tokens_after","budget"],"title":"ContextReport","description":"What context management did to fit this turn's history in the model's window.\n\nAbsent when the conversation fit as it was. Present, it means the model did NOT\nsee the whole transcript — which is worth knowing when an answer seems to have\nforgotten something."},"DocumentOut":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"filename":{"type":"string","title":"Filename"},"content_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Content Type"},"tags":{"items":{"type":"string"},"type":"array","title":"Tags"},"owner_subject":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Owner Subject"},"visibility":{"type":"string","title":"Visibility","default":"private"},"visibility_scope":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Visibility Scope"},"acl_roles":{"items":{"type":"string"},"type":"array","title":"Acl Roles"},"acl_groups":{"items":{"type":"string"},"type":"array","title":"Acl Groups"},"status":{"type":"string","title":"Status"},"chunk_count":{"type":"integer","title":"Chunk Count"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"},"embedding_model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Embedding Model"},"pipeline_version":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pipeline Version"},"content_hash":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Content Hash"},"duplicate_of":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Duplicate Of"},"read_with":{"items":{"type":"string"},"type":"array","title":"Read With"},"pdf_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pdf Type"},"ocr_page_count":{"type":"integer","title":"Ocr Page Count","default":0},"failure":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Failure"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","filename","content_type","tags","status","chunk_count","error","created_at"],"title":"DocumentOut"},"DocumentPage":{"properties":{"items":{"items":{"$ref":"#/components/schemas/DocumentOut"},"type":"array","title":"Items"},"has_more":{"type":"boolean","title":"Has More","default":false},"next_offset":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Next Offset"},"hidden":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Hidden"},"total":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Total"}},"type":"object","required":["items"],"title":"DocumentPage","description":"One page of documents, and whether there is another.\n\nThe same envelope `SessionPage` uses, for the same reason and one collection over.\n`GET /documents` was still the shape sessions used to be — a bare, unbounded array — and\nit is the collection that grows without bound in normal use: sessions at least churn, a\ncorpus only accumulates. Measured on a live project of 302 documents, every call returned\nall 302 and 181,628 bytes, and a 10k corpus would be a ~6MB response on a route a\ndashboard calls on page load (OBE-190).\n\nA bare array also asserts completeness by omission: nothing in it distinguishes \"here is\nthe set\" from \"here is as much of it as you got\".\n\nNo `total`, for the reason `SessionPage` gives: the count is a second query on every\nrender, and \"is there another page\" is the question a caller actually has. One spare row\nanswers it."},"DocumentPatch":{"properties":{"tags":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Tags"},"visibility":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Visibility"},"visibility_scope":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Visibility Scope"},"acl_roles":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Acl Roles"},"acl_groups":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Acl Groups"}},"type":"object","title":"DocumentPatch"},"DownloadUrlResponse":{"properties":{"url":{"type":"string","title":"Url"},"expires_in":{"type":"integer","title":"Expires In"},"size":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Size"},"content_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Content Type"}},"type":"object","required":["url","expires_in"],"title":"DownloadUrlResponse"},"FollowupsOut":{"properties":{"suggestions":{"items":{"type":"string"},"type":"array","title":"Suggestions"}},"type":"object","title":"FollowupsOut","description":"Things the user might say next, in their own voice.\n\nSent as ordinary messages when clicked — the agent is never told they were\nsuggested, and they are not stored anywhere. Empty when nothing sensible follows,\nor when generation failed; a missing affordance is not an error worth surfacing."},"FollowupsRequest":{"properties":{"count":{"type":"integer","maximum":5.0,"minimum":1.0,"title":"Count","description":"How many to suggest.","default":3}},"type":"object","title":"FollowupsRequest"},"ForgetRequest":{"properties":{"subject":{"type":"string","title":"Subject"}},"type":"object","required":["subject"],"title":"ForgetRequest"},"ForgetResult":{"properties":{"subject":{"type":"string","title":"Subject"},"documents_deleted":{"type":"integer","title":"Documents Deleted"},"sessions_deleted":{"type":"integer","title":"Sessions Deleted"},"sandboxes_destroyed":{"type":"integer","title":"Sandboxes Destroyed","default":0},"tasks_cancelled":{"type":"integer","title":"Tasks Cancelled","default":0},"vectors_purged":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Vectors Purged"},"rows_deleted":{"additionalProperties":{"type":"integer"},"type":"object","title":"Rows Deleted","default":{}},"objects_deleted":{"type":"integer","title":"Objects Deleted","default":0}},"type":"object","required":["subject","documents_deleted","sessions_deleted","vectors_purged"],"title":"ForgetResult"},"ForkRequest":{"properties":{"up_to_message_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Up To Message Id"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"}},"type":"object","title":"ForkRequest"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"HandoffCheck":{"properties":{"state":{"type":"string","title":"State","description":"solved | gone | unsolved | loading | unclear. `gone` and `loading` are decided from the page itself without asking a model."},"done":{"type":"boolean","title":"Done","default":false},"checked":{"type":"boolean","title":"Checked","default":true},"will_check_again":{"type":"boolean","title":"Will Check Again","default":true},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason"}},"type":"object","required":["state"],"title":"HandoffCheck","description":"Whether the person seems to have finished with a handed-over page.\n\n``state`` is one of four fixed words — the checker is shown a CAPTCHA, and a closed\nvocabulary is what stops it being a way to read one out.\n\n``checked`` is false when no call was made at all, and it used to be the only signal\n— which conflated two opposite instructions. \"Rate-limited, ask again in a moment\"\nand \"nothing here will ever answer\" produced the identical body, so a client doing\nwhat the docs said (poll until it reports finished) polled a blocking hand-off for\never and the turn sat there. ``will_check_again`` is the field a loop should branch\non, and ``reason`` says which of the ways it was."},"HandoffOut":{"properties":{"active":{"type":"boolean","title":"Active","default":true},"blocking":{"type":"boolean","title":"Blocking","default":true},"interactive":{"type":"boolean","title":"Interactive","default":true},"reason":{"type":"string","title":"Reason","default":""},"url":{"type":"string","title":"Url","default":""},"selector":{"type":"string","title":"Selector","default":""},"clipped":{"type":"boolean","title":"Clipped","default":false},"auto_done":{"type":"boolean","title":"Auto Done","default":false}},"type":"object","title":"HandoffOut","description":"A page the agent has put in front of the user.\n\n``blocking`` means the turn stopped and resumes when they say they're done — the\nsame shape as a pending client tool call, because it is the same situation.\n``interactive`` false means show it, don't let them touch it."},"KnowledgeItem":{"properties":{"id":{"type":"string","title":"Id"},"kind":{"type":"string","title":"Kind"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"text":{"type":"string","title":"Text"},"owner_subject":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Owner Subject"},"visibility":{"type":"string","title":"Visibility","default":"private"},"source_document_ids":{"items":{"type":"string"},"type":"array","title":"Source Document Ids"},"written_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Written At"},"stale":{"type":"boolean","title":"Stale","default":false},"stale_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Stale Reason"}},"type":"object","required":["id","kind","text"],"title":"KnowledgeItem","description":"One memory or wiki page, for browsing and curating what the agent wrote."},"McpProbeRequest":{"properties":{"name":{"type":"string","title":"Name","default":"probe"},"url":{"type":"string","title":"Url"},"transport":{"type":"string","title":"Transport","default":"streamable_http"},"headers":{"additionalProperties":{"type":"string"},"type":"object","title":"Headers"}},"type":"object","required":["url"],"title":"McpProbeRequest","description":"One MCP server to ask about, stored nowhere.\n\nThe same shape a registered server has, so the caller sends what they were about to\nregister rather than a second spelling of it."},"McpProbeResult":{"properties":{"ok":{"type":"boolean","title":"Ok"},"tools":{"type":"integer","title":"Tools","default":0},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"}},"type":"object","required":["ok"],"title":"McpProbeResult","description":"What the tool loader made of it — the listing's verdict, before anything is stored.\n\nDeliberately the listing's own fields (`ok`, `tools`, `error`) rather than a summary:\ntwo ways of saying one verdict is how they come to disagree (OBE-275)."},"MessageOut":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"role":{"type":"string","title":"Role"},"content":{"type":"string","title":"Content"},"extra":{"type":"object","title":"Extra"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","role","content","extra","created_at"],"title":"MessageOut"},"PendingApproval":{"properties":{"tool_call_id":{"type":"string","title":"Tool Call Id"},"action":{"type":"string","title":"Action"},"detail":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Detail"},"consequence":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Consequence"},"tool":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tool"},"arguments":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Arguments"}},"type":"object","required":["tool_call_id","action"],"title":"PendingApproval","description":"Something the agent stopped to ask permission for.\n\nThe pending call — if there is one — is NOT in `tool_calls`: an approval is not the\nclient's work to execute, so a caller that auto-runs tool calls can never grant one on\nthe user's behalf. Resume by sending `approval_decisions`.\n\nTwo ways to get here, told apart by `tool`:\n\n* The **model asked** (`request_approval`), and `tool` is null: it is describing work\n  it has not started, in its own words.\n* A **tool demanded it** — the caller declared `requires_approval: true` on it — and\n  `tool` names the call being held back. That gate fires because the tool was called,\n  so it holds whether or not the model would have thought to ask."},"PendingQuestions":{"properties":{"tool_call_id":{"type":"string","title":"Tool Call Id"},"questions":{"items":{"$ref":"#/components/schemas/AgentQuestion"},"type":"array","title":"Questions"}},"type":"object","required":["tool_call_id"],"title":"PendingQuestions","description":"A paused ``ask_user`` call: the questions, and the id that answers them."},"PendingToolCall":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"args":{"type":"object","title":"Args"}},"type":"object","required":["id","name","args"],"title":"PendingToolCall"},"PluginOut":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"name":{"type":"string","title":"Name"},"version":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Version"},"description":{"type":"string","title":"Description","default":""},"visibility":{"type":"string","title":"Visibility"},"owner_subject":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Owner Subject"},"enabled":{"type":"boolean","title":"Enabled"},"size_bytes":{"type":"integer","title":"Size Bytes"},"skills":{"items":{"$ref":"#/components/schemas/SkillOut"},"type":"array","title":"Skills","default":[]},"mcp_servers":{"items":{"type":"string"},"type":"array","title":"Mcp Servers","default":[]},"warnings":{"items":{"type":"string"},"type":"array","title":"Warnings","default":[]}},"type":"object","required":["id","name","visibility","enabled","size_bytes"],"title":"PluginOut"},"PresignPartsRequest":{"properties":{"upload_id":{"type":"string","title":"Upload Id"},"part_numbers":{"items":{"type":"integer"},"type":"array","title":"Part Numbers"}},"type":"object","required":["upload_id","part_numbers"],"title":"PresignPartsRequest"},"PresignPartsResponse":{"properties":{"urls":{"items":{"$ref":"#/components/schemas/PresignedPart"},"type":"array","title":"Urls"}},"type":"object","required":["urls"],"title":"PresignPartsResponse"},"PresignUploadRequest":{"properties":{"filename":{"type":"string","title":"Filename"},"content_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Content Type"},"tags":{"items":{"type":"string"},"type":"array","title":"Tags"},"visibility":{"type":"string","title":"Visibility","default":"private"},"visibility_scope":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Visibility Scope"},"acl_roles":{"items":{"type":"string"},"type":"array","title":"Acl Roles"},"acl_groups":{"items":{"type":"string"},"type":"array","title":"Acl Groups"}},"type":"object","required":["filename"],"title":"PresignUploadRequest"},"PresignUploadResponse":{"properties":{"document_id":{"type":"string","format":"uuid","title":"Document Id"},"upload_id":{"type":"string","title":"Upload Id"},"s3_key":{"type":"string","title":"S3 Key"},"part_size":{"type":"integer","title":"Part Size"}},"type":"object","required":["document_id","upload_id","s3_key","part_size"],"title":"PresignUploadResponse"},"PresignedPart":{"properties":{"part_number":{"type":"integer","title":"Part Number"},"url":{"type":"string","title":"Url"}},"type":"object","required":["part_number","url"],"title":"PresignedPart"},"QuestionAnswer":{"properties":{"tool_call_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tool Call Id"},"answers":{"items":{"$ref":"#/components/schemas/QuestionAnswerItem"},"type":"array","title":"Answers"},"chat_instead":{"type":"boolean","title":"Chat Instead","default":false},"message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Message"}},"type":"object","title":"QuestionAnswer","description":"The answer to one paused ``ask_user`` call, resuming the turn.\n\n``chat_instead`` is the user declining the picker (\"chat about this instead\"):\nthe model is told to drop the question and keep talking rather than re-ask it."},"QuestionAnswerItem":{"properties":{"question_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Question Id"},"selected":{"items":{"type":"string"},"type":"array","title":"Selected"},"text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Text"}},"type":"object","title":"QuestionAnswerItem","description":"What the user chose for ONE question in an ``ask_user`` batch."},"QuestionOption":{"properties":{"label":{"type":"string","title":"Label"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"}},"type":"object","required":["label"],"title":"QuestionOption"},"RecapOut":{"properties":{"recap":{"type":"string","title":"Recap","default":""}},"type":"object","title":"RecapOut","description":"One or two sentences on where the conversation got to, for a user returning\nafter a while. Generated on demand, never stored, never shown to the agent."},"RenameRequest":{"properties":{"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"}},"type":"object","title":"RenameRequest","description":"A new name for a conversation. Empty or null clears it."},"RetrieveRequest":{"properties":{"query":{"type":"string","title":"Query"},"document_ids":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Document Ids"},"tags":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Tags"},"top_k":{"anyOf":[{"type":"integer","minimum":1.0},{"type":"null"}],"title":"Top K"},"top_n":{"anyOf":[{"type":"integer","minimum":1.0},{"type":"null"}],"title":"Top N"}},"type":"object","required":["query"],"title":"RetrieveRequest"},"RetrievedChunkOut":{"properties":{"text":{"type":"string","title":"Text"},"score":{"type":"number","title":"Score"},"document_id":{"type":"string","title":"Document Id"},"chunk_index":{"type":"integer","title":"Chunk Index"},"metadata":{"type":"object","title":"Metadata"}},"type":"object","required":["text","score","document_id","chunk_index","metadata"],"title":"RetrievedChunkOut"},"SessionOut":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"user_ref":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Ref"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"},"parent_session_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Parent Session Id"},"last_model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Model"},"last_error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Error"},"last_finish_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Finish Reason"},"turn_count":{"type":"integer","title":"Turn Count","default":0},"status":{"type":"string","title":"Status","readOnly":true}},"type":"object","required":["id","title","user_ref","created_at","updated_at","status"],"title":"SessionOut"},"SessionPage":{"properties":{"items":{"items":{"$ref":"#/components/schemas/SessionOut"},"type":"array","title":"Items"},"has_more":{"type":"boolean","title":"Has More","default":false},"next_offset":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Next Offset"}},"type":"object","required":["items"],"title":"SessionPage","description":"One page of conversations, and whether there is another.\n\nThis used to be a bare array, which asserts completeness by omission: a project with\n137 sessions answered with 100 rows and nothing distinguishing that from a project that\nhas exactly 100. A caller had to already know to ask for more (OBE-73).\n\nNo `total`: the count is a second query on every render, and \"is there another page\" is\nthe question a caller actually has. It is answered by fetching one row more than asked\nfor and not returning it."},"SkillOut":{"properties":{"name":{"type":"string","title":"Name"},"description":{"type":"string","title":"Description"},"files":{"items":{"type":"string"},"type":"array","title":"Files","default":[]}},"type":"object","required":["name","description"],"title":"SkillOut"},"SteerRequest":{"properties":{"message":{"type":"string","title":"Message"}},"type":"object","required":["message"],"title":"SteerRequest"},"SubagentOut":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"session_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Session Id"},"ref":{"type":"string","title":"Ref"},"task":{"type":"string","title":"Task"},"model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Model"},"status":{"type":"string","title":"Status"},"progress":{"type":"string","title":"Progress","default":""},"steps":{"type":"integer","title":"Steps","default":0},"question":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Question"},"result":{"type":"string","title":"Result","default":""},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"}},"type":"object","required":["id","ref","task","status"],"title":"SubagentOut","description":"One piece of work the agent handed to another agent.\n\nSmall on purpose. A client shows a line per subagent — what it is doing and how far\nalong — not a transcript: the subagent's working conversation is its own and the\nonly part of it anyone else needs is the report at the end."},"TaskActionIn":{"properties":{"type":{"type":"string","title":"Type","description":"'agent' or 'webhook'.","default":"agent"},"session_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Session Id"},"prompt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Prompt"},"system_prompt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"System Prompt"},"model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Model"},"callback_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Callback Url"},"url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Url"},"method":{"type":"string","title":"Method","default":"POST"},"headers":{"additionalProperties":{"type":"string"},"type":"object","title":"Headers"},"payload":{"type":"object","title":"Payload"}},"type":"object","title":"TaskActionIn"},"TaskCreate":{"properties":{"name":{"type":"string","title":"Name"},"kind":{"type":"string","title":"Kind","description":"'once' or 'recurring'."},"run_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Run At","description":"Required for 'once'."},"cron":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cron","description":"Cron for 'recurring'."},"interval_seconds":{"anyOf":[{"type":"integer","minimum":1.0},{"type":"null"}],"title":"Interval Seconds","description":"Interval for 'recurring'."},"timezone":{"type":"string","title":"Timezone","default":"UTC"},"action":{"$ref":"#/components/schemas/TaskActionIn"}},"type":"object","required":["name","kind"],"title":"TaskCreate"},"TaskOut":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"name":{"type":"string","title":"Name"},"kind":{"type":"string","title":"Kind"},"status":{"type":"string","title":"Status"},"created_by":{"type":"string","title":"Created By"},"run_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Run At"},"cron":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cron"},"interval_seconds":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Interval Seconds"},"timezone":{"type":"string","title":"Timezone"},"action":{"type":"object","title":"Action"},"run_count":{"type":"integer","title":"Run Count"},"last_run_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Run At"},"next_run_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Next Run At"},"last_error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Error"},"last_session_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Last Session Id"},"last_finish_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Finish Reason"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","name","kind","status","created_by","run_at","cron","interval_seconds","timezone","action","run_count","last_run_at","next_run_at","last_error","created_at"],"title":"TaskOut"},"TenantCreate":{"properties":{"slug":{"type":"string","title":"Slug"},"name":{"type":"string","title":"Name"},"settings":{"type":"object","title":"Settings"}},"type":"object","required":["slug","name"],"title":"TenantCreate"},"TenantCreated":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"slug":{"type":"string","title":"Slug"},"name":{"type":"string","title":"Name"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"settings":{"type":"object","title":"Settings"},"api_key":{"type":"string","title":"Api Key"}},"type":"object","required":["id","slug","name","created_at","api_key"],"title":"TenantCreated","description":"Returned ONCE at creation — the only time the API key is exposed."},"TenantDeleted":{"properties":{"id":{"type":"string","title":"Id"},"slug":{"type":"string","title":"Slug"},"rows_deleted":{"additionalProperties":{"type":"integer"},"type":"object","title":"Rows Deleted"},"sandboxes_destroyed":{"type":"integer","title":"Sandboxes Destroyed"},"schedules_cancelled":{"type":"integer","title":"Schedules Cancelled"},"vectors_purged":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Vectors Purged"},"objects_deleted":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Objects Deleted"}},"type":"object","required":["id","slug","rows_deleted","sandboxes_destroyed","schedules_cancelled","vectors_purged","objects_deleted"],"title":"TenantDeleted","description":"What the erasure actually reached.\n\nReported rather than implied, because three of the five steps talk to another service\nand a silent \"deleted\" would be indistinguishable from a purge that only got as far as\nPostgres. ``vectors_purged`` / ``objects_deleted`` of ``None`` mean the store could not\nbe reached — the rows are gone and something still has to be swept by hand."},"TenantOut":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"slug":{"type":"string","title":"Slug"},"name":{"type":"string","title":"Name"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"settings":{"type":"object","title":"Settings"}},"type":"object","required":["id","slug","name","created_at"],"title":"TenantOut","description":"Public tenant view — never includes the API key."},"TenantSettingsUpdate":{"properties":{"settings":{"type":"object","title":"Settings"}},"type":"object","required":["settings"],"title":"TenantSettingsUpdate"},"TodoItem":{"properties":{"id":{"type":"string","title":"Id"},"number":{"type":"integer","title":"Number"},"content":{"type":"string","title":"Content"},"status":{"type":"string","title":"Status"}},"type":"object","required":["id","number","content","status"],"title":"TodoItem","description":"One step on the agent's plan for a chat session."},"TokenRequest":{"properties":{"user_ref":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Ref"},"expires_in":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Expires In"},"capabilities":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Capabilities"},"roles":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Roles"},"groups":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Groups"},"scope":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Scope"},"allowed_models":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Allowed Models"},"max_effort":{"anyOf":[{"type":"string","enum":["minimal","low","medium","high"]},{"type":"null"}],"title":"Max Effort"},"data_scope":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Data Scope"},"max_tool_iterations":{"anyOf":[{"type":"integer","minimum":1.0},{"type":"null"}],"title":"Max Tool Iterations"},"max_context_tokens":{"anyOf":[{"type":"integer","minimum":1.0},{"type":"null"}],"title":"Max Context Tokens"}},"type":"object","title":"TokenRequest"},"TokenResponse":{"properties":{"access_token":{"type":"string","title":"Access Token"},"token_type":{"type":"string","title":"Token Type","default":"bearer"},"expires_in":{"type":"integer","title":"Expires In"},"tenant_id":{"type":"string","title":"Tenant Id"},"subject":{"type":"string","title":"Subject"},"capabilities":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Capabilities"},"scope":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Scope"}},"type":"object","required":["access_token","expires_in","tenant_id","subject"],"title":"TokenResponse"},"TriggerCreate":{"properties":{"name":{"type":"string","title":"Name","default":""},"prompt":{"type":"string","title":"Prompt"},"system_prompt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"System Prompt"},"session_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Session Id"},"signed":{"type":"boolean","title":"Signed","default":false}},"type":"object","required":["prompt"],"title":"TriggerCreate"},"TriggerOut":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"name":{"type":"string","title":"Name"},"prompt":{"type":"string","title":"Prompt"},"enabled":{"type":"boolean","title":"Enabled"},"fired_count":{"type":"integer","title":"Fired Count"},"last_fired_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Fired At"},"last_error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Error"},"url":{"type":"string","title":"Url"},"secret":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Secret"}},"type":"object","required":["id","name","prompt","enabled","fired_count","url"],"title":"TriggerOut"},"TurnOutcomes":{"properties":{"window_hours":{"type":"integer","title":"Window Hours"},"total":{"type":"integer","title":"Total"},"errored":{"type":"integer","title":"Errored"},"consecutive_errors":{"type":"integer","title":"Consecutive Errors"},"last_error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Error"},"last_error_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Error At"},"last_success_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Success At"}},"type":"object","required":["window_hours","total","errored","consecutive_errors"],"title":"TurnOutcomes","description":"How the last turns on this project went.\n\n`chat_runs.status` is the only place a failed STREAMED turn is recorded: the failure\nis a frame inside a `200 OK` body, so every log sweep for `5xx` and `Traceback` comes\nback clean while turns are failing. Nothing read it, and a project on this deployment\nproduced a failing turn every ~6 minutes for an hour and a half with nobody told — 234\nof them over two days, and zero successes (OBE-119)."},"UiRender":{"properties":{"name":{"type":"string","title":"Name"},"args":{"type":"object","title":"Args"}},"type":"object","required":["name"],"title":"UiRender","description":"Something the agent asked the client to draw.\n\nOne-way: the agent called it, the turn carried on, and there is no result. Render\nfrom the whole list in order rather than from accumulated events — a dropped frame\nthen cannot leave the screen wrong."},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"VoiceContextRequest":{"properties":{"facts":{"type":"object","title":"Facts"}},"type":"object","title":"VoiceContextRequest","description":"Facts the frontend should KNOW and not necessarily say.\n\nA separate endpoint from anything that speaks, because the distinction is the whole\npoint: an account tier that shapes tone and a customer id it must never read out both\narrive here, and neither becomes speech."},"VoiceFrontendOut":{"properties":{"name":{"type":"string","title":"Name"},"rate":{"type":"integer","title":"Rate"},"frame_ms":{"type":"number","title":"Frame Ms"},"voices":{"items":{"type":"string"},"type":"array","title":"Voices"},"roles":{"items":{"type":"string"},"type":"array","title":"Roles"},"models":{"items":{"type":"string"},"type":"array","title":"Models"},"default_model":{"type":"string","title":"Default Model","default":""},"voice_languages":{"additionalProperties":{"type":"string"},"type":"object","title":"Voice Languages"},"default_language":{"type":"string","title":"Default Language","default":""},"supports_injection":{"type":"boolean","title":"Supports Injection","default":true},"supports_context":{"type":"boolean","title":"Supports Context","default":false},"max_concurrent":{"type":"integer","title":"Max Concurrent","default":0},"in_use":{"type":"integer","title":"In Use","default":0},"frontends":{"items":{"type":"string"},"type":"array","title":"Frontends"},"conditions_on_reference":{"type":"boolean","title":"Conditions On Reference","default":false},"emits_directives":{"type":"boolean","title":"Emits Directives","default":false},"decides_by_model":{"additionalProperties":{"type":"boolean"},"type":"object","title":"Decides By Model"},"provides_transcripts":{"type":"boolean","title":"Provides Transcripts","default":false}},"type":"object","required":["name","rate","frame_ms"],"title":"VoiceFrontendOut","description":"What the deployment's speech frontend can do.\n\nPublished so a client can offer the voices that exist rather than a hard-coded list —\nasking for one the host does not have fails at call setup, which is a worse place to\nfind out than a dropdown."},"VoiceHoldRequest":{"properties":{"reason":{"type":"string","title":"Reason","default":"the application asked for a hold"},"listen":{"anyOf":[{"type":"string","enum":["full","interrupt_only","dtmf_only","off"]},{"type":"null"}],"title":"Listen"},"max_seconds":{"anyOf":[{"type":"integer","minimum":1.0},{"type":"null"}],"title":"Max Seconds"}},"type":"object","title":"VoiceHoldRequest"},"VoiceResumeRequest":{"properties":{"lead":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lead"},"transition":{"type":"string","enum":["natural","interrupt_music"],"title":"Transition","default":"natural"}},"type":"object","title":"VoiceResumeRequest"},"VoiceSessionOut":{"properties":{"id":{"type":"string","title":"Id"},"session_id":{"type":"string","format":"uuid","title":"Session Id"},"stream_url":{"type":"string","title":"Stream Url"},"frontend":{"type":"string","title":"Frontend"},"voice":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Voice"},"role":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Role"},"voice_model":{"type":"string","title":"Voice Model","default":""},"rate":{"type":"integer","title":"Rate"},"frame_ms":{"type":"number","title":"Frame Ms"},"narrowband":{"type":"boolean","title":"Narrowband","default":false},"can_transfer":{"type":"boolean","title":"Can Transfer","default":false},"language":{"type":"string","title":"Language","default":""},"phrases_missing":{"items":{"type":"string"},"type":"array","title":"Phrases Missing"}},"type":"object","required":["id","session_id","stream_url","frontend","rate","frame_ms"],"title":"VoiceSessionOut"},"VoiceSessionRequest":{"properties":{"voice":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Voice"},"role":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Role"},"system":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"System"},"model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Model"},"voice_model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Voice Model"},"frontend":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Frontend"},"allowed_tools":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Allowed Tools"},"fidelity":{"type":"string","enum":["strict","natural","free"],"title":"Fidelity","default":"natural"},"waiting":{"$ref":"#/components/schemas/VoiceWaitingOptions"},"session_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Session Id"},"max_seconds":{"anyOf":[{"type":"integer","minimum":1.0},{"type":"null"}],"title":"Max Seconds"}},"type":"object","title":"VoiceSessionRequest","description":"Open a call."},"VoiceSpeechRequest":{"properties":{"text":{"type":"string","maxLength":2000,"minLength":1,"title":"Text"},"interrupt":{"type":"boolean","title":"Interrupt","default":true}},"type":"object","required":["text"],"title":"VoiceSpeechRequest","description":"A line the application wants said, in the frontend's voice."},"VoiceTransferRequest":{"properties":{"to":{"type":"string","title":"To"},"context":{"type":"string","title":"Context","default":""}},"type":"object","required":["to"],"title":"VoiceTransferRequest"},"VoiceWaitingOptions":{"properties":{"strategy":{"type":"string","enum":["auto","bridge","wait","hold"],"title":"Strategy","default":"auto"},"hold_music":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Hold Music"},"barge_in":{"type":"boolean","title":"Barge In","default":true},"listen_on_hold":{"type":"string","enum":["full","interrupt_only","dtmf_only","off"],"title":"Listen On Hold","default":"interrupt_only"},"quiet_while_waiting":{"type":"boolean","title":"Quiet While Waiting","default":false},"patient_bargein":{"type":"boolean","title":"Patient Bargein","default":false},"keep_answer_through_bargein":{"type":"boolean","title":"Keep Answer Through Bargein","default":false},"guard_asr_echo":{"type":"boolean","title":"Guard Asr Echo","default":false},"onset_echo_only":{"type":"boolean","title":"Onset Echo Only","default":true},"echo_ratio":{"anyOf":[{"type":"number","maximum":1.0,"minimum":0.0},{"type":"null"}],"title":"Echo Ratio"},"adaptive_echo":{"type":"boolean","title":"Adaptive Echo","default":false},"quiet_unless_answering":{"type":"boolean","title":"Quiet Unless Answering","default":false}},"type":"object","title":"VoiceWaitingOptions","description":"How this call should behave while it waits.\n\nA nested object rather than four top-level fields because they are one decision: an\nintegrator tuning \"how does it feel when this is slow\" changes them together, and a\nflat request makes them look independent."},"WebhookSecret":{"properties":{"secret":{"type":"string","title":"Secret"}},"type":"object","required":["secret"],"title":"WebhookSecret"}}}}