plungeai-discovery
Discovery — /v1/discovery
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.
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
| Param | Values | Notes |
|---|---|---|
q | free text | Natural-language capability query ("convert pdf to markdown") |
kind | agents | skills | digital-twins | personas | experts | backgrounds | workflows | models | providers | connectors | plugins | mcp-servers | Catalog segment (plural) |
type, category, tier | strings | Additional filters |
status | default active | Leave defaulted — active means deployed and callable |
limit, offset | integers | Paging |
mode | hybrid | keyword | vector | Force one search leg (default hybrid). Response searchMethod values are hybrid/vector/text — keyword mode (and any keyword fallback) answers "text", never "keyword" |
fields | list | summary | full | Card detail level |
include | quality | Attach 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,
"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, not the catalog total.
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 (messagecarries the original text verbatim); it never reaches the caller as a bare string. Always safe to readerr.error.code. 429→rate_limited(Retry-Afterheader).5xxfrom the registry never leaks through raw — it becomes a clean502 {"error":{"code":"upstream_error", ...}}.
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.
Related
Execution trace lookups (GET /v1/traces/{id}) are a separate observability
surface — see the plungeai-results-traces skill, not this one.