For AI agents: a documentation index is available at https://www.plungeai.com/docs/llms.txt. Append .md to any page URL, or send Accept: text/markdown, to get markdown. Setup instructions for agents are at https://www.plungeai.com/docs/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.

Discovery is the live catalog of everything the platform can do — agents, workflows, MCP servers, connectors, models — with hybrid semantic + keyword search ranked server-side.

Auth: Authorization: Bearer ozk_YOUR_KEY on every route here.

Why discovery first

Ids, capabilities, and counts change without notice. Any code (especially generated code) that names an agent, tool, MCP server, or model must have taken that id from a live discovery/list response — never from memory, docs, or this skill. Describe the capability in plain words and trust the ranking.

GET /v1/discovery/search

ParamValuesNotes
qfree textNatural-language capability query ("convert pdf to markdown")
kindagents | skills | digital-twins | personas | experts | backgrounds | workflows | models | providers | connectors | plugins | mcp-serversCatalog segment (plural)
type, category, tierstringsAdditional filters
statusdefault activeLeave defaulted — active means deployed and callable
limit, offsetintegersPaging
modehybrid | keyword | vectorForce one search leg (default hybrid). Response searchMethod values are hybrid/vector/text — keyword mode (and any keyword fallback) answers "text", never "keyword"
fieldslist | summary | fullCard detail level
includequalityAttach measured eval scores per card
curl -s "https://api.plungeai.com/v1/discovery/search?q=web%20search&kind=agents&limit=2" \
  -H "Authorization: Bearer ozk_YOUR_KEY"
{
  "cards": [
    { "id": "brave-agent", "name": "Brave Search", "type": "agent",
      "category": "search", "status": "active",
      "description": "Web search via Brave", "tags": ["search", "web"] },
    { "id": "exa-agent", "name": "Exa Search", "type": "agent",
      "category": "search", "status": "active",
      "description": "Semantic web search", "tags": ["search"] }
  ],
  "count": 2,
  "total": 14,
  "searchMethod": "hybrid"
}

The live response also carries a query echo object, and extra fields may appear — parse what you need, don't assert the exact shape. count is the returned page's length; total is every card the filters match, ignoring limit/offset. Agent cards also carry credential ({"tier": "platform"} or {"tier": "connection", "provider", "method"}).

With include=quality, each card gains a quality block — {"score": 1, "success_rate": 1, "runs": 12} — or null when unmeasured (no eval runs yet on that card/tier). Treat null as "unknown", not "bad".

401 → missing/invalid ozk_ key.

POST /v1/discovery/recommend

Ask the platform to pick the best card for a task instead of ranking yourself.

Body: {"type": "<card type, e.g. agent>", "task": "<what you need done>"}.

curl -s -X POST https://api.plungeai.com/v1/discovery/recommend \
  -H "Authorization: Bearer ozk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"type": "agent", "task": "summarize a long PDF into bullet points"}'
{
  "recommended": "pdf-agent",
  "card": { "id": "pdf-agent", "name": "PDF Agent", "type": "agent",
            "category": "documents", "status": "active",
            "description": "Convert and extract PDFs" },
  "score": 0.91
}

recommended (and card) can be null when nothing matches — handle it; a card does not always come back.

Errors — always the One API envelope ({"error": {"code", "message", ...}}), but the code differs by where the rejection happened:

  • Unparseable body → 400 {"error":{"code":"invalid_json","message":"JSON body required: { type, task }"}}.
  • A parseable body the registry rejects → normalized to 400 {"error":{"code":"invalid_request","message":"Invalid type: x"}} / {"code":"invalid_request","message":"Task description required"} — the registry's own flat {"error": "<string>"} is rewritten into the envelope before it reaches you (message carries the original text verbatim); it never reaches the caller as a bare string. Always safe to read err.error.code.
  • 429 → rate_limited (Retry-After header).
  • 5xx from the registry never leaks through raw — it becomes a clean 502 {"error":{"code":"upstream_error", ...}}.

POST /v1/discovery/resolve

Resolve one plain-language task to ONE tool, its operation and an example call, with a calibrated confidence — the shortcut when you want a single answer, not a ranked list. Body: task (required), optional kinds (≤ 8 card types; default every discoverable kind), category, status (default active).

curl -s -X POST https://api.plungeai.com/v1/discovery/resolve \
  -H "Authorization: Bearer ozk_YOUR_KEY" -H "Content-Type: application/json" \
  -d '{"task": "convert a PDF to markdown", "kinds": ["agent"]}'

Answer: {outcome: "match" | "uncertain" | "none", tool: {id, kind, type, name, description, category, status}, operation: {name, purpose, gated}, call: {required_params, example_cnl}, confidence, alternatives: [{id, kind, name, p}], mode}. confidence is null on the keyword fallback (the decision model was unavailable). Act on match only; on uncertain or none fall back to GET /v1/discovery/search and read the cards. A body with no task is 400 invalid_json; 429 rate_limited carries Retry-After.

GET /v1/discovery/cards/{type}/{id}

The full capability card as markdown (text/markdown) — the LLM-friendly view with operations, parameters, good-at examples, and "Not for → use X instead" redirects. Fetch it before building on an unfamiliar capability. {type} is the singular card type (agent, skill, digital_twin, expert, background, workflow, model, provider, connector, plugin, mcp_server) — the plural search kind values are accepted aliases.

curl -s https://api.plungeai.com/v1/discovery/cards/agent/brave-agent \
  -H "Authorization: Bearer ozk_YOUR_KEY"
# Brave Search (brave-agent)

Web search via the Brave Search API.

## Operations
- search — Run a web search (params: query, count?)
...

404 when no such card exists — normalized to the One API envelope, {"error":{"code":"not_found","message":"Card not found"}}; a bad {type} is 400 {"error":{"code":"invalid_request","message":"Invalid type: …"}}. The registry's own flat {"error": "<string>"} response is rewritten into this envelope (the original text lands in message) before it ever reaches you — same normalization as /v1/discovery/recommend above.

Templates — /v1/templates

Starter workflows, agents and bots (the gallery behind plungeai_templates and Studio's template picker).

curl -s "https://api.plungeai.com/v1/templates?kind=bot&limit=3" -H "Authorization: Bearer ozk_YOUR_KEY"
# 200 {"templates":[{"id","name","kind","category","difficulty","usage_count","description"}],"count":3}

curl -s https://api.plungeai.com/v1/templates/<template id> -H "Authorization: Bearer ozk_YOUR_KEY"
# 200 {"template": {…}, "yaml": "…"}

curl -s -X POST https://api.plungeai.com/v1/templates/<template id>/use \
  -H "Authorization: Bearer ozk_YOUR_KEY" -H "Content-Type: application/json" -d '{"name": "My copy"}'
# 201 {"workflow": {…}}   a saved workflow of the template's kind

kind is workflow, agent or bot (else 422 invalid_params); limit 1–100, default 50; category filters. Active templates only, featured first. use keeps a bot template's own name and names the others <template> (copy) unless you pass name (1–512 characters). The copy runs the same save-time lint as POST /v1/workflows: 422 invalid_workflow (with errors and warnings) creates nothing; 404 template_not_found for an id that is not an active template. CLI: ocean-cli templates list | get | use.

Execution trace lookups (GET /v1/traces/{id}) are a separate observability surface — see the plungeai-results-traces skill, not this one.

Planned: TI-34

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