For AI agents: a documentation index is available at https://docs.plungeai.com/llms.txt. Append .md to any page URL, or send Accept: text/markdown, to get markdown. Setup instructions for agents are at https://docs.plungeai.com/agents.md. Execution planes take an ozk_ key; the models plane takes an sk-ocean- key.

Documentation Index: fetch the complete documentation index at /llms.txt. Use this file to discover all available pages before exploring further.

Run multi-agent CNL workflows: inline (send the workflow document in the request), saved (reference a workflow id saved in Ocean Studio), each with an optional SSE streaming variant, plus a results-redemption route.

Auth: Authorization: Bearer ozk_YOUR_KEY on every route here. Tenancy is automatic — the engine keys every run to your key's identity; saved workflows and results resolve only within it.

Authoring CNL YAML itself (task types, parallel/sequential, harness missions) is this plungeai-workflows skill's job; this file covers the HTTP surface for executing it.

POST /v1/workflows/execute — inline execution

Two body formats:

JSON — {"workflow": <object or YAML string>, "input"?: string, "inputs"?: object}:

curl -s -X POST https://api.plungeai.com/v1/workflows/execute \
  -H "Authorization: Bearer ozk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "workflow": {
      "name": "demo",
      "tasks": [
        {"type": "task", "id": "t1", "agent": "llm-agent", "prompt": "Say: ok"}
      ]
    },
    "input": "x"
  }'

Raw YAML — send the whole workflow document as the body with Content-Type: text/yaml:

curl -s -X POST https://api.plungeai.com/v1/workflows/execute \
  -H "Authorization: Bearer ozk_YOUR_KEY" \
  -H "Content-Type: text/yaml" \
  --data-binary @- <<'YAML'
workflow:
  name: demo
  tasks:
    - type: task
      id: t1
      agent: llm-agent
      prompt: "Say: ok"
YAML

Response — HTTP 200 (an acknowledgement + pointer, not the content):

{
  "success": true,
  "workflow_id": "00000000-0000-4000-8000-000000000001",
  "final_task_id": "t1",
  "request_id": "00000000-0000-4000-8000-000000000004"
}

Redeem the actual output with workflow_id + final_task_id (below). For a multi-task workflow, final_task_id is the last task — intermediate task results are redeemable by their own task ids.

Errors: 400 missing_workflow (no workflow in a JSON body / empty YAML), 502 engine_error (engine reported failure; message included), 404 workflow_not_found — yes, on the inline route too: any engine failure whose message contains "not found" (typically an unknown agent id → "Service binding not found") maps to 404. Re-discover the agent id; don't hunt for a missing saved workflow.

POST /v1/workflows/{id}/execute — saved workflow

Runs a workflow saved under your account (the id shown in Ocean Studio). Body is optional: {"input"?: string, "inputs"?: object}.

curl -s -X POST https://api.plungeai.com/v1/workflows/wf-morning-brief/execute \
  -H "Authorization: Bearer ozk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"input": "today"}'
{
  "success": true,
  "workflow_id": "00000000-0000-4000-8000-000000000001",
  "final_task_id": "t3",
  "request_id": "..."
}

Errors: 404 workflow_not_found (no such id under your identity — list your saved workflows in Studio, or re-check the id), 502 engine_error.

SSE streaming — live workflow events

Two variants, same event stream:

  • POST /v1/workflows/{id}/execute-stream — saved workflow (in the OpenAPI spec)
  • POST /v1/workflows/execute-stream — inline body, same formats as /v1/workflows/execute, fully documented in the OpenAPI spec (orchestration/api-gateway/openapi.ts) alongside the saved-workflow variant. Caveat: this inline variant forwards input but silently drops inputs (the JSON branch never reads body.inputs, unlike the YAML branch which does — orchestration/api-gateway/routes/workflows.ts) — need multi-input? Use /v1/workflows/execute or /v1/workflows/{id}/execute-stream (both forward inputs).
curl -N -X POST https://api.plungeai.com/v1/workflows/wf-morning-brief/execute-stream \
  -H "Authorization: Bearer ozk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"input": "today"}'

