Getting started
Your first calls
One key, one agent call, one model call, one MCP connection.
Four steps from no account to a working agent call, model call and MCP connection. Every command reads its key from an environment variable; no example contains a key.
1. Get a key
- Create an ozk_ key
Sign in at https://dashboard.plungeai.com (opens in a new tab) and open Dashboard → One API → Keys. Name the key and pick an expiry: never, or 7, 30, 90, 180 or 365 days.
- Copy it once
The key starts with
ozk_and is shown exactly once. The same key works for steps 2 to 4. - Put it in your shell
export PLUNGE_API_KEY=ozk_... # every plane and MCP
Which key opens which route is on Authentication & keys.
2. Call an agent
One prompt to one-agent, the platform's agent runtime, answered on the same connection:
import os, requests
r = requests.post(
"https://api.plungeai.com/v1/agents/one-agent/execute",
headers={"Authorization": f"Bearer {os.environ['PLUNGE_API_KEY']}"},
json={"prompt": "In one sentence: what is a content delivery network?", "sync": True, "max_tokens": 60},
)
print(r.json()["content"])const r = await fetch('https://api.plungeai.com/v1/agents/one-agent/execute', {
method: 'POST',
headers: { Authorization: `Bearer ${process.env.PLUNGE_API_KEY}`, 'Content-Type': 'application/json' },
body: JSON.stringify({ prompt: 'In one sentence: what is a content delivery network?', sync: true, max_tokens: 60 }),
})
console.log((await r.json()).content)var client = java.net.http.HttpClient.newHttpClient();
var request = java.net.http.HttpRequest.newBuilder(java.net.URI.create("https://api.plungeai.com/v1/agents/one-agent/execute"))
.header("Authorization", "Bearer " + System.getenv("PLUNGE_API_KEY"))
.header("Content-Type", "application/json")
.POST(java.net.http.HttpRequest.BodyPublishers.ofString("{\"prompt\":\"In one sentence: what is a content delivery network?\",\"sync\":true,\"max_tokens\":60}"))
.build();
System.out.println(client.send(request, java.net.http.HttpResponse.BodyHandlers.ofString()).body());curl -s -X POST https://api.plungeai.com/v1/agents/one-agent/execute \
-H "Authorization: Bearer $PLUNGE_API_KEY" -H 'Content-Type: application/json' \
-d '{"prompt":"In one sentence: what is a content delivery network?","sync":true,"max_tokens":60}'The answer is in content. Add "stream": true to get OpenAI-shaped chunks that end with data: [DONE].
3. Call a model
The models plane is OpenAI-compatible: point the OpenAI SDK at https://api.plungeai.com/v1 and pass a provider/model slug from GET /v1/models.
import os
from openai import OpenAI
client = OpenAI(api_key=os.environ["PLUNGE_API_KEY"], base_url="https://api.plungeai.com/v1")
resp = client.chat.completions.create(
model="anthropic/claude-sonnet-4-6",
messages=[{"role": "user", "content": "Reply with exactly the word: pong"}],
max_tokens=16,
)
print(resp.choices[0].message.content)import OpenAI from 'openai'
const client = new OpenAI({ apiKey: process.env.PLUNGE_API_KEY, baseURL: 'https://api.plungeai.com/v1' })
const resp = await client.chat.completions.create({
model: 'anthropic/claude-sonnet-4-6',
messages: [{ role: 'user', content: 'Reply with exactly the word: pong' }],
max_tokens: 16,
})
console.log(resp.choices[0].message.content)var client = java.net.http.HttpClient.newHttpClient();
var request = java.net.http.HttpRequest.newBuilder(java.net.URI.create("https://api.plungeai.com/v1/chat/completions"))
.header("Authorization", "Bearer " + System.getenv("PLUNGE_API_KEY"))
.header("Content-Type", "application/json")
.POST(java.net.http.HttpRequest.BodyPublishers.ofString("{\"model\":\"anthropic/claude-sonnet-4-6\",\"messages\":[{\"role\":\"user\",\"content\":\"Reply with exactly the word: pong\"}],\"max_tokens\":16}"))
.build();
System.out.println(client.send(request, java.net.http.HttpResponse.BodyHandlers.ofString()).body());curl -s https://api.plungeai.com/v1/chat/completions \
-H "Authorization: Bearer $PLUNGE_API_KEY" -H 'Content-Type: application/json' \
-d '{"model":"anthropic/claude-sonnet-4-6","messages":[{"role":"user","content":"Reply with exactly the word: pong"}],"max_tokens":16}'The model field of the response names the model that served the request; after a failover it can differ from the one you asked for. The cURL call is re-run live by the One API guide's example verifier; the SDK snippets send the same request.
4. Connect your coding agent
One command connects Claude Code to the MCP server and its 20 plungeai_* tools:
claude mcp add --transport http plungeai https://mcp.plungeai.com/v1 \
--header "Authorization: Bearer $PLUNGE_API_KEY" --scope user--scope user keeps the entry in ~/.claude.json, outside your repository; never use --scope project with a literal key. Run /mcp in a session to see plungeai, then ask: use plungeai_whoami to confirm my identity. Every other client is on the MCP quickstart.
Request ids and traces
Every response carries a server-minted x-request-id; quote it when you report a problem. To group several calls into one trace, send your own UUID in x-trace-id and read the trace with GET /v1/traces/{id}:
curl -s "https://api.plungeai.com/v1/traces/$(uuidgen)" -H "Authorization: Bearer $PLUNGE_API_KEY"A trace id you already used on an execution returns 409 duplicate_execution_id: send a fresh UUID each time.
Next steps
The seven planes and how a request flows.
Match your job to a plane.
Every field of the agent call.
Make it a bot
A bot is a saved workflow that runs a One Agent loop on a clock, inside a policy you set. Four calls take it from nothing to a scheduled run; each reads the key from the same variable.
1. Create it. kind: bot runs the bot checks on the YAML before anything is stored:
curl -s -X POST https://api.plungeai.com/v1/workflows \
-H "Authorization: Bearer $PLUNGE_API_KEY" -H 'Content-Type: application/json' \
-d '{"name":"Daily Brief","kind":"bot","yaml":"workflow:\n name: Daily Brief\n tasks:\n - type: harness\n id: brief\n agent: one-agent\n goal: \"{input}\"\n max_iterations: 6\n allowed_tools: [web_search, web_fetch, task_complete]\n mission: |\n You are Daily Brief. Answer in at most five lines and cite each source URL.\n When your task is finished, call the task_complete tool with your final result.\n"}'The answer is 201 with the saved row under workflow. Its id is the <bot id> below.
2. Set what it may do and spend. Ask before it sends anything, never let it pay, cap one run at 25 cents:
curl -s -X PUT https://api.plungeai.com/v1/workflows/<bot id>/permissions \
-H "Authorization: Bearer $PLUNGE_API_KEY" -H 'Content-Type: application/json' \
-d '{"classes":{"send":"ask","pay":"hand_off"},"budget_usd_run":0.25}'3. Run it.
curl -s -X POST https://api.plungeai.com/v1/workflows/<bot id>/execute \
-H "Authorization: Bearer $PLUNGE_API_KEY" -H 'Content-Type: application/json' \
-d '{"input":"In one line: what is the current Node.js LTS major version? Cite the URL."}'The answer is in content. A run that stops on a held action reads needs_approval; answer it with POST /v1/executions/{id}/continue.
4. Schedule it. Weekdays at 09:00 Pacific:
curl -s -X POST https://api.plungeai.com/v1/schedules \
-H "Authorization: Bearer $PLUNGE_API_KEY" -H 'Content-Type: application/json' \
-d '{"name":"Daily Brief","workflow_id":"<bot id>","schedule":"0 9 * * 1-5","timezone":"America/Los_Angeles","parameters":{"input":"Top story about Cloudflare Workers today"}}'Add "deliver": ["slack"] under parameters to send each result to your Slack. The rest of the bot surface (channels, groups, triggers, files, the playbook of keys) starts at Bots.