Bots
Control a bot over REST, MCP and the CLI
Every bot operation on each door. The One API routes, the MCP actions and the Ocean CLI verbs side by side, with the same key, the same rows and the same stored policy.
A bot is the same row whichever door you use. The One API, the MCP server and the Ocean CLI read and write the rows Studio shows, take the same ozk_ key, and stop at the same stored policy. Pick the door that fits the caller: REST for code, MCP for an agent, the CLI for a terminal.
| Door | Address | Auth |
|---|---|---|
| One API 2.3.0 | https://api.plungeai.com | Authorization: Bearer $PLUNGE_API_KEY |
| MCP server 2.6.0 | https://mcp.plungeai.com/v1 | The same key; tools are named plungeai_* |
| Ocean CLI 2.1.0 | ocean-cli | ocean-cli login, or OCEAN_API_KEY |
Another account's id answers the same 404 <resource>_not_found as an id that does not exist. A storage or upstream failure is a generic 502; the message never carries database text. Every error is {"error": {"code", "message"}} with an X-Error-Code header. The response format is yours to pick (four wires).
Operations by door
| Do this | REST | MCP | CLI |
|---|---|---|---|
| Save a bot | POST /v1/workflows with kind: bot | plungeai_workflow create | workflows create NAME FILE.yaml --kind bot |
| Check the YAML | The save runs the lint and answers 422 invalid_workflow | The same, on create and update | workflows validate FILE.yaml --kind bot (local) |
| Change it, version it | PATCH /v1/workflows/{id}, POST .../versions | update, save_version, restore_version | workflows update, save-version, restore |
| Copy a template | POST /v1/templates/{id}/use | plungeai_templates | templates |
| Read or set permissions and caps | GET, PUT /v1/workflows/{id}/permissions | plungeai_workflow permissions_get, permissions_set | workflows permissions get, set |
| Run it | POST /v1/workflows/{id}/execute | plungeai_execute_workflow | workflows run ID |
| Answer a pause or approve | POST /v1/executions/{id}/continue | plungeai_continue | executions continue ID |
| Steer a running bot | POST /v1/executions/{id}/steer | plungeai_executions steer | executions steer ID TEXT |
| List a run's files | GET /v1/executions/{id}/files | plungeai_executions files | executions files ID |
| Schedule it | POST /v1/schedules (run_at, ends_at) | plungeai_schedule create | schedules create (--cron @once --at, --ends-at) |
| Wake it | POST /v1/schedules/{id}/wake | plungeai_schedule wake | schedules wake ID --note TEXT |
| Add a trigger or hook | POST /v1/triggers/{webhook,email,hooks} | plungeai_schedule webhook_mint, email_mint, hooks_mint (and _list, _delete) | schedules triggers webhook|email|hooks mint|list|delete |
| Read its workspace | GET /v1/workflows/{id}/workspace-files, .../download?path= | plungeai_workflow files, file | workflows files ID [--download PATH --out FILE] |
| Read its inbox | GET /v1/workflows/{id}/inbox | plungeai_workflow inbox | workflows inbox ID |
| Bind a chat | POST /v1/workflows/{id}/bindings, DELETE .../{channel}/{sender_id} | plungeai_workflow bindings, bind, unbind | workflows bindings list|bind|unbind |
| Pair a chat | POST /v1/channels/pair, GET /v1/channels; then send the code from the chat | Studio or REST | Studio or REST |
| Manage bot groups | /v1/bot-groups, .../{id}/thread | plungeai_workflow groups, group_set, group_delete, group_thread | bot-groups list|create|update|delete|thread |
| Give it an A2A door | No REST route; Studio (Share, A2A) | plungeai_workflow a2a_door | Studio (Share, A2A) |
| Search its runs, its memory | GET /v1/memory/runs, /v1/memory/recall | plungeai_memory | memory |
The operation pages are in the API reference: Bots, Schedules, Triggers and Executions.
The agent call door
POST /v1/execute takes the program as the body and always runs through the engine, so a saved bot keeps its stored policy. The body is JSON or YAML:
| Body | Runs |
|---|---|
agent: <id> and input | Your saved agent or bot, from its live YAML. |
agent: <id>@3 and input | Snapshot 3 of it: a pinned version. |
agent: <building block id> and that agent's own fields | A registry agent as a one-task workflow. |
workflow:, or a root name and tasks: | An inline workflow. |
dry_run: true validates and reports what would run without running it, spending anything or writing an execution row. stream: true answers as server-sent events. See Agent call.
MCP
- Every tool takes
user_request(the user's words) and most takeformat:markdown(default) orjson. A tool that runs something also takesuser_context(time zone, locale, place), merged over the zone the network request implies. plungeai_get_resultwithformat: jsonreturns the structured result (status,result,tasks), not the rendered thread.plungeai_workflowcreatetakeskind:workflow,agent,botorcampaign.plungeai_schedulecreatewithschedule: "@once"needsrun_at: without it the answer isrun_at required.permissions_settakesclasses,locks,budget_usd_runandbudget_usd_month;locksneeds a team admin.filereturns a workspace file as base64, up to 5 MiB; a bigger file is refused with the REST download route to use instead.
CLI
The verbs below are in Ocean CLI 2.1.0. Run it from the repository today with npm run ocean-cli -- <verb>; once it is published it installs with npm install -g @plungeai/ocean and runs as ocean-cli.
- Every verb takes
--json(one JSON document on stdout) and, when it creates, runs or pays,--dry-run(prints the exact request and sends nothing). - Destructive verbs (delete, unbind, restore, forget) need
--yes. workflows permissions setreads the stored classes and locks first and sends only what you name, so one--classkeeps the others.- Exit codes: 2 bad input, 3 auth, 4 API error or a run that needs input or approval, 5 timeout.
ocean-cli workflows permissions set <bot id> --class pay=ask --lock pay --budget-run 0.5 --budget-month 20
ocean-cli schedules create "Reminder" --type workflow --target <bot id> --cron @once --at 2026-10-06T09:00:00Z
ocean-cli bot-groups create --name research-crew --members <bot id>,<bot id>
ocean-cli executions steer <execution id> "also check the pricing page"