Response is text/event-stream with named events — each frame is event: <type> + data: <json>, and the data payload always carries {workflow_id, execution_id, timestamp, type, data, elapsed_ms, duration_ms?} (the event-specific fields live under data). Event sequence:

request_received → workflow_loaded → workflow_started
  → task_dispatched → task_completed   (per task)
  → heartbeat                          (every ~25s during a task >20s — expect it,
                                        or idle timeouts will kill long streams)
  → workflow_completed                 (success only; execution summary + metrics)
  → workflow_result                    (terminal, ALWAYS check its success field)

On failure the engine emits workflow_error (error + progress counters) and the terminal workflow_result carries success: false + error — code that only checks for the workflow_result event name reports failed runs as done. Other event types appear for the matching task types (parallel_start, batch_progress, debate_*, …) — switch on the ones you need, ignore the rest.

A body the engine can't parse returns HTTP 400 whose body is itself an SSE error event — check the status before treating the body as a stream.

Consume with any SSE client (EventSource won't do — it's a POST; use fetch + a stream reader in JS, or curl -N / httpx.stream elsewhere) and parse the event: lines, not just data: lines. The stream is pass-through and unbuffered; x-request-id is stamped on the response headers. Don't rely on a dropped stream's run surviving — the engine runs the workflow inside the stream; for durability use /v1/workflows/execute + the results route.

GET /v1/workflows/results/{workflowId}/{taskId} — redeem a task result

curl -s https://api.plungeai.com/v1/workflows/results/00000000-0000-4000-8000-000000000005/t1 \
  -H "Authorization: Bearer ozk_YOUR_KEY"

Ready — HTTP 200:

{
  "content": "ok",
  "content_type": "text/plain",
  "workflow_id": "00000000-0000-4000-8000-000000000001",
  "task_id": "t1"
}

Not ready — HTTP 404 {"error":{"code":"not_ready",...}}. Poll with backoff (2s+, growing); not_ready while a workflow runs is normal.

POST /v1/workflows/executions/{id}/cancel — cancel a running execution

Cooperative cancel: writes the SharedMemory cancel marker the engine and agent loops poll at their next turn/tool boundary, then stamps the execution row cancelled. {id} is the execution id — the same value returned as workflow_id from /v1/workflows/execute (or the x-trace-id you sent on that call). Since /v1/workflows/execute is synchronous, send the cancel from a second connection while the first is still running.

curl -s -X POST https://api.plungeai.com/v1/workflows/executions/00000000-0000-4000-8000-000000000005/cancel \
  -H "Authorization: Bearer ozk_YOUR_KEY"
{
  "success": true,
  "cancelled": "00000000-0000-4000-8000-000000000005",
  "markers": ["00000000-0000-4000-8000-000000000005"]
}

Errors: 404 not_found (no such execution under your identity — wrong owner never confirms the execution exists), 409 not_running (already finished or already cancelled).

Fire-and-redeem pattern (Python)

import time, requests

BASE = "https://api.plungeai.com"
H = {"Authorization": "Bearer ozk_YOUR_KEY"}

ack = requests.post(f"{BASE}/v1/workflows/execute", headers=H, json={
    "workflow": {"name": "demo", "tasks": [
        {"type": "task", "id": "t1", "agent": "llm-agent", "prompt": "Say: ok"}]},
}).json()

wf, task = ack["workflow_id"], ack["final_task_id"]
for i in range(1, 9):
    r = requests.get(f"{BASE}/v1/workflows/results/{wf}/{task}", headers=H)
    if r.status_code == 200:
        print(r.json()["content"]); break
    time.sleep(2 * i)

Trace correlation

Send x-trace-id: <your-id> on any execute call; every engine span of the run (dispatches, completions, the result) lands under that id at GET /v1/traces/<your-id> — see plungeai-results-traces.

Legacy aliases (deprecated — do not use in new code)

POST /v1/execute, POST /v1/cnl/execute, POST /v1/cnl/execute-stream are pre-router aliases of the inline workflow handlers, kept so old integrations don't break. Same auth, same bodies, same responses. New and generated code targets /v1/workflows/* only.

Planned: TI-33

Search is not available yet. Until it ships, use the page index or browse the sidebar.

Planned: TI-34

The docs assistant is not available yet. You can hand these docs to your own assistant instead.