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. One ozk_ key opens every plane, models included.

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

One API 2.3.0 puts everything a saved bot needs on REST, under the same ozk_ key (Authorization: Bearer ozk_YOUR_KEY). The live contract is GET https://api.plungeai.com/v1/openapi.json (tags Workflows, Executions, Schedules, Triggers, Bots, Memory, Skills, Templates, Connections, Agent Call) — regenerate clients from it, never copy routes from this page.

Rules on every route here: your rows only (another account's id answers 404 <thing>_not_found, same as a missing one) · JSON by default, YAML in (Content-Type: text/yaml) and out on the same routes, format= or Accept picks json | yaml | markdown | text · errors are {"error":{"code","message"}} · a storage or upstream failure is a generic 502, never its text.

Saved workflows and bots

RouteDoes
POST /v1/workflowssave {name, kind, yaml, folder?, campaign_config?}; kind is workflow, agent, bot or campaign (campaign_config with kind: campaign: the ledger and its schedule)
GET /v1/workflows, GET|PATCH|DELETE /v1/workflows/{id}list (kind, search, folder, limit ≤ 200, offset), read, change, delete (a bot also loses its memory and jobs)
GET|POST /v1/workflows/{id}/versions, POST …/versions/{versionId}/restorelist versions, save one {label?}, restore one
POST /v1/workflows/{id}/executerun a saved workflow or bot by id (level 2)

The YAML is validated and linted for its kind before anything is written: a bot is ONE type: harness task on agent: one-agent; a refusal is 422 invalid_workflow with errors.

Bot policy, workspace, inbox, chats, groups (owner only)

RouteDoes
GET|PUT /v1/workflows/{id}/permissions{classes: {send|write|pay|delete: allow|ask|deny|hand_off}, locks: [...], budget_usd_run, budget_usd_month}; fields you send replace, null clears a cap. locks need a team admin (else 403 lock_admin_required, nothing written)
GET …/workspace-files, GET …/workspace-files/download?path=the files the bot keeps (workspace: bot); raw bytes, Content-Disposition: attachment, 20 MB cap
GET …/inboxqueued bot-to-bot messages (read-only)
GET|POST …/bindings, DELETE …/bindings/{channel}/{sender_id}which paired chat talks to this bot: {channel, sender_id}; a chat talks to ONE bot
GET /v1/channels, POST /v1/channels/pair {channel}your paired chats; a 10-minute pairing code (telegram, whatsapp, discord, teams)
GET|POST /v1/bot-groups, PUT|DELETE /v1/bot-groups/{id}, GET …/{id}/threadnamed sets of 2–6 of your bots (name 1–40 chars) for message_bot to=group:<name>; the thread is read-only

The engine loads the stored policy once per run, so every door (REST, MCP, CLI, Studio, schedules, triggers, chat) stops at the same caps and holds. A run that reaches its cap says so in its result.

Executions (every run, whichever door started it)

RouteDoes
GET /v1/executions, GET|DELETE /v1/executions/{id}list (source, status, workflow_id), poll, delete
GET …/{id}/output, GET …/{id}/conversation, GET …/{id}/filesfinal result, turns added by continue/followup, Office/PDF files the run produced
POST …/{id}/continue {answer | approve, allow_scope?}answer a paused run, or approve its held action; allow_scope: once, run, always (409 not_paused on a finished run: use followup)
POST …/{id}/followup {text}queued (202) while running, a new turn (200) once finished
POST …/{id}/steer {text}queue a message for the live loop (202); a finished run is 409 execution_finished
POST …/{id}/cancel, GET …/{id}/streamcooperative stop; SSE re-attach (status, progress, done)

Schedules, triggers, hooks

RouteDoes
POST /v1/schedules{name, schedule, workflow_id, job_type?: workflow|heartbeat, timezone?, run_at?, ends_at?, parameters?}; schedule: "@once" needs run_at (ISO-8601 WITH a UTC offset, in the future: 400 run_at_required, 400 run_at_past)
GET /v1/schedules, GET|PATCH|DELETE /v1/schedules/{id}list, read (with latest runs), change, delete (history stays)
POST …/{id}/pause, …/resume, …/run {input?}, …/wake {note?, in?}state; run now (run_id, execution_id); fire the workflow once, optionally later (a pending wake is re-timed, never stacked)
GET /v1/schedules/{id}/runsrun history; execution_id is what the execution routes take
GET|POST /v1/triggers/webhook, DELETE …/{token}, POST …/{token}/rotatean HTTPS URL that runs the schedule; scheme: generic, github, gitlab, standard-webhooks; prompt_template, filters
GET|POST /v1/triggers/email, DELETE …/{token}, POST …/{token}/rotatean address (bot+<token>) that runs it; allowed_from filter
GET|POST /v1/triggers/hooks, DELETE …/{id}signed run events to your https URL: run.started, run.finished, run.failed, run.needs_approval; verify X-Ocean-Signature

Every trigger call names the schedule with schedule_id; a secret is shown once, on mint.

Connections — your keys, or your customer's

RouteDoes
GET /v1/connectionsstatus only, never a credential; ?on_behalf_of=<customer id> lists one customer's
POST /v1/connections/{provider}bring a key {api_key, api_secret?, on_behalf_of?}; checked live, stored encrypted
DELETE /v1/connections/{provider}disconnect (204); ?on_behalf_of= for a customer's
POST /v1/connections/{provider}/linka one-use, 15-minute hosted connect URL to send a customer

A connection-tier agent with no connection answers 424 connection_required with a connect pointer. on_behalf_of (1–128 chars of A-Za-z0-9_.-, no ..) is accepted on POST /v1/execute among the execute routes: the run reads the credential connected under that customer id.

Other errors you will meet

503 not_enabled (bindings, bot groups, channel pairing before their migration or deploy) and 503 unavailable (outbound hooks) · 409 binding_limit, 422 not_paired (bind a chat you did not pair) · 409 name_taken, 422 invalid_name / invalid_members (bot groups) · 400 invalid_path, 404 file_not_found, 413 file_too_large (workspace download) · 404 trigger_not_found · 410 result_expired · 409 execution_failed · 502 upstream_error. The live spec lists each per operation.

Memory, skills, templates

GET /v1/memory/recall, POST /v1/memory/remember, POST /v1/memory/forget, GET /v1/memory/runs, GET /v1/memory/runs/{id} · GET /v1/skills, POST /v1/skills/learn, DELETE /v1/skills/{id} · GET /v1/templates, GET /v1/templates/{id}, POST /v1/templates/{id}/use. Detail: plungeai-memory, plungeai-skills-plugins, plungeai-discovery.

The Agent Call door — POST /v1/execute (level 3)

The body (JSON or YAML) is the program, and the call always runs through the engine, so a saved bot keeps its stored policy:

BodyRuns
agent: <id> + inputyour saved agent or bot, from its live YAML
agent: <id>@3 + inputsnapshot 3 of it (a pinned version)
agent: <building block id> + that agent's own fields (or a bare agent: one-agent + prompt)a registry agent as a one-task workflow
workflow: (object or YAML string), or root name + tasks:an inline workflow

Root keys that steer the call and never reach an agent: format, input, inputs, user_context, stream (SSE), dry_run (200 {dry_run, kind, agent, tasks, warnings}, no run, no row, no spend), on_behalf_of. Answers carry x-ocean-agent, x-ocean-tasks, x-ocean-version (<n>, live or inline).

curl -s -X POST https://api.plungeai.com/v1/execute \
  -H "Authorization: Bearer ozk_YOUR_KEY" -H "Content-Type: application/json" \
  -d '{"agent":"<saved bot id>@3","input":"Check the pricing page","dry_run":true}'
Status and codeWhen
404 agent_not_foundno saved agent of yours (or snapshot) and no building block with that id
400 ambiguous_body / invalid_body / missing_workflowagent: next to workflow:; a malformed agent ref or a non-boolean dry_run/stream; none of agent, workflow, tasks
403 agent_not_activea named agent card is parked
424 connection_required / credential_requireda connection-tier agent and no connected account (connect in the error)

The per-resource execute routes (/v1/workflows/{id}/execute, /v1/agents/{id}/execute) answer exactly as before: the three levels all stay. Start with level 2; use the door when the body is the program.

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.