{"openapi":"3.1.0","info":{"title":"Ocean One API","version":"2.1.0","description":"Single front door for the Ocean platform — discovery, tools, agents, workflows, MCP, and model inference. Every response echoes a server-generated x-request-id; pass x-trace-id to correlate across planes. 2.1.0 (Phase 2): the money plane gains ordered model fallback (models[]), sort (price/latency/throughput), retry + 30s outage exclusion with honest billing of the model that actually served, @preset/<slug> addressable configs, per-org/per-key guardrails (spend caps, allow-lists, content filtering, BYOK gates), an opt-in exact-match response cache (x-cache header), and an atomic per-key rate limiter."},"servers":[{"url":"https://api.plungeai.com"}],"components":{"securitySchemes":{"ozkBearer":{"type":"http","scheme":"bearer","description":"ozk_ platform API key (Authorization: Bearer ozk_…)"},"skOcean":{"type":"http","scheme":"bearer","description":"sk-ocean- inference key (money plane, forwarded downstream)"}},"schemas":{"Error":{"type":"object","description":"Standard error envelope. Every error response also carries an `X-Error-Code` response header equal to error.code, so a client branches on the header regardless of the negotiated body format (json | yaml | markdown | text). When the request created an execution, the `X-Execution-Id` response header is also set. Errors follow the negotiated format like success bodies.","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"Card":{"type":"object","description":"Registry capability card (summary fields).","properties":{"id":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"},"category":{"type":"string"},"status":{"type":"string"},"description":{"type":"string"},"tags":{"type":"array","items":{"type":"string"}},"quality":{"description":"Present only when the search was called with include=quality; null when unmeasured (no eval-service binding on this tier, no runs yet, or an upstream miss).","type":["object","null"],"properties":{"score":{"type":["number","null"]},"success_rate":{"type":["number","null"]},"runs":{"type":"integer"}}}},"required":["id","name","type","category","status"],"additionalProperties":true},"ToolContract":{"type":"object","description":"Exact invocation contract for a tool-agent.","properties":{"agent_id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"operations":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"purpose":{"type":"string"},"gated":{"type":"boolean"},"required_params":{"type":"array","items":{"type":"string"}}},"required":["name","gated"]}},"inputSchema":{"type":"object"},"examples":{"type":"array","items":{"type":"object","properties":{"title":{"type":"string"},"cnl":{"type":"string"}},"required":["title","cnl"]}},"output_type":{"type":"string"}},"required":["agent_id","name","description","operations","inputSchema","examples"],"additionalProperties":true},"StoredResult":{"type":"object","properties":{"content":{"type":"string"},"content_type":{"type":"string"},"workflow_id":{"type":"string"},"task_id":{"type":"string"}},"required":["content"]},"McpProtocolTool":{"type":"object","description":"Standard MCP tool descriptor (JSON-RPC tools/list result item).","properties":{"name":{"type":"string"},"description":{"type":"string"},"inputSchema":{"type":"object","description":"JSON Schema for the tool arguments"}},"required":["name","inputSchema"],"additionalProperties":true},"McpRunTool":{"type":"object","description":"Namespaced tool descriptor for an outbound MCP run (mcp-executor).","properties":{"name":{"type":"string","description":"Namespaced as mcp__<server>__<tool>"},"description":{"type":"string"},"input_schema":{"type":"object","description":"JSON Schema for the tool arguments"}},"required":["name","description","input_schema"]},"Span":{"type":"object","description":"One row of execution_trace_spans.","properties":{"id":{"type":"integer"},"trace_id":{"type":"string"},"workflow_id":{"type":"string"},"task_id":{"type":["string","null"]},"ts":{"type":"integer"},"type":{"type":"string","description":"request_received|task_dispatched|task_completed|workflow_result|…"},"agent":{"type":["string","null"]},"status":{"type":["string","null"]},"duration_ms":{"type":["integer","null"]},"payload_ref":{"type":["string","null"],"description":"R2 key when large, else null"},"payload_inline":{"type":["string","null"],"description":"guard-scanned, <=1KB"}},"required":["id","trace_id","workflow_id","ts","type"]},"GatewayRequest":{"type":"object","description":"One row of api_gateway_requests — this router’s own request log.","properties":{"id":{"type":"string"},"trace_id":{"type":["string","null"]},"plane":{"type":"string"},"route":{"type":"string"},"user_id":{"type":["string","null"]},"status":{"type":"integer"},"upstream":{"type":["string","null"]},"duration_ms":{"type":["integer","null"]},"cost_usd":{"type":["number","null"]},"created_at":{"type":"integer"}},"required":["id","plane","route","status","created_at"]},"ChatMessage":{"type":"object","properties":{"role":{"type":"string","enum":["system","user","assistant","tool"]},"content":{"type":"string"}},"required":["role","content"]},"ChatCompletionRequest":{"type":"object","description":"Money plane, sk-ocean- auth. Transparent proxy to inference-gateway — any OpenAI-compatible field is passed through untouched; the fields below are the ones Phase 2 routing adds on top.","properties":{"model":{"type":"string","description":"A single model slug (\"provider/model\", e.g. \"anthropic/claude-sonnet-5\"), or \"@preset/<slug>\" to expand a stored model+routing+params bundle (request-explicit fields below still override the preset). Ignored if models[] is set."},"models":{"type":"array","items":{"type":"string"},"description":"Ordered fallback candidates — alternative to model. One retry per candidate on 429/5xx/network, then failover to the next; a candidate whose provider just failed out is excluded for 30s."},"sort":{"type":"string","enum":["price","latency","throughput"],"description":"Reorders models[] before the first attempt. latency/throughput sort by rolling provider stats; a provider with no history yet sorts last."},"messages":{"type":"array","items":{"$ref":"#/components/schemas/ChatMessage"}},"stream":{"type":"boolean","default":false},"temperature":{"type":"number","description":"Set to exactly 0 to make the request response-cache eligible."},"max_tokens":{"type":"integer"},"top_p":{"type":"number"}},"required":["messages"],"additionalProperties":true},"ChatCompletionResponse":{"type":"object","description":"model is the slug that ACTUALLY served the request (honest billing) — it may differ from the requested model/first models[] entry after a failover.","properties":{"id":{"type":"string"},"object":{"type":"string"},"model":{"type":"string","description":"The model that served this response — bill and log both key on this value."},"choices":{"type":"array","items":{"type":"object"}},"usage":{"type":"object","properties":{"prompt_tokens":{"type":"integer"},"completion_tokens":{"type":"integer"},"total_tokens":{"type":"integer"}}}},"required":["id","object","model","choices"]},"EmbeddingsRequest":{"type":"object","description":"Money plane, sk-ocean- auth. Same guardrail/cache enforcement as chat completions.","properties":{"model":{"type":"string"},"input":{"description":"A string, or an array of strings"}},"required":["model","input"],"additionalProperties":true},"EmbeddingsResponse":{"type":"object","properties":{"object":{"type":"string"},"data":{"type":"array","items":{"type":"object"}},"model":{"type":"string"},"usage":{"type":"object"}},"required":["object","data","model"]},"ModelCatalog":{"type":"object","properties":{"object":{"type":"string"},"data":{"type":"array","items":{"type":"object","description":"Priced model catalog entry (id, pricing, provider)"}}},"required":["object","data"]}}},"paths":{"/health":{"get":{"summary":"Liveness probe","security":[],"responses":{"200":{"description":"Router is up"}}}},"/v1/openapi.json":{"get":{"summary":"This document","security":[],"responses":{"200":{"description":"OpenAPI spec"}}}},"/v1/discovery/search":{"get":{"summary":"Search the capability registry (hybrid semantic + keyword)","security":[{"ozkBearer":[]}],"parameters":[{"name":"q","in":"query","schema":{"type":"string"},"description":"Natural-language capability query"},{"name":"kind","in":"query","schema":{"type":"string","enum":["agents","skills","digital-twins","personas","experts","backgrounds","workflows","models","providers","connectors","plugins","mcp-servers"]},"description":"Plural capability group, e.g. agents, mcp-servers"},{"name":"type","in":"query","schema":{"type":"string"}},{"name":"category","in":"query","schema":{"type":"string"}},{"name":"status","in":"query","schema":{"type":"string","default":"active"}},{"name":"tier","in":"query","schema":{"type":"string"}},{"name":"limit","in":"query","schema":{"type":"integer"}},{"name":"offset","in":"query","schema":{"type":"integer"}},{"name":"mode","in":"query","schema":{"type":"string","enum":["hybrid","keyword","vector"]}},{"name":"fields","in":"query","schema":{"type":"string","enum":["list","summary","full"]}}],"responses":{"200":{"description":"Registry search envelope","content":{"application/json":{"schema":{"type":"object","properties":{"cards":{"type":"array","items":{"$ref":"#/components/schemas/Card"}},"count":{"type":"integer"},"searchMethod":{"type":"string"}}}}}},"401":{"description":"Missing/invalid ozk_ key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/discovery/recommend":{"post":{"summary":"Recommend the best capability card for a task","security":[{"ozkBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"task":{"type":"string"}},"required":["type","task"]}}}},"responses":{"200":{"description":"Recommendation","content":{"application/json":{"schema":{"type":"object","properties":{"recommended":{"type":"string"},"card":{"$ref":"#/components/schemas/Card"},"score":{"type":"number"}}}}}},"400":{"description":"invalid_json / invalid_request — malformed or rejected body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — Retry-After header","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/discovery/resolve":{"post":{"summary":"Resolve a task to one tool, its operation and an example call, with a calibrated confidence","security":[{"ozkBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"task":{"type":"string","description":"What you want done, in plain language"},"kinds":{"type":"array","items":{"type":"string"},"maxItems":8,"description":"Card types to consider (agent, workflow, connector, mcp_server, skill, plugin, …); plural kinds are accepted aliases. Default: every discoverable kind"},"category":{"type":"string"},"status":{"type":"string","default":"active"}},"required":["task"]}}}},"responses":{"200":{"description":"Resolve decision","content":{"application/json":{"schema":{"type":"object","properties":{"outcome":{"type":"string","enum":["match","uncertain","none"]},"tool":{"type":"object","properties":{"id":{"type":"string"},"kind":{"type":"string"},"type":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"category":{"type":"string"},"status":{"type":"string"}}},"operation":{"type":"object","properties":{"name":{"type":"string"},"purpose":{"type":"string"},"gated":{"type":"boolean"}}},"call":{"type":"object","properties":{"required_params":{"type":"array","items":{"type":"string"}},"example_cnl":{"type":"string"}}},"confidence":{"type":["number","null"],"description":"null on the keyword fallback (decision model unavailable)"},"alternatives":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"p":{"type":"number"}}}},"mode":{"type":"string","enum":["shadow","act"]}}}}}},"400":{"description":"invalid_json — body missing or no task","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — Retry-After header","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/discovery/cards/{type}/{id}":{"get":{"summary":"Fetch a capability card (markdown LLM view)","security":[{"ozkBearer":[]}],"parameters":[{"name":"type","in":"path","required":true,"schema":{"type":"string","enum":["agent","skill","digital_twin","expert","background","workflow","model","provider","connector","plugin","mcp_server"]},"description":"Singular card type; plural search kinds (agents, mcp-servers, …) are accepted aliases"},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Card markdown","content":{"text/markdown":{"schema":{"type":"string"}}}},"400":{"description":"invalid_request — a bad type/id is normalised to the One-API error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not_found — no such card","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools":{"get":{"summary":"List active tool-agents","security":[{"ozkBearer":[]}],"parameters":[{"name":"limit","in":"query","schema":{"type":"integer","default":50,"maximum":100}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}}],"responses":{"200":{"description":"Active tool list","content":{"application/json":{"schema":{"type":"object","properties":{"tools":{"type":"array","items":{"$ref":"#/components/schemas/Card"}},"count":{"type":"integer"}}}}}}}}},"/v1/tools/{id}":{"get":{"summary":"Get a tool contract (JSON Schema params, operations, gates, examples)","security":[{"ozkBearer":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The contract","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolContract"}}}},"404":{"description":"unknown_tool","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tools/{id}/execute":{"post":{"summary":"Execute a tool operation (fenced: gated/money verbs refuse unattended)","security":[{"ozkBearer":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"operation":{"type":"string","description":"Operation name from the contract"},"params":{"type":"object","description":"Operation params per the contract inputSchema"},"prompt":{"type":"string","description":"Free-text prompt for prompt-driven agents"},"format":{"type":"string","enum":["json","yaml","markdown","text"],"description":"Response format override (precedence: this field → Accept header → mirror of the request Content-Type). Default json. yaml = the envelope with Markdown as block scalars; markdown = the same result the MCP plane renders; text = the bare result content. An unknown value → 400 invalid_format."}}}}}},"responses":{"200":{"description":"Execution result Response format negotiates via the `format` field, an Accept header (application/json, text/yaml, text/markdown, text/plain), or the request Content-Type mirror; default JSON.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"content":{"type":"string"},"outcome":{"type":"string"},"request_id":{"type":"string"}},"required":["ok","content"]}},"text/yaml":{"schema":{"type":"string"}},"text/markdown":{"schema":{"type":"string"}},"text/plain":{"schema":{"type":"string"}}}},"400":{"description":"invalid_format — format must be one of json, yaml, markdown, text","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"refused — fence/gated operation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"unknown_tool","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"approval_required — needs a human approval surface; duplicate_execution_id — x-trace-id already used by an earlier run","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"payload_too_large — body over 1 MiB (MAX_REQUEST_SIZE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"invalid_params — needs_input; body carries missing/reserved + the contract","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"424":{"description":"connection_required / credential_required — agent needs a connection or key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — Retry-After header","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"execution_failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"agent_unavailable — agent temporarily down","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/agents":{"get":{"summary":"List active agents","security":[{"ozkBearer":[]}],"parameters":[{"name":"limit","in":"query","schema":{"type":"integer","default":50,"maximum":100}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}}],"responses":{"200":{"description":"Active agent list","content":{"application/json":{"schema":{"type":"object","properties":{"agents":{"type":"array","items":{"$ref":"#/components/schemas/Card"}},"count":{"type":"integer"}}}}}}}}},"/v1/agents/categories":{"get":{"summary":"Agent categories with active-agent counts (aggregated from the registry)","security":[{"ozkBearer":[]}],"responses":{"200":{"description":"Categories envelope","content":{"application/json":{"schema":{"type":"object","properties":{"categories":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"count":{"type":"integer"}}}},"count":{"type":"integer"}}}}}}}}},"/v1/agents/{id}/execute":{"post":{"summary":"Execute an agent with a prompt (sync by default; sync:false returns a pointer)","security":[{"ozkBearer":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"prompt":{"type":"string"},"input":{"type":"string","description":"Alias for prompt"},"persona":{"type":"string"},"provider":{"type":"string","description":"Provider id (anthropic, openai, gemini, …); required alongside a pinned model"},"model":{"type":"string"},"maxTokens":{"type":"integer","description":"Max output tokens (alias: max_tokens)"},"max_tokens":{"type":"integer","description":"Alias for maxTokens"},"temperature":{"type":"number","description":"Sampling temperature, forwarded to the provider"},"top_p":{"type":"number","description":"Nucleus sampling probability, forwarded to the provider"},"reasoning_effort":{"type":"string","description":"Reasoning-effort hint (e.g. low/medium/high) for reasoning models"},"thinking_level":{"type":"string","description":"Extended-thinking level hint for models that support it"},"system":{"type":"string","description":"System prompt / instructions for the run"},"messages":{"type":"array","description":"Prior chat messages ([{role, content}]) instead of a single prompt","items":{"type":"object"}},"sync":{"type":"boolean","default":true},"stream":{"type":"boolean","default":false,"description":"When true, the response is an OpenAI-shaped chat.completion.chunk SSE (see the 200 text/event-stream variant) instead of a JSON result. Ignored by the async pointer path."},"format":{"type":"string","enum":["json","yaml","markdown","text"],"description":"Response format override (precedence: this field → Accept header → mirror of the request Content-Type). Default json. yaml = the envelope with Markdown as block scalars; markdown = the same result the MCP plane renders; text = the bare result content. An unknown value → 400 invalid_format."}}}}}},"responses":{"200":{"description":"Resolved result. Default (stream absent/false): a JSON result object. With stream:true: an OpenAI-shaped chat.completion.chunk SSE — one primer chunk carrying delta.role=\"assistant\", then a delta.content chunk per provider token, then a final chunk with delta:{} and finish_reason \"stop\" (or \"length\" when the model was truncated at max_tokens), then a literal `data: [DONE]` line. usage is emitted on the final chunk only when the provider reports the prompt/completion split (often omitted for streamed runs). Comment keepalives (`: OCEAN PROCESSING`) may appear every ~15s while idle. Errors before the first byte are the normal JSON error envelopes below (not SSE); an error after the first byte is a single `data: {\"error\":{…}}` frame and the stream closes WITHOUT `[DONE]`. Response header X-Execution-Id carries the execution id for result redemption / polling. Response format negotiates via the `format` field, an Accept header (application/json, text/yaml, text/markdown, text/plain), or the request Content-Type mirror; default JSON.","content":{"application/json":{"schema":{"type":"object","properties":{"content":{"type":"string"},"workflow_id":{"type":"string"},"task_id":{"type":"string"},"request_id":{"type":"string"}},"required":["content"]}},"text/yaml":{"schema":{"type":"string"}},"text/markdown":{"schema":{"type":"string"}},"text/plain":{"schema":{"type":"string"}},"text/event-stream":{"schema":{"type":"string"},"example":"data: {\"id\":\"chatcmpl-e2222ee13ea2499a95105245\",\"object\":\"chat.completion.chunk\",\"created\":1788574344,\"model\":\"llm-agent\",\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\"},\"finish_reason\":null}]}\n\ndata: {\"id\":\"chatcmpl-e2222ee13ea2499a95105245\",\"object\":\"chat.completion.chunk\",\"created\":1788574344,\"model\":\"llm-agent\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"391\"},\"finish_reason\":null}]}\n\ndata: {\"id\":\"chatcmpl-e2222ee13ea2499a95105245\",\"object\":\"chat.completion.chunk\",\"created\":1788574344,\"model\":\"llm-agent\",\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}]}\n\ndata: [DONE]\n\n"}}},"202":{"description":"Accepted (async) — redeem via /v1/agents/results/{workflowId}/{taskId}","content":{"application/json":{"schema":{"type":"object","properties":{"workflow_id":{"type":"string"},"task_id":{"type":"string"},"request_id":{"type":"string"}}}}}},"400":{"description":"missing_prompt / invalid_format — format must be one of json, yaml, markdown, text","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"agent_not_active — the agent card is not status:active (refused pre-dispatch)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"unknown_agent — no such agent id in the registry (refused pre-dispatch)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"duplicate_execution_id — x-trace-id already used by an earlier run — send a fresh UUID","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"payload_too_large — body over 1 MiB (MAX_REQUEST_SIZE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"invalid_params — needs_input (the agent named a missing/invalid input); unknown_model (pinned model absent/inactive in the catalog); empty_completion (the run completed but the model returned no visible content — raise max_tokens ≥ 64 or change the model)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"424":{"description":"connection_required / credential_required — agent needs a connection or key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — Retry-After header","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"engine_error / result_unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"agent_unavailable — agent temporarily down","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/agents/results/{workflowId}/{taskId}":{"get":{"summary":"Redeem an async agent result","security":[{"ozkBearer":[]}],"parameters":[{"name":"workflowId","in":"path","required":true,"schema":{"type":"string"}},{"name":"taskId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Stored result Response format negotiates via the `format` field, an Accept header (application/json, text/yaml, text/markdown, text/plain), or the request Content-Type mirror; default JSON.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StoredResult"}},"text/yaml":{"schema":{"type":"string"}},"text/markdown":{"schema":{"type":"string"}},"text/plain":{"schema":{"type":"string"}}}},"400":{"description":"invalid_format — format must be one of json, yaml, markdown, text","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not_ready","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/workflows/execute":{"post":{"summary":"Execute an inline workflow (JSON {workflow, input} or raw YAML body)","security":[{"ozkBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"workflow":{"description":"CNL workflow object, or a YAML string"},"input":{"type":"string"},"inputs":{"type":"object"},"format":{"type":"string","enum":["json","yaml","markdown","text"],"description":"Response format override (precedence: this field → Accept header → mirror of the request Content-Type). Default json. yaml = the envelope with Markdown as block scalars; markdown = the same result the MCP plane renders; text = the bare result content. An unknown value → 400 invalid_format."}},"required":["workflow"]}},"text/yaml":{"schema":{"type":"string"}}}},"responses":{"200":{"description":"Engine acknowledgement Response format negotiates via the `format` field, an Accept header (application/json, text/yaml, text/markdown, text/plain), or the request Content-Type mirror; default JSON.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"workflow_id":{"type":"string"},"final_task_id":{"type":"string"},"request_id":{"type":"string"}}}},"text/yaml":{"schema":{"type":"string"}},"text/markdown":{"schema":{"type":"string"}},"text/plain":{"schema":{"type":"string"}}}},"400":{"description":"missing_workflow / invalid_format — format must be one of json, yaml, markdown, text","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"agent_not_active — a named agent card is not status:active (refused pre-dispatch)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"unknown_agent — a named agent id does not exist in the registry (refused pre-dispatch)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"duplicate_execution_id — x-trace-id already used by an earlier run — send a fresh UUID","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"payload_too_large — body over 1 MiB (MAX_REQUEST_SIZE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — Retry-After header","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"engine_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/workflows/execute-stream":{"post":{"summary":"Execute an inline workflow (YAML or JSON) with SSE event streaming","security":[{"ozkBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"workflow":{"description":"CNL workflow object, or a YAML string"},"input":{"type":"string"},"inputs":{"type":"object"}},"required":["workflow"]}},"text/yaml":{"schema":{"type":"string"}}}},"responses":{"200":{"description":"SSE stream: request_received, workflow_loaded, workflow_started, task_dispatched, streaming_started (streaming agents), token (one frame per provider delta: {\"task_id\",\"delta\"}), heartbeat, task_completed, workflow_completed (carries execution_summary), workflow_result. Single connection: the gateway drains the provider stream itself; terminal events always arrive on this SSE.","content":{"text/event-stream":{"schema":{"type":"string"}}}},"400":{"description":"missing_workflow","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"agent_not_active — a named agent card is not status:active (refused pre-dispatch)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"unknown_agent — a named agent id does not exist in the registry (refused pre-dispatch)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"payload_too_large — body over 1 MiB (MAX_REQUEST_SIZE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — Retry-After header","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/workflows/{id}/execute":{"post":{"summary":"Execute a saved workflow (loaded from the engine KV by id + your user)","security":[{"ozkBearer":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"input":{"type":"string"},"inputs":{"type":"object"},"format":{"type":"string","enum":["json","yaml","markdown","text"],"description":"Response format override (precedence: this field → Accept header → mirror of the request Content-Type). Default json. yaml = the envelope with Markdown as block scalars; markdown = the same result the MCP plane renders; text = the bare result content. An unknown value → 400 invalid_format."}}}}}},"responses":{"200":{"description":"Engine acknowledgement Response format negotiates via the `format` field, an Accept header (application/json, text/yaml, text/markdown, text/plain), or the request Content-Type mirror; default JSON.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"workflow_id":{"type":"string"},"final_task_id":{"type":"string"},"request_id":{"type":"string"}}}},"text/yaml":{"schema":{"type":"string"}},"text/markdown":{"schema":{"type":"string"}},"text/plain":{"schema":{"type":"string"}}}},"400":{"description":"invalid_format — format must be one of json, yaml, markdown, text","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"workflow_not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"duplicate_execution_id — x-trace-id already used by an earlier run — send a fresh UUID","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"payload_too_large — body over 1 MiB (MAX_REQUEST_SIZE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — Retry-After header","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"engine_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/workflows/{id}/execute-stream":{"post":{"summary":"Execute a saved workflow with SSE event streaming","security":[{"ozkBearer":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"input":{"type":"string"},"inputs":{"type":"object"}}}}}},"responses":{"200":{"description":"SSE stream: request_received, workflow_loaded, workflow_started, task_dispatched, streaming_started (streaming agents), token (one frame per provider delta: {\"task_id\",\"delta\"}), heartbeat, task_completed, workflow_completed (carries execution_summary), workflow_result. Single connection: the gateway drains the provider stream itself; terminal events always arrive on this SSE.","content":{"text/event-stream":{"schema":{"type":"string"}}}},"413":{"description":"payload_too_large — body over 1 MiB (MAX_REQUEST_SIZE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — Retry-After header","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/workflows/results/{workflowId}/{taskId}":{"get":{"summary":"Redeem a workflow task result from SharedMemory","security":[{"ozkBearer":[]}],"parameters":[{"name":"workflowId","in":"path","required":true,"schema":{"type":"string"}},{"name":"taskId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Stored result Response format negotiates via the `format` field, an Accept header (application/json, text/yaml, text/markdown, text/plain), or the request Content-Type mirror; default JSON.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StoredResult"}},"text/yaml":{"schema":{"type":"string"}},"text/markdown":{"schema":{"type":"string"}},"text/plain":{"schema":{"type":"string"}}}},"400":{"description":"invalid_format — format must be one of json, yaml, markdown, text","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not_ready","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/workflows/executions/{id}/cancel":{"post":{"summary":"Cancel a running workflow execution (cooperative)","description":"Writes the SharedMemory cancel marker the engine and agent loops poll at their next turn/tool boundary, and stamps the row cancelled. Wrong owner → 404 (no existence leak); not running → 409. Since /v1/workflows/execute is synchronous, pass your own x-trace-id on the execute call and use it as {id} here.","security":[{"ozkBearer":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Cancelled","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"cancelled":{"type":"string","description":"The execution id"},"markers":{"type":"array","items":{"type":"string"},"description":"Run ids the cancel marker was written under (row id + engine cln id)"}}}}}},"404":{"description":"not_found — no such execution for this key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"not_running — the execution already finished or was cancelled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/mcp/tools":{"get":{"summary":"List the platform-as-MCP-server tools (JSON-RPC tools/list, signed pass-through)","security":[{"ozkBearer":[]}],"responses":{"200":{"description":"JSON-RPC tools/list result","content":{"application/json":{"schema":{"type":"object","properties":{"jsonrpc":{"type":"string"},"id":{"type":"integer"},"result":{"type":"object","properties":{"tools":{"type":"array","items":{"$ref":"#/components/schemas/McpProtocolTool"}}}}}}}}}}}},"/v1/mcp":{"post":{"summary":"Inbound MCP Streamable-HTTP pass-through — point any MCP client here with an ozk_ key","security":[{"ozkBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","description":"JSON-RPC 2.0 message"}}}},"responses":{"200":{"description":"JSON-RPC response (JSON, or SSE for streamed tool calls)","content":{"application/json":{"schema":{"type":"object","description":"JSON-RPC 2.0 response"}},"text/event-stream":{"schema":{"type":"string"}}}},"429":{"description":"rate_limited — Retry-After header","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/mcp/runs":{"post":{"summary":"Open an outbound MCP run: connect catalog servers, get their tool table","security":[{"ozkBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"server_ids":{"type":"array","items":{"type":"string"},"description":"Registry mcp-server card ids"}},"required":["server_ids"]}}}},"responses":{"201":{"description":"Run opened","content":{"application/json":{"schema":{"type":"object","properties":{"run_id":{"type":"string"},"tools":{"type":"array","items":{"$ref":"#/components/schemas/McpRunTool"}},"connected":{"type":"array","items":{"type":"string"}},"failed":{"type":"array","items":{"type":"object"}},"warnings":{"type":"array","items":{"type":"string"}}}}}}},"400":{"description":"invalid_body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — Retry-After header","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"no_servers_connected (body carries per-server failures)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/mcp/runs/{id}/tools":{"get":{"summary":"List an MCP run's namespaced tools","security":[{"ozkBearer":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Tool table","content":{"application/json":{"schema":{"type":"object","properties":{"tools":{"type":"array","items":{"$ref":"#/components/schemas/McpRunTool"}},"count":{"type":"integer"}}}}}}}}},"/v1/mcp/runs/{id}/call":{"post":{"summary":"Call one namespaced tool in an MCP run","security":[{"ozkBearer":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"Namespaced tool name (mcp__<server>__<tool>)"},"args":{"type":"object"},"timeout_ms":{"type":"integer"}},"required":["name"]}}}},"responses":{"200":{"description":"Tool result","content":{"application/json":{"schema":{"type":"object","properties":{"content":{"type":"string"}}}}}},"400":{"description":"invalid_body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — Retry-After header","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"tool_call_failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/mcp/runs/{id}":{"delete":{"summary":"Close an MCP run (drop the run's Durable Object state; idempotent)","security":[{"ozkBearer":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Cleared","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"}}}}}}}}},"/v1/traces/{id}":{"get":{"summary":"Persisted execution trace — spans + gateway request log for one trace id","security":[{"ozkBearer":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Trace","content":{"application/json":{"schema":{"type":"object","properties":{"trace_id":{"type":"string"},"spans":{"type":"array","items":{"$ref":"#/components/schemas/Span"}},"gateway_requests":{"type":"array","items":{"$ref":"#/components/schemas/GatewayRequest"}}}}}}}}}},"/v1/chat/completions":{"post":{"summary":"Chat completion (proxied to inference-gateway). Phase 2: models[]/sort ordered fallback with retry + 30s outage exclusion, @preset/<slug>, guardrails, opt-in response cache.","security":[{"skOcean":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatCompletionRequest"}}}},"responses":{"200":{"description":"Completion (model = the slug that actually served it, not necessarily the one requested). stream:true returns text/event-stream instead — see the developer guide for the streaming caveat.","headers":{"x-cache":{"description":"\"miss\" or \"hit\" — present only when the org has response caching enabled and the request was cache-eligible (temperature:0, stream not true); absent otherwise.","schema":{"type":"string","enum":["miss","hit"]}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatCompletionResponse"}},"text/event-stream":{"schema":{"type":"string"}}}},"401":{"description":"Missing/invalid sk-ocean- key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"byok_required — this provider needs your own connected key on this plan","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"model_not_allowed (routing candidates excluded by an allow-list) or content_blocked (prompt matched a guardrail regex)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"preset_not_found — @preset/<slug> does not exist or is inactive","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limit_exceeded (per-key/per-provider) or spend_cap_exceeded (guardrail cap reached)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"money_plane_unavailable — INFERENCE_GATEWAY_SERVICE not bound on this tier","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/embeddings":{"post":{"summary":"Embeddings (proxied to inference-gateway). Same guardrail enforcement as chat completions.","security":[{"skOcean":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmbeddingsRequest"}}}},"responses":{"200":{"description":"Embeddings result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmbeddingsResponse"}}}},"401":{"description":"Missing/invalid sk-ocean- key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"byok_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"model_not_allowed or content_blocked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limit_exceeded or spend_cap_exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"money_plane_unavailable — INFERENCE_GATEWAY_SERVICE not bound on this tier","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/models":{"get":{"summary":"Model catalog (proxied to inference-gateway) — the priced list routing candidates are drawn from.","security":[{"skOcean":[]}],"responses":{"200":{"description":"Priced model catalog","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ModelCatalog"}}}},"401":{"description":"Missing/invalid sk-ocean- key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"money_plane_unavailable — INFERENCE_GATEWAY_SERVICE not bound on this tier","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}