This is the full developer documentation for AgentDepot Docs
# AgentDepot Documentation
> Guides and API reference for the AgentDepot REST API and MCP server.
Welcome to the AgentDepot developer documentation. AgentDepot is a platform for building and running AI agents connected to your organization’s resources through tools.
There are two ways to drive AgentDepot programmatically, and both are documented here:
## Guides
[Section titled “Guides”](#guides)
Start with the [Overview](/docs/guides/overview) to learn what the platform is, then read [Core concepts](/docs/guides/concepts) and [Setting up a full flow](/docs/guides/build-a-flow). These are the same guides the MCP server serves to connected agents via `read_documentation` — one source of truth.
## REST API reference
[Section titled “REST API reference”](#rest-api-reference)
The [REST API reference](/docs/reference/rest/) documents every public endpoint of the AgentDepot HTTP API, grouped by resource. It is generated from the live OpenAPI schema.
## MCP server reference
[Section titled “MCP server reference”](#mcp-server-reference)
The [MCP server reference](/docs/reference/mcp/) documents every tool the AgentDepot MCP server exposes (usable from Claude Desktop, Cowork, and other MCP hosts), grouped by category. It is generated from the live tool catalog.
## For agents
[Section titled “For agents”](#for-agents)
Every page on this site is also available as raw Markdown: append `.md` to any docs URL (for example, [`/docs/guides/overview.md`](/docs/guides/overview.md)). A machine-readable index lives at [`/llms.txt`](/llms.txt), and the full corpus at [`/llms-full.txt`](/llms-full.txt).
# Mention tokens in agent instructions
> Mention tokens (/type[key]) in agent instructions.
Agent instructions can embed **mention tokens** — short references to org resources — that the platform resolves at run time. The syntax is:
```plaintext
/type[key]
```
The resolved resource is appended to the agent’s system prompt as a “Referenced Resources” block that tells the agent exactly what the resource is and which tool to use to act on it. The agent sees the friendly description; you just embed the token.
## Supported types
[Section titled “Supported types”](#supported-types)
| Token | `key` value | What the agent is told to do |
| ----------------------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| `/prompt[slug]` | Prompt template slug | Call `run_prompt` with `prompt=""` and the required variables (or material input, if the prompt has an extraction schema) |
| `/agent[slug]` | Agent slug | Start a work chat via `create_chat` with `agent_slug=""` (fire-and-forget) |
| `/skill[slug]` | Skill slug | Call `activate_skill` with `slug=""` to load its instructions |
| `/tool[name]` | Custom tool name | Call the tool directly by name |
| `/connected-tool[slug]` | Integration slug (or name) | Use the integration’s tools (available prefixed with `_`) |
A prompt with an extraction schema (`fields`, see `prompt-fields`) is still referenced with `/prompt[slug]` — there is no separate extractor token.
## Example
[Section titled “Example”](#example)
An instruction that classifies a ticket, drafts a reply, and optionally escalates:
```plaintext
When a new support ticket arrives:
1. Use /prompt[ticket-classifier] to extract the category and priority.
2. If priority is "urgent", hand it off to /agent[escalation-bot].
3. Otherwise, use /prompt[draft-reply] with variables {category} to draft a reply.
```
## Notes
[Section titled “Notes”](#notes)
* Keys are **slugs** (not display names) for prompts, skills, and agents. Use `list_prompts`, `list_skills`, or `list_agents` to find slugs.
* Custom tool keys are the **tool name** (not slug), matching the name it was created with.
* Unresolved mentions (typos, deleted resources) are handled gracefully — the agent is warned in-context that the resource was not found.
* Duplicate tokens are deduplicated; order of first appearance is preserved.
# Setting up a full flow
> Set up a full agent flow end-to-end with these tools.
A typical end-to-end setup using these tools:
1. **Pick the org** — if you belong to several, call `list_orgs` and pass `org=` to each tool (single-org accounts can omit it).
2. **(Optional) build reusable blocks first** so the agent can reference them:
* `create_code_tool(name, source_code)` for a custom Python tool.
* `create_prompt(name, text)` — pass `fields` too for a prompt that returns structured data instead of free text (see `prompt-fields`) — / `create_skill(name, instructions, tool_slugs)`.
3. **Create the agent** — `create_agent(name, instruction=..., provider=..., model=..., allowed_tools=[...])`. `allowed_tools` accepts tool scope strings or slugs.
4. **Wire / adjust it** — `update_agent(agent, instruction=..., allowed_tools=..., mounted_skills=[...])`. Partial: only the fields you pass change.
5. **Test before deploying** — try the draft without making it live:
* `start_chat(agent, message, use_draft=true)` runs the chat on the **unpublished draft** instruction. Poll `get_chat` as usual.
* Building blocks in isolation: `test_code_tool(tool, args)`, `test_prompt(prompt, variables)` (or `test_prompt(prompt, input_text=...)` for a schema-bearing prompt) — no chat needed. See the `testing` doc.
6. **Deploy** — `deploy_agent(agent)` to make the draft instruction active. (Skills/code tools/prompts don’t need a deploy step.)
7. **Run it** — `start_chat(agent, message)` → returns a `chat_id`.
8. **Read the result** — poll `get_chat(chat_id)` until `status` != “running”; read the final assistant message + `outcomes`. If it’s “paused” with a `pending_hitl_request`, answer via `respond_to_hitl`.
Use `list_*` / `get_*` tools at any point to inspect existing entities.
# Chat lifecycle & polling
> How chats execute asynchronously and how to poll them.
Chats execute **asynchronously** on a background worker — `start_chat` / `send_message` return immediately with `status: "accepted"`; the turn runs after.
`get_chat(chat_id)` is the poll target. Its `status`:
* **running** — a turn is in flight. Keep polling.
* **active** — idle / turn finished. Read the last assistant message + `outcomes`.
* **paused** — waiting on a human. `pending_hitl_request` describes what’s needed (`question`, `request_type`, `tool_name`/`tool_args`, and `ui` when the request offered specific options — e.g. `[{"buttons": ["Retry now", "Skip Todoist"]}]`). Resolve with `respond_to_hitl(request_id, action=... | text=... | selection=...)`, which resumes the turn. When `ui` offered `buttons`/`choice`, `action`/`selection` must be one of those options — anything else is rejected with the valid list. Sending a new `send_message` also resumes a paused chat.
* **errored** — the turn failed.
Note a tool-only turn may produce no new assistant message — rely on `status` and `outcomes`, not message presence. `outcomes` is where completed goals are recorded (status success / failed / partial + a `summary`).
# Use with Claude Desktop
> Connect Claude Desktop, claude.ai, or Claude Code to AgentDepot as a custom connector and manage your agents by chatting with Claude.
AgentDepot runs a hosted [MCP](https://modelcontextprotocol.io) server that lets Claude manage your AgentDepot workspace directly from a conversation: create and configure agents, build reusable blocks (code tools, prompts, skills), start chats, and read their results.
The server URL is:
```plaintext
https://api.agentdepot.org/mcp
```
Authentication happens through your AgentDepot account via OAuth — no API keys to copy around.
## What you need
[Section titled “What you need”](#what-you-need)
* A **paid Claude plan** (Pro, Max, Team, or Enterprise). Custom connectors are not available on the free plan.
* An **AgentDepot account** that belongs to at least one organization.
## Connect on claude.ai
[Section titled “Connect on claude.ai”](#connect-on-claudeai)
1. Open [claude.ai connector settings](https://claude.ai/new?modal=add-custom-connector#settings/customize-connectors) — this link opens the connector settings directly. (Manual path: **Customize → Connectors → Add custom connector**. On Team/Enterprise plans, connectors are managed under **Organization settings** by an admin.)
2. Enter a name (e.g. `AgentDepot`) and the server URL `https://api.agentdepot.org/mcp`. Leave the advanced OAuth fields empty.
3. Click **Add**, then **Connect**. A window opens asking you to sign in to AgentDepot and approve access.
4. After approving, the connector shows as connected.
## Connect in Claude Desktop
[Section titled “Connect in Claude Desktop”](#connect-in-claude-desktop)
Connectors are tied to your Claude account, so anything you add on claude.ai is also available in Claude Desktop after a restart. To add it from the app instead: **Settings → Connectors → Add custom connector**, then follow the same steps as above.
## Connect in Claude Code
[Section titled “Connect in Claude Code”](#connect-in-claude-code)
```plaintext
claude mcp add --transport http agentdepot https://api.agentdepot.org/mcp
```
Claude Code opens your browser for the same OAuth sign-in on first use.
## Using the connector
[Section titled “Using the connector”](#using-the-connector)
* In a chat, open the **+** (tools) menu, choose **Connectors**, and make sure AgentDepot is enabled for the conversation.
* Ask Claude to *“read the AgentDepot documentation”* — the connector ships a `read_documentation` tool that teaches Claude the platform end to end, so you can immediately ask for things like *“create an agent that triages incoming support email”*.
* If you belong to several organizations, tell Claude which one to work in, or ask it to *“list my orgs”*.
## Troubleshooting
[Section titled “Troubleshooting”](#troubleshooting)
* **“Your account was authorized, but AgentDepot returned an error when connecting.”** Try connecting again. If it keeps failing, remove the connector and add it back.
* **Claude doesn’t see any AgentDepot tools.** Check that the connector is enabled for the current conversation via the **+** menu.
* **Requests start failing after working fine.** Your session may have expired — open the connector’s settings and reconnect.
# Core concepts
> Core concepts: agents, revisions, building blocks, chats, outcomes, and HITL.
* **Agent** — the primary entity. Has a `name`/`slug`, an LLM (`provider`/`model`), an **instruction** (its task definition), an optional `system_prompt` (personality), an allowed toolset, and mounted skills. `execution_mode` is auto / manual / paused; `status` is active / archived.
* **Instruction & revisions** — instruction edits land on a **draft** revision. They are NOT live until you `deploy_agent`, which activates the draft. `get_agent` shows `instruction` (active) plus `draft_instruction` / `has_undeployed_draft`.
* **Building blocks** (reusable, org-scoped) the agent composes:
* **Code tool** (`code_tool`) — a custom Python tool; params/description come from the code’s manifest.
* **Prompt** — a reusable prompt template with `{{variables}}`. Optionally carries an extraction schema (`fields`, see `prompt-fields`) — when set, running it pulls structured fields out of input instead of generating free text.
* **Skill** — a bundle of {instructions + a tool subset + reference material} an agent mounts by slug. Live immediately on create/update.
* **Integration** — a connection to an external SaaS / MCP server (read-only here; connect new ones in the web UI — many need an interactive OAuth flow).
* **Chat** — the unit of work. You `start_chat` with a message; the agent runs a turn. Success is recorded as **outcomes** (not a terminal status).
* **Outcome** — an append-only record the agent emits when it completes a goal (status success / failed / partial, with a summary).
* **HITL** — human-in-the-loop. A chat can pause awaiting approval or input; you answer with `respond_to_hitl` to resume it.
# Files
> Read, list, and search files attached to or produced in chats.
A **file** is anything attached to or produced inside a chat. Two things look identical here on purpose — you do not need to tell them apart:
* **uploads** — files a user attached to the chat.
* **artifacts** — outputs an agent produced (reports, code, charts, stamped PDFs).
All three file tools speak one vocabulary; each returned file carries a `kind` (`upload` or `artifact`) if you ever need to know.
* `read_file(file_id)` — full text content of one file by id (upload OR artifact). Images / scanned files return metadata + a note (vision reads aren’t available over MCP).
* `list_files(chat_id)` — everything in a chat: uploads + artifacts produced there.
* `search_files(...)` — find files across scopes: by `chat_id`, by `agent`, or org-wide, optionally filtered by `title_contains` / `type`.
This is the same surface agents use at run time, so what you see here matches what an agent sees.
# What AgentDepot is
> What AgentDepot is and what this MCP server lets you do.
AgentDepot is a platform for building and running **AI agents** connected to your organization’s resources through tools. You create an agent, give it an instruction and a toolset, then assign it work as a **chat**; the agent executes, can call tools and other agents, and pauses for human approval when needed.
It’s a horizontal business-automation platform — integrations are general business SaaS (email, drive, CRM, docs, support desks, etc.), not just developer tools.
This MCP server lets you do all of that from here: create and configure agents, build reusable blocks (code tools, prompts — optionally with an extraction schema, skills), connect them, then start chats and read the results — the whole flow, without the web UI.
See also: `concepts`, `build-a-flow`, `chat-lifecycle`, `prompt-fields`, `agent-mentions`.
# Processes
> Define, validate, test, and monitor step-by-step processes.
A **process** is a compiled, deterministic SOP the platform executes step by step. It is NOT an agent chat: there is no free-running loop, and a run is a standalone object you watch with the run tools below (not a conversation). Reach for a process when the same procedure must run the same way every time — repeatable, auditable, with LLM judgment confined to small scoped steps. Reach for an agent when the work is open-ended and conversational.
## Anatomy of a definition
[Section titled “Anatomy of a definition”](#anatomy-of-a-definition)
A definition is plain data (YAML or JSON) — no expressions, no templates:
* `process` — the process’s name (slug). Must match the process it’s saved to.
* `envelope_schema` — JSON Schema for the **envelope**, the run’s input contract.
* `steps` — executed in order. Each step has:
* `id` — unique, referenced by other steps’ wiring.
* `sop` — required prose: the SOP sentence(s) this step implements.
* `block` — exactly one block kind (below).
* `params` — plain JSON for the block. Values may be reference strings (`"$envelope.external_id"`, `"$steps.extract.count"`, `"$flags"`, `"$item"` inside a fan-out) — references are the only interpolation.
* `inputs` — wiring from prior outcomes: `"envelope"`, `""`, `"."`, `"$flags"`.
* `when` — optional gate: `{step: classify, equals: update}` or `{step: extract, has: shifts}`. Presence / enum equality only.
* `map_over` — optional fan-out: one child per item of the referenced list (e.g. `envelope.files`).
* `on_fail` — `stop` (fail the run — the default) or `flag` (record a flag and keep going).
* `outcome` — optional final message; `{step_id.field}` placeholders resolve from step outcomes: `outcome: {message: "Done — {create.url}"}`.
### Files in the envelope
[Section titled “Files in the envelope”](#files-in-the-envelope)
An envelope can carry **file ids** — declare them as plain `type: string` fields in `envelope_schema` and wire them into steps like any other value (`params: {schedule_file: "$envelope.schedule_file"}`). When the target is a code tool whose parameter is declared `type: file`, the platform resolves the id and hands the tool the actual file content at execution time — the same injection agents rely on in chat. Any file uploaded to the organization works (chat uploads included); get an id from `list_files` / `search_files`, or upload one with `create_upload_url`. Ids from another organization do not resolve and fail the step.
For **agent** steps there are two ways to give the agent the file itself:
* `attachments` on the agent block (e.g. `attachments: ["$envelope.timereport_file"]`) attaches the resolved file(s) to the bounded turn exactly like a chat attachment: images (scans, photos) are shown to the agent inline so it can read them visually; other files are announced in the task and read via `read_file`. An attachment that does not resolve fails the step rather than letting the agent run blind. When the step runs as a named agent (so it has a mirror chat), the attached files also appear in that chat’s Files panel.
* `read_file` inside an agent step resolves any org file id (not just the step’s attachments), so an agent step handed a file id through wired inputs can always open it on demand.
## Block kinds
[Section titled “Block kinds”](#block-kinds)
* **action** — a built-in platform operation (deterministic code): `block: {action: core.create_idempotent}` with `params: {tool: create_draft, idempotency_key: $envelope.external_id, ...}`.
* **code\_tool** — one of your org’s custom code tools, called with wired args: `block: {code_tool: extract-shifts}`. Reference the tool by its slug (the hyphenated identifier from `list_code_tools`).
* **llm** — a single tool-less structured model call: `block: {llm: {instruction: "Classify the request...", output_schema: {...}}}`.
* **prompt** — same as `llm`, but the instruction text comes from an org prompt: `block: {prompt: {ref: classify-request, output_schema: {...}}}`. The step still owns `output_schema`.
* **agent** — a bounded agent turn, the only kind that can use tools: `block: {agent: {ref: generic, tools: [search_customer], instruction: "...", output_schema: {...}, max_turns: 8, attachments: ["$envelope.scan"]}}`. `ref: generic` is an anonymous worker: it gets only the step’s `tools:` list and the platform’s default process model. To delegate the step to one of YOUR agents instead, set `ref` to the agent’s name (from `list_agents`) — it then runs as itself, with its own model and its own configured tools (the step’s `tools:` list is not needed). Either way the step’s instruction + wired inputs form the task, the loop is capped by `max_turns`, and the agent delivers the result itself by calling a `complete_step` tool whose arguments must match the step’s `output_schema`. Optional `attachments` (file-id values or refs) attach files to the turn like chat attachments — images are shown to the agent inline (see “Files in the envelope”).
* **process** — run another process as a child step: `block: {process: other-process}`. The step’s `params` ARE the child’s envelope — its keys must match the child process’s `envelope_schema` directly (`params: {topic: "$envelope.topic"}`, NOT wrapped in an `envelope:` key).
### Tool references
[Section titled “Tool references”](#tool-references)
Agent steps’ `tools:` lists and action steps’ `params.tool` accept slugs from the **org tool catalog** — browse it with `list_org_tools(query=?)`. Tools from an integration (MCP server) are catalogued under a prefixed slug `{prefix}_{tool}`: an ERP server’s `create_draft` appears as `erp_create_draft`. Look the exact slug up rather than guessing — the validator rejects anything not in the catalog (and suggests close matches). Custom code tools are the exception: a `code_tool` block references the hyphenated slug from `list_code_tools`. In action params (`params.tool`, `params.tools.*`, `map_dispatch` `variants`) a custom code tool may be named by either that hyphenated slug or its catalog name (source `custom` in `list_org_tools`). Every tool reference is a plain slug string — never a block object.
## Actions catalog
[Section titled “Actions catalog”](#actions-catalog)
The `action` block kind runs one of these built-in `core.*` operations. Every tool call inside an action is schema-gated, retried on transient failures, and repaired by a bounded one-shot agent on payload mismatch — the happy path involves no model calls.
* `core.call_tool` — one deterministic tool call. `params: {tool, args}`.
* `core.create_idempotent` — create through a tool; the `idempotency_key` (usually an envelope ref) guarantees a re-run never duplicates. `capture` lifts result fields onto the step outcome; `protected` registers payload fields no later update may re-send. `params: {tool, payload, idempotency_key?, capture?, protected?}`.
* `core.update_complement` — follow-up update restricted to what the create couldn’t set: `from` is the create step’s outcome (ref), `echo_exact` copies fields from it verbatim, protected fields are refused. `params: {tool, from, payload?, echo_exact?, require?, args?}`.
* `core.verify_fields` — fetch and assert: `expect` (field → exact value), `require_not_null` (fields present and non-null), `count` (`{field, equals}`), optional single-shot `repair: {tool, args}` then re-assert. `params: {tool, args?, expect?, require_not_null?, count?, repair?}`.
* `core.upload_attach` — ordered sequence create URL → push bytes → attach; the byte push between the two tool calls is automatic, with fresh-URL retry. `params: {tools: {create_url, attach}, file, create_url_args?, attach_args?, url_field?, upload_ref_field?, retry_fresh_url?}` — `file` is a ref to an item with `file_id` and `name`.
* `core.replace_collection` — delete-all + one bulk add + count assertion. `params: {tools: {delete, add}, items, items_field?, args?, delete_args?, add_args?, expected_count?, count_field?}`.
* `core.map_dispatch` — dispatch each item to a tool picked by a discriminator field; the item itself is passed under `args_field` automatically; unknown discriminator values flag the item. `params: {items, discriminator, variants, args_field?, args?}`. Each `variants` value is a plain tool-slug STRING (`"docx": "extract-shifts"`), never a block object like `{code_tool: …}`.
Validation errors report each action’s exact params schema when a step’s params don’t match — `validate_process_definition` is the authoritative reference for the current contracts.
## Lifecycle: draft, test, deploy
[Section titled “Lifecycle: draft, test, deploy”](#lifecycle-draft-test-deploy)
1. `create_process(name, title, description=?)` — creates the empty shell. `name` is the permanent lowercase-hyphen slug; `title` is the display name. No definition exists yet.
2. Write the definition and dry-run it with `validate_process_definition(definition)` — returns `{ok, errors, warnings}`. Fix errors and re-run until `ok` is true.
3. `update_process_definition(process, definition)` — saves it as a new **draft** revision (returns its version). Never deploys.
4. `test_process_run(process, envelope, revision_version=?)` — runs a revision end-to-end; pass the draft’s version to test it before anyone deploys.
5. `deploy_process_revision(process, version=? | revision_id=?)` — makes that revision LIVE: it is re-validated against the current catalog, the previously deployed revision is archived, and every future run uses the new one immediately. Always test the draft first. (The same deploy is available from the CLI as `agentdepot process deploy`. The web app’s Processes pages are read-only — there is no deploy button there.)
A process is not live until a revision is deployed: a freshly created shell, or a definition that was drafted and tested but never deployed, never runs. Deploying is the step that turns your work on.
Revisions have status draft / deployed / archived. Inspect them with `list_process_revisions(process)` and `get_process_revision(process, version=N)`; `get_process(process)` returns the currently deployed definition, and `list_processes()` is the org-wide starting point.
## Runs
[Section titled “Runs”](#runs)
A run’s status is `running`, `completed`, `flagged` (finished, but steps raised flags worth a look), `failed`, or `cancelled`. To watch one:
* `list_process_runs(process=?, status=?)` — recent runs, newest first.
* `get_process_run(run_id)` — the full picture: every step with its status, timing, error and outcome, plus the run’s flags, trigger envelope, and `revision_version`.
* `get_process_run_calls(run_id, step_id=?, include_messages=?)` — the model calls behind the steps, merged into one timeline; set `include_messages=true` to see the actual (truncated) request/response.
* `restart_process_run(run_id)` — re-runs a **finished** run’s envelope as a brand-new run on the current deployed revision.
* `cancel_process_run(run_id, reason=?)` — stops a run that is still running.
## Troubleshooting a run
[Section titled “Troubleshooting a run”](#troubleshooting-a-run)
1. `get_process_run` — find the first failed step; read its `error` and the outcomes of the steps before it.
2. `get_process_run_calls` scoped to that `step_id` with `include_messages=true` — see exactly what the model was asked and answered. `repair` entries mean a tool call’s payload failed validation; their verdict shows whether the automatic fix was accepted.
3. Check the run’s **flags** — non-blocking issues steps recorded while proceeding (`on_fail: flag`); they explain a `flagged` run.
4. Fetch exactly what ran: `get_process_revision(process, version=)` — the live definition may have moved on since.
5. Fix the definition → `update_process_definition` (new draft) → `test_process_run` pinned to the draft → `deploy_process_revision` to make the fix live.
# Structured output fields
> Field definitions for giving a prompt an extraction schema.
`create_prompt` / `update_prompt` take an optional `fields`: a list of field defs. When `fields` is set, the prompt runs as **structured extraction** instead of free-text generation — `run_prompt` / `test_prompt` return typed data, and `text` (if given) becomes the extraction instructions. Each field is an object with at least `name` and `field_type`. Valid `field_type`:
* `text`, `date`, `datetime`, `yes_no`, `whole_number`, `money`
* `choice` — also requires a `choices` list of allowed values.
Example:
```plaintext
[
{"name": "invoice_total", "field_type": "money"},
{"name": "due_date", "field_type": "date"},
{"name": "priority", "field_type": "choice", "choices": ["low", "high"]}
]
```
Passing `fields` to `update_prompt` creates a new revision. `post_processing_instructions` (also on `create_prompt`/`update_prompt`) runs a second refinement call over the extracted data — useful for cleanup or cross-field derivation that needs the full first-pass result in context.
# Testing before you publish
> Test agents and building blocks before you publish them.
You can validate changes without making them live to your org.
**Run a chat on an unpublished agent revision.** Instruction edits land on a draft (see `concepts`). To try the draft end-to-end before `deploy_agent`:
* `start_chat(agent, message, use_draft=true)` — pins the chat to the agent’s current draft revision.
* `start_chat(agent, message, revision_version=N)` — pins a specific past version (re-test an old instruction).
* Omit both → the chat runs the published (active) revision (the default).
The pin holds for the whole chat. `get_chat` reports `revision_version` (and `pinned_revision_id`) so you can confirm which revision ran — null means it followed the published one. In the web UI these chats show a “Running draft v{n}” badge. Iterate on the draft (`update_agent`) → test → `deploy_agent` when happy.
**Test building blocks in isolation** (no chat, no agent wiring):
* `test_code_tool(tool, args)` — runs the code tool’s current source in a sandbox and returns its `status`, `result`, `logs`, and any `error`.
* `test_prompt(prompt, variables, revision_version=?)` — renders the template and runs it against its LLM; returns `status`, `result` (the model output), `error`, `duration_ms`, and token `usage`. If the tested revision has an extraction schema (`fields`, see `prompt-fields`), pass `input_text` or `input_url` instead of (or alongside) `variables` — `result` is then the structured data.
Each of these records a run, so it shows up on the building block’s Runs page. Prompts are revision-versioned: pass `revision_version` to test an unpublished revision; omit it for the latest. (Code tools have no revisions — the test runs the single saved source.) These all require an admin/owner role.
To test a **skill**, mount it on an agent and run a draft-revision chat — there is no isolated skill runner.
# MCP Server Reference
> Tools exposed by the AgentDepot MCP server.
The AgentDepot MCP server (mounted at `/mcp`) exposes the following tools, usable from any MCP host (Claude Desktop, Cowork, etc.). Authenticate with an `agd_*` API token or the OAuth flow.
* [Agents](/docs/reference/mcp/agents) — 5 tools
* [Building Blocks](/docs/reference/mcp/building-blocks) — 15 tools
* [Chats](/docs/reference/mcp/chats) — 5 tools
* [Documentation](/docs/reference/mcp/documentation) — 1 tool
* [Files](/docs/reference/mcp/files) — 4 tools
* [Integrations](/docs/reference/mcp/integrations) — 3 tools
* [Organizations](/docs/reference/mcp/orgs) — 1 tool
* [Skills](/docs/reference/mcp/skills) — 2 tools
* [Teams](/docs/reference/mcp/teams) — 6 tools
* [Testing](/docs/reference/mcp/testing) — 2 tools
## Resources
[Section titled “Resources”](#resources)
The server also exposes these read-only MCP resources:
| URI | Name | Description |
| ---------------------------------- | ------------------------------------ | ------------------------------------------------------ |
| `agentdepot://docs` | AgentDepot documentation index | Index of available AgentDepot documentation topics. |
| `agentdepot://docs/agent-mentions` | Mention tokens in agent instructions | AgentDepot docs: Mention tokens in agent instructions. |
| `agentdepot://docs/build-a-flow` | Setting up a full flow | AgentDepot docs: Setting up a full flow. |
| `agentdepot://docs/chat-lifecycle` | Chat lifecycle & polling | AgentDepot docs: Chat lifecycle & polling. |
| `agentdepot://docs/claude-desktop` | Use with Claude Desktop | AgentDepot docs: Use with Claude Desktop. |
| `agentdepot://docs/concepts` | Core concepts | AgentDepot docs: Core concepts. |
| `agentdepot://docs/files` | Files | AgentDepot docs: Files. |
| `agentdepot://docs/overview` | What AgentDepot is | AgentDepot docs: What AgentDepot is. |
| `agentdepot://docs/processes` | Processes | AgentDepot docs: Processes. |
| `agentdepot://docs/prompt-fields` | Structured output fields | AgentDepot docs: Structured output fields. |
| `agentdepot://docs/testing` | Testing before you publish | AgentDepot docs: Testing before you publish. |
# Agents
> MCP server tools for agents.
### `create_agent`
[Section titled “create\_agent”](#create_agent)
Create a new agent.
`instruction` is the agent’s task definition (becomes its v1 draft revision — call `deploy_agent` to make it active). `allowed_tools` is a list of tool scope strings or slugs; `provider`/`model` pick the LLM. `per_chat_cost_limit_usd` caps spend per chat (auto-pauses the agent when exceeded); defaults to 1.00 if omitted. `tags` is a list of tag names to attach to the agent (created if they don’t exist yet).
**Mention tokens:** Instructions can reference org resources inline using `/type[key]` syntax (e.g. `/prompt[summarize]`, `/agent[researcher]`). The platform resolves them at run time and appends a “Referenced Resources” block to the agent’s system prompt. Read the `agent-mentions` documentation topic for the full list of supported types and their keys.
Every `allowed_tools` entry must resolve in this org — a scope grant, or a tool slug from `list_org_tools` / `list_code_tools`.
| Parameter | Type | Required | Description |
| --------------------------- | ---------- | -------- | ----------- |
| allowed\_tools | `string[]` | no | |
| description | `string` | no | |
| instruction | `string` | no | |
| model | `string` | no | |
| name | `string` | yes | |
| org | `string` | no | |
| per\_chat\_cost\_limit\_usd | `number` | no | |
| provider | `string` | no | |
| reasoning\_effort | `string` | no | |
| system\_prompt | `string` | no | |
| tags | `string[]` | no | |
### `deploy_agent`
[Section titled “deploy\_agent”](#deploy_agent)
Deploy an agent’s draft instruction, making it the active revision.
| Parameter | Type | Required | Description |
| --------- | -------- | -------- | ----------- |
| agent | `string` | yes | |
| org | `string` | no | |
### `get_agent`
[Section titled “get\_agent”](#get_agent)
Get full detail for one agent (by id or slug), including its active instruction and any undeployed draft.
| Parameter | Type | Required | Description |
| --------- | -------- | -------- | ----------- |
| agent | `string` | yes | |
| org | `string` | no | |
### `list_agents`
[Section titled “list\_agents”](#list_agents)
List the agents in an organization.
Paged: the response carries `total`, `has_more` and `next_offset` — pass `next_offset` back as `offset` to walk the rest.
| Parameter | Type | Required | Description |
| --------- | --------- | -------- | ---------------------------------------------------------- |
| limit | `integer` | no | Max rows to return (1–200). |
| offset | `integer` | no | Rows to skip — pass the previous response’s `next_offset`. |
| org | `string` | no | |
### `update_agent`
[Section titled “update\_agent”](#update_agent)
Update an agent (by id or slug). Partial: only the fields you pass are changed; omit the rest to leave them untouched.
`instruction` edits land on the agent’s draft revision (NOT live until you call `deploy_agent`); other fields apply immediately. `execution_mode` is auto/manual/paused; `status` is active/archived. `tags` replaces the agent’s current tag set (pass an empty list to clear all tags).
**Mention tokens:** Use `/type[key]` tokens in `instruction` to reference org resources inline (e.g. `/prompt[slug]`, `/skill[slug]`, `/agent[slug]`, `/tool[name]`, `/connected-tool[slug]`). The platform resolves them at run time. See the `agent-mentions` documentation topic for details.
To save tokens the response OMITS the full instruction texts (it returns their lengths + revision ids + `has_undeployed_draft`); call `get_agent` for the full text.
Every `allowed_tools` entry must resolve in this org (a scope grant, or a slug from `list_org_tools` / `list_code_tools`), and every `mounted_skills` entry must be an existing skill slug (`list_skills`).
| Parameter | Type | Required | Description |
| --------------------------- | ---------- | -------- | ----------- |
| agent | `string` | yes | |
| allowed\_tools | `string[]` | no | |
| description | `string` | no | |
| execution\_mode | `string` | no | |
| instruction | `string` | no | |
| model | `string` | no | |
| mounted\_skills | `string[]` | no | |
| name | `string` | no | |
| org | `string` | no | |
| per\_chat\_cost\_limit\_usd | `number` | no | |
| provider | `string` | no | |
| reasoning\_effort | `string` | no | |
| status | `string` | no | |
| system\_prompt | `string` | no | |
| tags | `string[]` | no | |
# Building Blocks
> MCP server tools for building blocks.
### `create_code_tool`
[Section titled “create\_code\_tool”](#create_code_tool)
Create a code tool from Python `source_code`. The tool’s parameters and description are parsed from the code’s manifest (a parse error is returned as an error). `tags` attaches tag names to the new tool.
**File parameters:** Annotate a parameter as `bytes` to accept file\_id UUID strings. The platform downloads the file content from S3 before invoking the tool, so the function receives raw `bytes`. Example: `def run(data: bytes) -> dict:` — callers pass `{"data": ""}`.
| Parameter | Type | Required | Description |
| ------------ | ---------- | -------- | ----------- |
| env\_vars | `string[]` | no | |
| name | `string` | yes | |
| org | `string` | no | |
| source\_code | `string` | yes | |
| tags | `string[]` | no | |
### `create_prompt`
[Section titled “create\_prompt”](#create_prompt)
Create a prompt template. `text` may contain `{{variable}}` placeholders and is optional when `fields` alone defines a pure extraction schema.
`fields` is an optional list of field defs, each {name, field\_type, …}; valid field\_type: text, date, datetime, yes\_no, whole\_number, money, choice, object (choice needs a `choices` list). Any field can also set `is_list: true` to extract multiple values of that type instead of one. `object` fields nest a sub-schema under `fields` (a list of field defs, same shape, recursively) to extract a structured record; combine `field_type: "object"` with `is_list: true` to extract a list of records. When `fields` is set, the prompt runs as **structured extraction** instead of free-text generation — `run_prompt`/`test_prompt` return typed data, and `text` (if given) becomes the extraction instructions. `post_processing_instructions` (optional) runs a second refinement call over the extracted data.
`reasoning_effort` sets the LLM reasoning level (e.g. `"low"`, `"medium"`, `"high"`). `tags` attaches tag names to the new template.
| Parameter | Type | Required | Description |
| ------------------------------ | ---------- | -------- | ----------- |
| description | `string` | no | |
| fields | `object[]` | no | |
| model | `string` | no | |
| name | `string` | yes | |
| org | `string` | no | |
| post\_processing\_instructions | `string` | no | |
| provider | `string` | no | |
| reasoning\_effort | `string` | no | |
| tags | `string[]` | no | |
| text | `string` | no | |
### `create_skill`
[Section titled “create\_skill”](#create_skill)
Create a skill (a bundle of instructions + a tool subset + reference material). Created immediately active. `description` is a one-line summary kept in-context for agents that mount it. `tags` attaches tag names to the new skill.
Every entry in `tool_slugs` must resolve in this org — call `list_org_tools` (or `list_code_tools`) for the valid slugs.
| Parameter | Type | Required | Description |
| ------------------- | ---------- | -------- | ----------- |
| description | `string` | no | |
| instructions | `string` | yes | |
| name | `string` | yes | |
| org | `string` | no | |
| reference\_material | `string` | no | |
| tags | `string[]` | no | |
| tool\_slugs | `string[]` | no | |
### `get_code_tool`
[Section titled “get\_code\_tool”](#get_code_tool)
Get a code tool (by id or exact name), including its source code.
| Parameter | Type | Required | Description |
| --------- | -------- | -------- | ----------- |
| org | `string` | no | |
| tool | `string` | yes | |
### `get_knowledge_base`
[Section titled “get\_knowledge\_base”](#get_knowledge_base)
Get a knowledge base (by id or slug), including its embedding model.
| Parameter | Type | Required | Description |
| --------------- | -------- | -------- | ----------- |
| knowledge\_base | `string` | yes | |
| org | `string` | no | |
### `get_prompt`
[Section titled “get\_prompt”](#get_prompt)
Get a prompt template (by id or slug), including its active text.
| Parameter | Type | Required | Description |
| --------- | -------- | -------- | ----------- |
| org | `string` | no | |
| prompt | `string` | yes | |
### `get_skill`
[Section titled “get\_skill”](#get_skill)
Get a skill (by id or slug), including its active instructions and tools.
| Parameter | Type | Required | Description |
| --------- | -------- | -------- | ----------- |
| org | `string` | no | |
| skill | `string` | yes | |
### `list_code_tools`
[Section titled “list\_code\_tools”](#list_code_tools)
List the org’s code tools (custom Python tools).
| Parameter | Type | Required | Description |
| --------- | -------- | -------- | ----------- |
| org | `string` | no | |
### `list_knowledge_bases`
[Section titled “list\_knowledge\_bases”](#list_knowledge_bases)
List the org’s knowledge bases, with source/chunk counts.
| Parameter | Type | Required | Description |
| --------- | -------- | -------- | ----------- |
| org | `string` | no | |
### `list_prompts`
[Section titled “list\_prompts”](#list_prompts)
List the org’s prompt templates.
Paged: the response carries `total`, `has_more` and `next_offset` — pass `next_offset` back as `offset` to walk the rest.
| Parameter | Type | Required | Description |
| --------- | --------- | -------- | ---------------------------------------------------------- |
| limit | `integer` | no | Max rows to return (1–200). |
| offset | `integer` | no | Rows to skip — pass the previous response’s `next_offset`. |
| org | `string` | no | |
### `list_skills`
[Section titled “list\_skills”](#list_skills)
List the org’s skills.
Paged: the response carries `total`, `has_more` and `next_offset` — pass `next_offset` back as `offset` to walk the rest.
| Parameter | Type | Required | Description |
| --------- | --------- | -------- | ---------------------------------------------------------- |
| limit | `integer` | no | Max rows to return (1–200). |
| offset | `integer` | no | Rows to skip — pass the previous response’s `next_offset`. |
| org | `string` | no | |
### `search_knowledge_base`
[Section titled “search\_knowledge\_base”](#search_knowledge_base)
Search the org’s knowledge bases for relevant content chunks.
This is the same retrieval the in-chat `search_knowledge` agent tool uses: it matches both meaning and exact wording, so a single distinctive term works as well as a full question. Pass `knowledge_base` (an id or slug from `list_knowledge_bases`) to restrict the search to one base; omit it to search all of them.
| Parameter | Type | Required | Description |
| --------------- | --------- | -------- | ---------------- |
| knowledge\_base | `string` | no | |
| limit | `integer` | no | Max hits (1–25). |
| org | `string` | no | |
| query | `string` | yes | |
### `update_code_tool`
[Section titled “update\_code\_tool”](#update_code_tool)
Update a code tool (by id or exact name). Only the fields you pass are changed. `tags` replaces the tool’s current tag set (pass an empty list to clear all tags).
**File parameters:** Annotate a parameter as `bytes` to accept file\_id UUID strings. The platform downloads the file content from S3 before invoking the tool, so the function receives raw `bytes`. Example: `def run(data: bytes) -> dict:` — callers pass `{"data": ""}`.
| Parameter | Type | Required | Description |
| ------------ | ---------- | -------- | ----------- |
| env\_vars | `string[]` | no | |
| is\_enabled | `boolean` | no | |
| name | `string` | no | |
| org | `string` | no | |
| source\_code | `string` | no | |
| tags | `string[]` | no | |
| tool | `string` | yes | |
### `update_prompt`
[Section titled “update\_prompt”](#update_prompt)
Update a prompt template (by id or slug). Passing `text`, `fields`, or `post_processing_instructions` creates a new revision (versioned together). Only the fields you pass are changed. `fields` (see `create_prompt` for the shape) turns the prompt into — or updates — structured extraction; valid field\_type: text, date, datetime, yes\_no, whole\_number, money, choice, object. Any field can set `is_list: true` to extract multiple values; `object` fields nest a sub-schema under `fields` for a structured record, and `object` + `is_list: true` extracts a list of records. `reasoning_effort` sets the LLM reasoning level. `tags` replaces the template’s current tag set (pass an empty list to clear all tags).
| Parameter | Type | Required | Description |
| ------------------------------ | ---------- | -------- | ----------- |
| description | `string` | no | |
| fields | `object[]` | no | |
| model | `string` | no | |
| name | `string` | no | |
| org | `string` | no | |
| post\_processing\_instructions | `string` | no | |
| prompt | `string` | yes | |
| provider | `string` | no | |
| reasoning\_effort | `string` | no | |
| tags | `string[]` | no | |
| text | `string` | no | |
### `update_skill`
[Section titled “update\_skill”](#update_skill)
Update a skill (by id or slug) and deploy the change so it takes effect (skills are live immediately, like on create). Only the fields you pass are changed. `tags` replaces the skill’s current tag set (pass an empty list to clear all tags).
Every entry in `tool_slugs` must resolve in this org — call `list_org_tools` (or `list_code_tools`) for the valid slugs.
| Parameter | Type | Required | Description |
| ------------------- | ---------- | -------- | ----------- |
| description | `string` | no | |
| instructions | `string` | no | |
| name | `string` | no | |
| org | `string` | no | |
| reference\_material | `string` | no | |
| skill | `string` | yes | |
| tags | `string[]` | no | |
| tool\_slugs | `string[]` | no | |
# Chats
> MCP server tools for chats.
### `get_chat`
[Section titled “get\_chat”](#get_chat)
Get a chat’s current state — status, full message history, recorded outcomes, cost, and any pending human-input request. Poll this until `status` is no longer “running”.
The `messages` history holds only user/assistant text turns. Human input requests and the answers they got are NOT messages — they come back in `hitl_requests` (every request for the chat, with its `response_text`), while `pending_hitl_request` holds only the one still waiting. When the request offered `ui` (buttons/choice/text/info — the same shape `request_human_input` accepts), it’s included on both so you can see exactly what a human would be asked to pick from before calling `respond_to_hitl`.
When the agent recorded an outcome, its summary IS the answer, and the last assistant message carries it (tagged `kind: "outcome_summary"`) even if the model’s own closing turn was empty — so `messages` alone is enough to read the result. `outcomes` remains the graded record.
`stop_reason` says why a chat is no longer moving: “cost\_limit” (raise the agent’s per-chat budget and start again), “awaiting\_input” (a human must answer), or “no\_outcome” — the agent replied and stopped without calling `goal_complete`, so `outcomes` is empty and nothing was declared. It is idle, not running: stop polling and treat the result as unverified.
Pass `include_trace=true` to also get a `trace` array of the underlying events (tool calls + results with name/args/result preview), oldest first — useful to see *why* the agent did something or which tool failed.
| Parameter | Type | Required | Description |
| -------------- | --------- | -------- | ----------- |
| chat\_id | `string` | yes | |
| include\_trace | `boolean` | no | |
| org | `string` | no | |
### `list_chats`
[Section titled “list\_chats”](#list_chats)
List recent chats for an agent (by id or slug), newest first.
Paged: the response carries `total`, `has_more` and `next_offset` — pass `next_offset` back as `offset` to walk the rest.
| Parameter | Type | Required | Description |
| --------- | --------- | -------- | ---------------------------------------------------------- |
| agent | `string` | yes | |
| limit | `integer` | no | Max rows to return (1–200). |
| offset | `integer` | no | Rows to skip — pass the previous response’s `next_offset`. |
| org | `string` | no | |
### `respond_to_hitl`
[Section titled “respond\_to\_hitl”](#respond_to_hitl)
Answer a pending human-input request (from a paused chat) and resume the agent. Use `action` (“approve”/“reject”, or one of the request’s `ui` `buttons`) for approvals and button choices, `selection` for one of the `ui` `choice` options, `text` for a free-text answer. At least one is required.
When the request declared `buttons`/`choice` in its `ui` (see `get_chat`’s `pending_hitl_request.ui`), `action`/`selection` must be one of the offered options — a value that isn’t gets rejected with the valid options listed. Requests with no such `ui` (plain approvals, free-text questions) accept anything.
| Parameter | Type | Required | Description |
| ----------- | -------- | -------- | ----------- |
| action | `string` | no | |
| org | `string` | no | |
| request\_id | `string` | yes | |
| selection | `string` | no | |
| text | `string` | no | |
### `send_message`
[Section titled “send\_message”](#send_message)
Send a user message to an existing chat and dispatch the agent turn. A message to a paused chat resumes it. Runs asynchronously — poll `get_chat` for the result.
To attach files, first use `create_upload_url` to get presigned upload URLs, PUT your files to those URLs, then pass the returned `upload_id`s in `attachment_upload_ids`.
| Parameter | Type | Required | Description |
| ----------------------- | ---------- | -------- | ----------- |
| attachment\_upload\_ids | `string[]` | no | |
| chat\_id | `string` | yes | |
| message | `string` | yes | |
| org | `string` | no | |
### `start_chat`
[Section titled “start\_chat”](#start_chat)
Start a new chat with an agent (by id or slug) and send the first message. Returns the `chat_id`; the turn runs asynchronously — poll `get_chat` for the result.
By default the chat runs the agent’s **published** (active) revision. To test an unpublished instruction without deploying it, pass `use_draft=true` (pins the agent’s current draft revision) OR `revision_version=N` (pins a specific past version). The pin holds for the chat’s whole life. The two options are mutually exclusive.
Pass `sandbox_enabled=true` to run the chat in a Cloud Workspace — an isolated Linux sandbox with a real filesystem + network that persists across the conversation. Enable it for substantial coding, data, or file-heavy work; it only ever adds capability on top of the agent’s own sandbox setting.
To attach files, first use `create_upload_url` to get presigned upload URLs, PUT your files to those URLs, then pass the returned `upload_id`s in `attachment_upload_ids`.
| Parameter | Type | Required | Description |
| ----------------------- | ---------- | -------- | ----------- |
| agent | `string` | yes | |
| attachment\_upload\_ids | `string[]` | no | |
| message | `string` | yes | |
| org | `string` | no | |
| revision\_version | `integer` | no | |
| sandbox\_enabled | `boolean` | no | |
| title | `string` | no | |
| use\_draft | `boolean` | no | |
# Documentation
> MCP server tools for documentation.
### `read_documentation`
[Section titled “read\_documentation”](#read_documentation)
Read AgentDepot documentation (what the platform is and how to use it).
Call with no `topic` to get the index, then with a topic slug (e.g. “overview”, “build-a-flow”, “testing”, “processes”, “concepts”, “chat-lifecycle”, “files”, “prompt-fields”, “agent-mentions”) for that section. Use this to orient before setting up agents and flows.
| Parameter | Type | Required | Description |
| --------- | -------- | -------- | ----------- |
| topic | `string` | no | |
# Files
> MCP server tools for files.
### `create_upload_url`
[Section titled “create\_upload\_url”](#create_upload_url)
Create a presigned PUT URL for uploading a file.
Step 1 of attaching a local file to a chat. Returns a temporary upload URL that you can PUT file bytes to directly.
Usage: 1. Call this tool to get an upload URL 2. PUT the file bytes to the returned `upload_url` with headers: - `Content-Type: ` 3. Pass the returned `upload_id` to `start_chat` or `send_message` in the `attachment_upload_ids` parameter
The upload URL expires in 15 minutes. Max file size is 10 MB.
`filename` is reduced to a safe single path segment before it is used — directory components are dropped and the extension is preserved — so the stored name may differ from what you passed.
| Parameter | Type | Required | Description |
| ------------- | --------- | -------- | ----------- |
| content\_type | `string` | no | |
| filename | `string` | yes | |
| org | `string` | no | |
| size | `integer` | no | |
### `list_files`
[Section titled “list\_files”](#list_files)
List all files in a chat — both user uploads and agent-produced artifacts — as a unified file list.
`chat_id` is required. The returned objects each carry `id`, `kind` (`"upload"` or `"artifact"`), `type`, `name`, `mime_type`, `size_bytes`, `preview` (first 500 chars), and `created_at`.
| Parameter | Type | Required | Description |
| --------- | -------- | -------- | ----------- |
| chat\_id | `string` | yes | |
| org | `string` | no | |
### `read_file`
[Section titled “read\_file”](#read_file)
Read a file or artifact by id, returning its text content.
`file_id` may refer to a chat upload (File) or an agent-produced artifact (Artifact) — both are resolved transparently.
`mode` controls extraction behaviour:
* `"auto"` (default) — try text extraction; if the MIME type is not supported (e.g. `image/jpeg`), return metadata + a `note` instead of raising an error.
* `"text"` — force text extraction; raises an error if the file type is not extractable as text.
* `"visual"` — always return metadata + note without attempting extraction (useful when you know you have an image and just want the metadata).
The response always contains `id`, `name`, `mime_type`, and `size_bytes`. Successful extraction adds `content`; unsupported types add `note`.
| Parameter | Type | Required | Description |
| --------- | -------- | -------- | ----------- |
| file\_id | `string` | yes | |
| mode | `string` | no | |
| org | `string` | no | |
### `search_files`
[Section titled “search\_files”](#search_files)
Search files (uploads and artifacts) across the org.
All filters are optional; combine them to narrow the result set:
* `chat_id` — restrict to one chat’s files.
* `agent` — restrict to artifacts produced by one agent (id or slug). User uploads have no agent dimension, so `agent` searches artifacts only.
* `title_contains` — case-insensitive substring match on the filename or artifact title.
* `type` — `"file"` to search uploads only; an artifact type value (`"text"`, `"code"`, `"markdown"`, `"json"`) to search artifacts only.
* `limit` — max results (default 20, max 100).
Results are returned newest-first.
| Parameter | Type | Required | Description |
| --------------- | --------- | -------- | -------------------- |
| agent | `string` | no | |
| chat\_id | `string` | no | |
| limit | `integer` | no | Max results (1–100). |
| org | `string` | no | |
| title\_contains | `string` | no | |
| type | `string` | no | |
# Integrations
> MCP server tools for integrations.
### `disable_integration`
[Section titled “disable\_integration”](#disable_integration)
Disable an integration (by id or slug) so agents no longer see its tools — sets status to “inactive”. Requires ADMIN or OWNER role.
| Parameter | Type | Required | Description |
| ----------- | -------- | -------- | ----------- |
| integration | `string` | yes | |
| org | `string` | no | |
### `enable_integration`
[Section titled “enable\_integration”](#enable_integration)
Enable an integration (by id or slug) so its tools are exposed to agents — sets status to “active”. Requires ADMIN or OWNER role.
| Parameter | Type | Required | Description |
| ----------- | -------- | -------- | ----------- |
| integration | `string` | yes | |
| org | `string` | no | |
### `list_integrations`
[Section titled “list\_integrations”](#list_integrations)
List the org’s integrations / connections.
Each has `status` and an `enabled` bool (the web UI toggle). A disabled integration exposes NO tools to agents — so an agent whose `allowed_tools` references a disabled integration will run with none of those tools. Use `enable_integration` to turn one on. Connecting a brand-new integration still happens in the web UI (often needs interactive OAuth).
| Parameter | Type | Required | Description |
| --------- | -------- | -------- | ----------- |
| org | `string` | no | |
# Organizations
> MCP server tools for organizations.
### `list_orgs`
[Section titled “list\_orgs”](#list_orgs)
List the organizations you can act in.
Pass an org’s `slug` (or `id`) as the `org` argument to other tools. If you belong to exactly one org, `org` can be omitted everywhere.
*No parameters.*
# Skills
> MCP server tools for skills.
### `get_system_skill`
[Section titled “get\_system\_skill”](#get_system_skill)
Get a platform/system skill by slug, including full instructions.
Returns:
* `slug`, `name`, `description` — identity fields
* `version` — active revision number
* `tool_slugs` — MCP tool names the skill uses
* `instructions` — the full step-by-step procedure to follow
* `reference_material` — optional supplementary reference text
Reading `instructions` tells you exactly how to carry out the skill. All tools listed in `tool_slugs` are already exposed by the `agents`, `building_blocks`, and `chats` MCP modules — call them as directed by the instructions.
Raises a ToolError if the slug does not match any active system skill. Use `list_system_skills` to see available slugs.
| Parameter | Type | Required | Description |
| --------- | -------- | -------- | ----------- |
| slug | `string` | yes | |
### `list_system_skills`
[Section titled “list\_system\_skills”](#list_system_skills)
List all active platform/system skills available on this deployment.
System skills are global — they are not scoped to any org and are the same for every authenticated user. Each entry contains:
* `slug` — stable identifier, use with `get_system_skill`
* `description` — one-line summary
* `version` — current active revision number
* `tool_slugs` — MCP tool names the skill relies on
Call `get_system_skill(slug)` to retrieve the full `instructions` for a specific skill before executing it.
*No parameters.*
# Teams
> MCP server tools for teams.
### `create_team`
[Section titled “create\_team”](#create_team)
Create a new agent team.
The three `shared_*` fields form the team’s shared context, merged with each member agent’s own configuration at prompt-assembly time: `shared_instruction` is prepended to member instructions; `shared_allowed_tools` is a list of tool scope strings or slugs granted to all members; `shared_mounted_skills` is a list of skill slugs mounted on all members. Add agents to the team afterwards with `set_agent_team`. The slug is derived from `name` (deduped within the org).
Both lists are checked against the org: every `shared_allowed_tools` entry must resolve in the tool catalog (`list_org_tools`) and every `shared_mounted_skills` entry must be an existing skill slug (`list_skills`).
| Parameter | Type | Required | Description |
| ----------------------- | ---------- | -------- | ----------- |
| description | `string` | no | |
| name | `string` | yes | |
| org | `string` | no | |
| shared\_allowed\_tools | `string[]` | no | |
| shared\_instruction | `string` | no | |
| shared\_mounted\_skills | `string[]` | no | |
### `delete_team`
[Section titled “delete\_team”](#delete_team)
Delete a team (by id or slug). Member agents are NOT deleted — they become ungrouped and revert to their own configuration.
| Parameter | Type | Required | Description |
| --------- | -------- | -------- | ----------- |
| org | `string` | no | |
| team | `string` | yes | |
### `get_team`
[Section titled “get\_team”](#get_team)
Get full detail for one team (by id or slug): its shared context (shared instruction, allowed tools, mounted skills) and the agents that belong to it.
| Parameter | Type | Required | Description |
| --------- | -------- | -------- | ----------- |
| org | `string` | no | |
| team | `string` | yes | |
### `list_teams`
[Section titled “list\_teams”](#list_teams)
List the agent teams in an organization, ordered for display.
Each entry includes the team’s slug, name, description, and current member count. Call `get_team` for a team’s shared context and member list.
Paged: the response carries `total`, `has_more` and `next_offset` — pass `next_offset` back as `offset` to walk the rest.
| Parameter | Type | Required | Description |
| --------- | --------- | -------- | ---------------------------------------------------------- |
| limit | `integer` | no | Max rows to return (1–200). |
| offset | `integer` | no | Rows to skip — pass the previous response’s `next_offset`. |
| org | `string` | no | |
### `set_agent_team`
[Section titled “set\_agent\_team”](#set_agent_team)
Set (or clear) an agent’s team membership.
Pass `team` (id or slug) to move the agent onto that team — it then inherits the team’s shared context. Omit `team` (or pass an empty string) to remove the agent from any team, reverting it to its own configuration.
| Parameter | Type | Required | Description |
| --------- | -------- | -------- | ----------- |
| agent | `string` | yes | |
| org | `string` | no | |
| team | `string` | no | |
### `update_team`
[Section titled “update\_team”](#update_team)
Update a team (by id or slug). Partial: only the fields you pass are changed; omit the rest to leave them untouched.
Renaming (`name`) re-derives the slug. `shared_allowed_tools` and `shared_mounted_skills` REPLACE the current lists (pass an empty list to clear). Pass an empty string for `shared_instruction` to clear it. Changes apply immediately to every current member’s assembled prompt. Both lists are checked against the org before they are stored — see `create_team`.
| Parameter | Type | Required | Description |
| ----------------------- | ---------- | -------- | ----------- |
| description | `string` | no | |
| name | `string` | no | |
| org | `string` | no | |
| shared\_allowed\_tools | `string[]` | no | |
| shared\_instruction | `string` | no | |
| shared\_mounted\_skills | `string[]` | no | |
| team | `string` | yes | |
# Testing
> MCP server tools for testing.
### `test_code_tool`
[Section titled “test\_code\_tool”](#test_code_tool)
Run a code tool (by id or name) in isolation with the given `args` and return its result, logs, and any error — without wiring it into an agent. Runs the tool’s current saved source in a Docker sandbox. `args` are passed straight to the tool as keyword arguments.
**File arguments:** For parameters typed as `bytes` in the tool source, pass a file\_id UUID string as the value. The platform downloads the file content from S3 and delivers raw `bytes` to the tool function. Example: `{"data": ""}` for a tool with `def run(data: bytes)`. You may also pass an `upload_id` from `create_upload_url` (after PUTting the bytes) to test against a freshly-uploaded local file without first sending it through a chat.
`args` are checked against the tool’s `parameters_schema` before anything runs — a missing required argument or an unknown one fails immediately instead of starting a container.
| Parameter | Type | Required | Description |
| --------- | -------- | -------- | ----------- |
| args | `object` | no | |
| org | `string` | no | |
| tool | `string` | yes | |
### `test_prompt`
[Section titled “test\_prompt”](#test_prompt)
Test a prompt template (by id or slug). Behavior depends on whether the tested revision has an extraction schema (`fields`, see `create_prompt`):
* **Plain prompt** (no `fields`): renders `text` with `variables` and runs it against the configured LLM, returning the rendered text and the model’s free-text output.
* **Schema-bearing prompt** (`fields` set): runs structured extraction and returns typed data instead. Provide the material to extract from via `input_text` (raw text) or `input_url` (fetched and used as the input) — one of the two is required. `variables` still interpolates any `{{name}}` placeholders in the prompt’s instructions.
Every variable the tested revision declares must be supplied in `variables` — a missing one fails before the model is called, rather than sending the raw `{{placeholder}}` to it.
Pass `revision_version` to test a specific (e.g. unpublished) revision; omit it to use the latest.
`file_ids` is an optional list of ids to attach to the prompt as multimodal content — text documents become text blocks, images and scanned PDFs become image blocks. Each id may be a durable file\_id (a chat upload or artifact) OR an `upload_id` from `create_upload_url` (after you’ve PUT the bytes), so you can test against a freshly-uploaded local file without first sending it through a chat. Uploads are resolved only within the caller’s organization.
`file_mode` optionally overrides how attached files render into the LLM message: `auto` (default — text if extractable else image), `image`, `text`, or `both`. Omit to use the prompt template’s configured mode.
| Parameter | Type | Required | Description |
| ----------------- | ---------- | -------- | ----------- |
| file\_ids | `string[]` | no | |
| file\_mode | `string` | no | |
| input\_text | `string` | no | |
| input\_url | `string` | no | |
| org | `string` | no | |
| prompt | `string` | yes | |
| revision\_version | `integer` | no | |
| variables | `object` | no | |
# REST API Reference
> Public HTTP endpoints of the AgentDepot API.
The **AgentDepot API** (v0.1.0) exposes the following resource groups. All endpoints require an `Authorization: Bearer ` header (a web session JWT or an `agd_*` API token).
* [Admin](/docs/reference/rest/admin)
* [Admin Ai](/docs/reference/rest/admin-ai)
* [Admin Costs](/docs/reference/rest/admin-costs)
* [Agent Chats](/docs/reference/rest/agent-chats)
* [Agent Memories](/docs/reference/rest/agent-memories)
* [Agent Teams](/docs/reference/rest/agent-teams)
* [Agent Toolkit](/docs/reference/rest/agent-toolkit)
* [Agents](/docs/reference/rest/agents)
* [Artifacts](/docs/reference/rest/artifacts)
* [Authentication](/docs/reference/rest/auth)
* [Chat Files](/docs/reference/rest/chat-files)
* [Chats](/docs/reference/rest/chats)
* [Connections](/docs/reference/rest/connections)
* [Conversation Resources](/docs/reference/rest/conversation-resources)
* [Custom Tools](/docs/reference/rest/custom-tools)
* [Files](/docs/reference/rest/files)
* [Human-in-the-Loop](/docs/reference/rest/hitl)
* [Inbox](/docs/reference/rest/inbox)
* [Composio Integrations](/docs/reference/rest/integrations-composio)
* [Knowledge](/docs/reference/rest/knowledge)
* [Members](/docs/reference/rest/members)
* [Models](/docs/reference/rest/models)
* [Org Integrations](/docs/reference/rest/org-integrations)
* [Org Settings](/docs/reference/rest/org-settings)
* [Org Variables](/docs/reference/rest/org-variables)
* [Organizations](/docs/reference/rest/organizations)
* [Overview](/docs/reference/rest/overview)
* [Processes](/docs/reference/rest/processes)
* [Projects](/docs/reference/rest/projects)
* [Prompt Templates](/docs/reference/rest/prompt-templates)
* [Resources](/docs/reference/rest/resources)
* [Schedules](/docs/reference/rest/schedules)
* [Search](/docs/reference/rest/search)
* [Skills](/docs/reference/rest/skills)
* [Tags](/docs/reference/rest/tags)
* [API Tokens](/docs/reference/rest/tokens)
* [Tool Sources](/docs/reference/rest/tool-sources)
* [Usage](/docs/reference/rest/usage)
# Admin
> REST API reference for admin.
### GET `/api/admin/admins`
[Section titled “GET /api/admin/admins”](#get-apiadminadmins)
List Admins
List all platform admins, joined to user + adder info.
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ------------------------- |
| 200 | Successful Response | `PlatformAdminResponse[]` |
| 422 | Validation Error | `HTTPValidationError` |
### POST `/api/admin/admins`
[Section titled “POST /api/admin/admins”](#post-apiadminadmins)
Add Admin
Grant platform-admin access to an existing, already-registered user.
**Request body** (required)
| Field | Type | Required | Description |
| ----- | -------- | -------- | ----------- |
| email | `string` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ----------------------- |
| 201 | Successful Response | `PlatformAdminResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### DELETE `/api/admin/admins/{user_id}`
[Section titled “DELETE /api/admin/admins/{user\_id}”](#delete-apiadminadminsuser_id)
Remove Admin
Revoke platform-admin access. Guards: no self-removal, no removing the last admin.
**Parameters**
| Name | In | Type | Required | Description |
| -------- | ---- | --------------- | -------- | ----------- |
| user\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 204 | Successful Response | |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/admin/allowed-emails`
[Section titled “GET /api/admin/allowed-emails”](#get-apiadminallowed-emails)
List Allowed Emails
List all registration-allowlist entries.
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ------------------------ |
| 200 | Successful Response | `AllowedEmailResponse[]` |
| 422 | Validation Error | `HTTPValidationError` |
### POST `/api/admin/allowed-emails`
[Section titled “POST /api/admin/allowed-emails”](#post-apiadminallowed-emails)
Add Allowed Email
Add an entry to the registration allowlist.
**Request body** (required)
| Field | Type | Required | Description |
| ----- | -------- | -------- | ----------- |
| email | `string` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ---------------------- |
| 201 | Successful Response | `AllowedEmailResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### DELETE `/api/admin/allowed-emails/{allowed_email_id}`
[Section titled “DELETE /api/admin/allowed-emails/{allowed\_email\_id}”](#delete-apiadminallowed-emailsallowed_email_id)
Remove Allowed Email
Remove a registration-allowlist entry.
**Parameters**
| Name | In | Type | Required | Description |
| ------------------ | ---- | --------------- | -------- | ----------- |
| allowed\_email\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 204 | Successful Response | |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/admin/orgs`
[Section titled “GET /api/admin/orgs”](#get-apiadminorgs)
List Orgs
List/search all organizations, cross-tenant, with per-org member counts.
**Parameters**
| Name | In | Type | Required | Description |
| ------ | ----- | --------- | -------- | -------------------------------------------------- |
| limit | query | `integer` | no | |
| offset | query | `integer` | no | |
| q | query | `string` | no | Search org name/slug (substring, case-insensitive) |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `OrgListResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/admin/orgs/{org_id}`
[Section titled “GET /api/admin/orgs/{org\_id}”](#get-apiadminorgsorg_id)
Get Org
Org detail plus its member roster.
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `OrgDetailResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### POST `/api/admin/orgs/{org_id}/members`
[Section titled “POST /api/admin/orgs/{org\_id}/members”](#post-apiadminorgsorg_idmembers)
Add Org Member
Add an EXISTING, already-registered user to an org. Never creates users or sends invites.
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
**Request body** (required)
| Field | Type | Required | Description |
| ----- | -------- | -------- | ----------- |
| email | `string` | yes | |
| role | `string` | no | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 201 | Successful Response | `OrgMemberInfo` |
| 422 | Validation Error | `HTTPValidationError` |
### PATCH `/api/admin/orgs/{org_id}/members/{user_id}`
[Section titled “PATCH /api/admin/orgs/{org\_id}/members/{user\_id}”](#patch-apiadminorgsorg_idmembersuser_id)
Update Org Member Role
Change a member’s role. Refuses if it would leave the org with 0 owners.
**Parameters**
| Name | In | Type | Required | Description |
| -------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
| user\_id | path | `string (uuid)` | yes | |
**Request body** (required)
| Field | Type | Required | Description |
| ----- | -------- | -------- | ----------- |
| role | `string` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `OrgMemberInfo` |
| 422 | Validation Error | `HTTPValidationError` |
### DELETE `/api/admin/orgs/{org_id}/members/{user_id}`
[Section titled “DELETE /api/admin/orgs/{org\_id}/members/{user\_id}”](#delete-apiadminorgsorg_idmembersuser_id)
Remove Org Member
Remove a member from an org. Refuses to remove the last OWNER.
**Parameters**
| Name | In | Type | Required | Description |
| -------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
| user\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 204 | Successful Response | |
| 422 | Validation Error | `HTTPValidationError` |
### POST `/api/admin/orgs/{org_id}/suspend`
[Section titled “POST /api/admin/orgs/{org\_id}/suspend”](#post-apiadminorgsorg_idsuspend)
Suspend Org
Suspend an organization — blocks regular member access via `get_current_org`.
Idempotent: calling this on an already-suspended org is a no-op (keeps the original `suspended_at` timestamp, 200, no duplicate audit entry) rather than 409 — this is a “make it so” action, safe to double-click from the UI.
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ----------------------- |
| 200 | Successful Response | `OrgSuspensionResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### POST `/api/admin/orgs/{org_id}/unsuspend`
[Section titled “POST /api/admin/orgs/{org\_id}/unsuspend”](#post-apiadminorgsorg_idunsuspend)
Unsuspend Org
Lift a suspension. Idempotent no-op if the org isn’t currently suspended.
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ----------------------- |
| 200 | Successful Response | `OrgSuspensionResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/admin/orgs/{org_id}/usage`
[Section titled “GET /api/admin/orgs/{org\_id}/usage”](#get-apiadminorgsorg_idusage)
Get Org Usage
Usage summary for one org — same shape/service as the self-serve `/api/orgs/{org_id}/usage/summary` endpoint, just without membership gating.
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ----- | --------------- | -------- | ----------------------------------------------- |
| org\_id | path | `string (uuid)` | yes | |
| window | query | `string` | no | Counter/cost window: 24h, 7d, 30d (default 30d) |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ---------------------- |
| 200 | Successful Response | `UsageSummaryResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### POST `/api/admin/users/{user_id}/deactivate`
[Section titled “POST /api/admin/users/{user\_id}/deactivate”](#post-apiadminusersuser_iddeactivate)
Deactivate User
Disable a user’s account. Guard: no self-deactivate.
**Parameters**
| Name | In | Type | Required | Description |
| -------- | ---- | --------------- | -------- | ----------- |
| user\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `UserStatusResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### POST `/api/admin/users/{user_id}/reactivate`
[Section titled “POST /api/admin/users/{user\_id}/reactivate”](#post-apiadminusersuser_idreactivate)
Reactivate User
Re-enable a previously deactivated user’s account.
**Parameters**
| Name | In | Type | Required | Description |
| -------- | ---- | --------------- | -------- | ----------- |
| user\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `UserStatusResponse` |
| 422 | Validation Error | `HTTPValidationError` |
# Admin Ai
> REST API reference for admin ai.
### GET `/api/admin/ai-settings`
[Section titled “GET /api/admin/ai-settings”](#get-apiadminai-settings)
Get Platform Ai Settings
Current platform AI scalars. Null fields defer to the env defaults.
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ---------------------------- |
| 200 | Successful Response | `PlatformAISettingsResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### PATCH `/api/admin/ai-settings`
[Section titled “PATCH /api/admin/ai-settings”](#patch-apiadminai-settings)
Update Platform Ai Settings
Update platform AI scalars.
Values land in `platform_settings` and are re-read per run, so a change here reaches running workers within their catalog/settings TTL — no deploy.
The default model is checked against the catalog before it is stored: it is what every org without a default of its own runs on, so a typo’d or retired id here would silently break all of them at the next turn instead of here, now, with a list of the ids that would have worked.
**Request body** (required)
| Field | Type | Required | Description |
| -------------------------- | --------------------------- | -------- | ----------- |
| compaction\_enabled | `boolean` | no | |
| compaction\_threshold | `number` | no | |
| default\_model | `PlatformDefaultModelInput` | no | |
| default\_reasoning\_effort | `string` | no | |
| max\_reasoning\_effort | `string` | no | |
| thinking\_enabled | `boolean` | no | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ---------------------------- |
| 200 | Successful Response | `PlatformAISettingsResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/admin/models`
[Section titled “GET /api/admin/models”](#get-apiadminmodels)
List Catalog Models
Every catalog row, enabled or not, in display order.
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ----------------------------- |
| 200 | Successful Response | `ModelCatalogEntryResponse[]` |
| 422 | Validation Error | `HTTPValidationError` |
### POST `/api/admin/models`
[Section titled “POST /api/admin/models”](#post-apiadminmodels)
Create Catalog Model
Add a model. `key` must be unique — it’s what agents store.
**Request body** (required)
| Field | Type | Required | Description |
| ----------------------------- | -------------------- | -------- | ----------- |
| allowed\_efforts | `string[]` | no | |
| cache\_write\_price\_per\_1m | `number` \| `string` | no | |
| cached\_input\_price\_per\_1m | `number` \| `string` | no | |
| cost\_tier | `string` | no | |
| enabled | `boolean` | no | |
| input\_price\_per\_1m | `number` \| `string` | no | |
| key | `string` | yes | |
| kind | `string` | no | |
| label | `string` | yes | |
| max\_output\_tokens | `integer` | no | |
| output\_price\_per\_1m | `number` \| `string` | no | |
| provider | `string` | yes | |
| replacement\_model\_id | `string (uuid)` | no | |
| sort\_order | `integer` | no | |
| supports\_reasoning | `boolean` | no | |
| supports\_vision | `boolean` | no | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------------- |
| 201 | Successful Response | `ModelCatalogEntryResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### PATCH `/api/admin/models/{entry_id}`
[Section titled “PATCH /api/admin/models/{entry\_id}”](#patch-apiadminmodelsentry_id)
Update Catalog Model
Update a model. Switching `enabled` off takes effect platform-wide.
Runs already pinned to a disabled model are not rewritten: they resolve to `replacement_model_id` (or the platform default) lazily at dispatch.
**Parameters**
| Name | In | Type | Required | Description |
| --------- | ---- | --------------- | -------- | ----------- |
| entry\_id | path | `string (uuid)` | yes | |
**Request body** (required)
| Field | Type | Required | Description |
| ----------------------------- | -------------------- | -------- | ----------- |
| allowed\_efforts | `string[]` | no | |
| cache\_write\_price\_per\_1m | `number` \| `string` | no | |
| cached\_input\_price\_per\_1m | `number` \| `string` | no | |
| cost\_tier | `string` | no | |
| deprecated | `boolean` | no | |
| enabled | `boolean` | no | |
| input\_price\_per\_1m | `number` \| `string` | no | |
| kind | `string` | no | |
| label | `string` | no | |
| max\_output\_tokens | `integer` | no | |
| output\_price\_per\_1m | `number` \| `string` | no | |
| provider | `string` | no | |
| replacement\_model\_id | `string (uuid)` | no | |
| sort\_order | `integer` | no | |
| supports\_reasoning | `boolean` | no | |
| supports\_vision | `boolean` | no | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------------- |
| 200 | Successful Response | `ModelCatalogEntryResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### DELETE `/api/admin/models/{entry_id}`
[Section titled “DELETE /api/admin/models/{entry\_id}”](#delete-apiadminmodelsentry_id)
Delete Catalog Model
Remove a model from the catalog.
Prefer disabling: a deleted row loses its replacement pointer, so anything still pinned to the key falls all the way through to the platform default.
**Parameters**
| Name | In | Type | Required | Description |
| --------- | ---- | --------------- | -------- | ----------- |
| entry\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 204 | Successful Response | |
| 422 | Validation Error | `HTTPValidationError` |
### POST `/api/admin/models/{entry_id}/sync-price`
[Section titled “POST /api/admin/models/{entry\_id}/sync-price”](#post-apiadminmodelsentry_idsync-price)
Sync Catalog Model Price
Re-price one model from the community LiteLLM dataset.
A convenience for identifying prices, not a runtime dependency: runs bill from the catalog, and this is one way to fill it. Deliberate per-row action, so it *does* overwrite what’s there — the boot-time sweep is the one that only fills blanks, precisely so a hand-typed price survives it.
**Parameters**
| Name | In | Type | Required | Description |
| --------- | ---- | --------------- | -------- | ----------- |
| entry\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------------- |
| 200 | Successful Response | `ModelCatalogEntryResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/admin/orgs/{org_id}/ai-settings`
[Section titled “GET /api/admin/orgs/{org\_id}/ai-settings”](#get-apiadminorgsorg_idai-settings)
Get Org Ai Settings
One org’s runtime overrides, plus the platform values behind its nulls.
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ---------------------------- |
| 200 | Successful Response | `OrgRuntimeSettingsResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### PATCH `/api/admin/orgs/{org_id}/ai-settings`
[Section titled “PATCH /api/admin/orgs/{org\_id}/ai-settings”](#patch-apiadminorgsorg_idai-settings)
Update Org Ai Settings
Set (or clear) one org’s runtime overrides on its behalf.
Writes the same rows the org’s own settings page writes, so support flipping a single org and that org flipping itself are the same operation — and the platform tier stays where everyone else reads it.
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
**Request body** (required)
| Field | Type | Required | Description |
| --------------------- | --------- | -------- | ----------- |
| compaction\_enabled | `boolean` | no | |
| compaction\_threshold | `number` | no | |
| thinking\_enabled | `boolean` | no | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ---------------------------- |
| 200 | Successful Response | `OrgRuntimeSettingsResponse` |
| 422 | Validation Error | `HTTPValidationError` |
# Admin Costs
> REST API reference for admin costs.
### GET `/api/admin/cogs-rates`
[Section titled “GET /api/admin/cogs-rates”](#get-apiadmincogs-rates)
List Cogs Rates
Current plan + this month’s consumption for each flat-rate provider.
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `CogsRateResponse[]` |
| 422 | Validation Error | `HTTPValidationError` |
### PUT `/api/admin/cogs-rates/{metric}`
[Section titled “PUT /api/admin/cogs-rates/{metric}”](#put-apiadmincogs-ratesmetric)
Update Cogs Rate
Set a provider’s plan, then re-price the affected rollups.
`effective_from` defaults to the start of the current month so the change covers the month being billed. Anything already rolled up from that date forward is recomputed, since the hourly cron would only ever revisit its own trailing window.
**Parameters**
| Name | In | Type | Required | Description |
| ------ | ---- | -------- | -------- | ----------- |
| metric | path | `string` | yes | |
**Request body** (required)
| Field | Type | Required | Description |
| ------------------ | -------------------- | -------- | ----------- |
| billing\_mode | `string` | no | |
| effective\_from | `string (date)` | no | |
| included\_units | `integer` | no | |
| monthly\_fee\_usd | `number` \| `string` | no | |
| overage\_unit\_usd | `number` \| `string` | no | |
| plan | `string` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `CogsRateResponse` |
| 422 | Validation Error | `HTTPValidationError` |
# Agent Chats
> REST API reference for agent chats.
### GET `/api/orgs/{org_id}/agents/{agent_id}/chats/`
[Section titled “GET /api/orgs/{org\_id}/agents/{agent\_id}/chats/”](#get-apiorgsorg_idagentsagent_idchats)
List Chats
List chat conversations for an agent (no message content — summary only).
**Parameters**
| Name | In | Type | Required | Description |
| --------- | ----- | --------------- | -------- | ----------- |
| agent\_id | path | `string (uuid)` | yes | |
| limit | query | `integer` | no | |
| offset | query | `integer` | no | |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `ChatListResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### POST `/api/orgs/{org_id}/agents/{agent_id}/chats/`
[Section titled “POST /api/orgs/{org\_id}/agents/{agent\_id}/chats/”](#post-apiorgsorg_idagentsagent_idchats)
Create Chat
Create a new chat conversation with an agent.
**Parameters**
| Name | In | Type | Required | Description |
| --------- | ---- | --------------- | -------- | ----------- |
| agent\_id | path | `string (uuid)` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Request body** (required)
| Field | Type | Required | Description |
| ---------------- | --------- | -------- | ----------- |
| sandbox\_enabled | `boolean` | no | |
| title | `string` | no | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 201 | Successful Response | `ChatResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/agents/{agent_id}/chats/{chat_id}`
[Section titled “GET /api/orgs/{org\_id}/agents/{agent\_id}/chats/{chat\_id}”](#get-apiorgsorg_idagentsagent_idchatschat_id)
Get Chat
Get a chat conversation with all messages.
**Parameters**
| Name | In | Type | Required | Description |
| --------- | ---- | --------------- | -------- | ----------- |
| agent\_id | path | `string (uuid)` | yes | |
| chat\_id | path | `string (uuid)` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `ChatResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### PATCH `/api/orgs/{org_id}/agents/{agent_id}/chats/{chat_id}`
[Section titled “PATCH /api/orgs/{org\_id}/agents/{agent\_id}/chats/{chat\_id}”](#patch-apiorgsorg_idagentsagent_idchatschat_id)
Update Chat
Update a chat — title, archived state, and/or shared visibility.
At least one of `title`, `archived` or `shared` must be provided. `shared` (private↔shared visibility) is creator-only.
**Parameters**
| Name | In | Type | Required | Description |
| --------- | ---- | --------------- | -------- | ----------- |
| agent\_id | path | `string (uuid)` | yes | |
| chat\_id | path | `string (uuid)` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Request body** (required)
| Field | Type | Required | Description |
| -------- | --------- | -------- | ----------- |
| archived | `boolean` | no | |
| shared | `boolean` | no | |
| title | `string` | no | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `ChatResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### DELETE `/api/orgs/{org_id}/agents/{agent_id}/chats/{chat_id}`
[Section titled “DELETE /api/orgs/{org\_id}/agents/{agent\_id}/chats/{chat\_id}”](#delete-apiorgsorg_idagentsagent_idchatschat_id)
Delete Chat
Soft-delete a chat conversation.
**Parameters**
| Name | In | Type | Required | Description |
| --------- | ---- | --------------- | -------- | ----------- |
| agent\_id | path | `string (uuid)` | yes | |
| chat\_id | path | `string (uuid)` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 204 | Successful Response | |
| 422 | Validation Error | `HTTPValidationError` |
### POST `/api/orgs/{org_id}/agents/{agent_id}/chats/{chat_id}/messages`
[Section titled “POST /api/orgs/{org\_id}/agents/{agent\_id}/chats/{chat\_id}/messages”](#post-apiorgsorg_idagentsagent_idchatschat_idmessages)
Send Message
Send a user message and dispatch the agent turn to the worker.
Persists the user message immediately (for optimistic echo + sidebar bump), then dispatches a `CONVERSATION_TURN_REQUESTED` event to the worker. The worker owns LLM execution, assistant-message persistence, cost rollup, and title generation.
Returns 202 Accepted with the persisted user message id. Returns 503 if the worker dispatch fails (a silent 202 would leave the turn never running).
**Parameters**
| Name | In | Type | Required | Description |
| --------- | ---- | --------------- | -------- | ----------- |
| agent\_id | path | `string (uuid)` | yes | |
| chat\_id | path | `string (uuid)` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Request body** (required)
| Field | Type | Required | Description |
| ----------------- | ----------------- | -------- | ----------- |
| attachment\_ids | `string (uuid)[]` | no | |
| content | `string` | yes | |
| model | `string` | no | |
| provider | `string` | no | |
| reasoning\_effort | `string` | no | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 202 | Successful Response | `SendMessageResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### POST `/api/orgs/{org_id}/agents/{agent_id}/chats/{chat_id}/stop`
[Section titled “POST /api/orgs/{org\_id}/agents/{agent\_id}/chats/{chat\_id}/stop”](#post-apiorgsorg_idagentsagent_idchatschat_idstop)
Stop Chat
Stop the current generation run — keep the chat ACTIVE.
Flips `chat.status` from `RUNNING` to `ACTIVE` so the in-flight worker aborts at its next LLM step (`pre_llm_checks` raises `AssignmentCancelledError` whenever `chat.status != RUNNING`).
Unlike `/terminate` the chat is **not** closed: no `completed_at`, no `archived_at`, and no HITL resolution. The chat stays live and the user can immediately send another message.
Idempotent: if the chat is not RUNNING (already ACTIVE, PAUSED, or in a terminal state) 200 is returned without mutation — stopping a non-running chat is always a no-op.
**Parameters**
| Name | In | Type | Required | Description |
| --------- | ---- | --------------- | -------- | ----------- |
| agent\_id | path | `string (uuid)` | yes | |
| chat\_id | path | `string (uuid)` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ----------------------- |
| 200 | Successful Response | `TerminateChatResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### POST `/api/orgs/{org_id}/agents/{agent_id}/chats/{chat_id}/terminate`
[Section titled “POST /api/orgs/{org\_id}/agents/{agent\_id}/chats/{chat\_id}/terminate”](#post-apiorgsorg_idagentsagent_idchatschat_idterminate)
Terminate Chat
Terminate a chat — set status to ARCHIVED and resolve any pending HITL.
Flips `chat.status` to `ARCHIVED` (the user-closed terminal state) and sets `completed_at` to now. The ORM listener fires a `status_changed` realtime envelope so the frontend receives the update immediately.
Any pending HITL request for this chat is resolved to `cancelled` so the chat is not left awaiting human input.
Idempotent: if the chat is already in a terminal status (ERRORED, ARCHIVED, ABANDONED) 200 is returned without re-mutating.
Setting status away from RUNNING signals an in-flight runner to abort at its next LLM step (`pre_llm_checks` raises `AssignmentCancelledError`). No extra worker call is needed.
**Parameters**
| Name | In | Type | Required | Description |
| --------- | ---- | --------------- | -------- | ----------- |
| agent\_id | path | `string (uuid)` | yes | |
| chat\_id | path | `string (uuid)` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ----------------------- |
| 200 | Successful Response | `TerminateChatResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/agents/{agent_id}/chats/{chat_id}/timeline`
[Section titled “GET /api/orgs/{org\_id}/agents/{agent\_id}/chats/{chat\_id}/timeline”](#get-apiorgsorg_idagentsagent_idchatschat_idtimeline)
Get Conversation Timeline
Get the unified conversation-spine timeline for a chat.
Returns a newest-first list of events composed from:
1. All `agent_events` for this `chat_id` — regardless of whether each row has `assignment_id` set or NULL. This captures `agent_step` prose rows written by a chat-lane turn before or without span attribution, which the per-assignment endpoint misses.
2. Synthetic `user_message_received` events derived from `agent_chat_messages WHERE role='user'` for this chat. User messages are not on the event spine, but the frontend renders the whole conversation from this single feed, so user turns are synthesised here. `metadata.content` carries the message text; `metadata.attachments` carries any file attachments so the frontend can render file chips.
The merged list is sorted newest-first (same convention as `GET /assignments/{id}/timeline`) so the frontend `buildTurns` (which does `[...events].reverse()`) works unchanged.
Pagination: `limit` / `offset` are applied AFTER the merge-sort, so the total reflects the combined event + user-message count.
Requires membership in the organization and that the chat belongs to the given agent.
**Parameters**
| Name | In | Type | Required | Description |
| --------- | ----- | --------------- | -------- | -------------------- |
| agent\_id | path | `string (uuid)` | yes | |
| chat\_id | path | `string (uuid)` | yes | |
| limit | query | `integer` | no | Max events to return |
| offset | query | `integer` | no | Pagination offset |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ------------------------------ |
| 200 | Successful Response | `ConversationTimelineResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/agents/{agent_id}/chats/{chat_id}/toggles`
[Section titled “GET /api/orgs/{org\_id}/agents/{agent\_id}/chats/{chat\_id}/toggles”](#get-apiorgsorg_idagentsagent_idchatschat_idtoggles)
Get Chat Toggles
Get the available composer toggles for a chat with their current enabled state.
Always includes a `system:web` entry for the web-search bundle. Also includes one entry per ACTIVE Composio integration connected to this org.
The `enabled` field reflects whether the scope is currently active for the chat (i.e. is present in `enabled_scopes`).
Only Composio integrations are surfaced here — MCP-server and other integration types are not toggle-able via this surface.
**Parameters**
| Name | In | Type | Required | Description |
| --------- | ---- | --------------- | -------- | ----------- |
| agent\_id | path | `string (uuid)` | yes | |
| chat\_id | path | `string (uuid)` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `TogglesResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### PUT `/api/orgs/{org_id}/agents/{agent_id}/chats/{chat_id}/toggles`
[Section titled “PUT /api/orgs/{org\_id}/agents/{agent\_id}/chats/{chat\_id}/toggles”](#put-apiorgsorg_idagentsagent_idchatschat_idtoggles)
Update Chat Toggles
Update the composer toggle state for a chat.
Replaces `enabled_scopes` with the provided list. Every scope in the request body must be one of the allowed values for this chat (`system:web` or a `composio:` scope for an ACTIVE Composio integration in this org) — unknown scopes are rejected with 422.
Returns the updated toggle list (same shape as GET /{chat\_id}/toggles).
**Parameters**
| Name | In | Type | Required | Description |
| --------- | ---- | --------------- | -------- | ----------- |
| agent\_id | path | `string (uuid)` | yes | |
| chat\_id | path | `string (uuid)` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Request body** (required)
| Field | Type | Required | Description |
| --------------- | ---------- | -------- | ----------- |
| enabled\_scopes | `string[]` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `TogglesResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/agents/{agent_id}/chats/unified`
[Section titled “GET /api/orgs/{org\_id}/agents/{agent\_id}/chats/unified”](#get-apiorgsorg_idagentsagent_idchatsunified)
List Unified Sidebar
Unified sidebar list: conversations ordered by activity.
Phase 2 (chat-outcomes model): chatless assignment items are gone — every work unit is a chat.
Returns a keyset-paginated list of conversations for the agent sidebar.
When `archived=true`, only archived conversations are returned. The response includes `archived_count=0` on this branch.
When `archived=false` (default), only active (non-archived) conversations are returned. The response includes `archived_count` with the total number of archived conversations for this agent.
Keyset pagination: cursor encodes (activity\_at ISO, id) as base64. Use next\_cursor from the response to fetch the next page.
**Parameters**
| Name | In | Type | Required | Description |
| --------- | ----- | --------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| agent\_id | path | `string (uuid)` | yes | |
| archived | query | `boolean` | no | When true, return archived conversations only; when false (default), return active (non-archived) conversations and chatless assignments. |
| cursor | query | `string` | no | Opaque keyset cursor |
| limit | query | `integer` | no | |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ------------------------ |
| 200 | Successful Response | `UnifiedSidebarResponse` |
| 422 | Validation Error | `HTTPValidationError` |
# Agent Memories
> REST API reference for agent memories.
### GET `/api/orgs/{org_id}/agent-memories`
[Section titled “GET /api/orgs/{org\_id}/agent-memories”](#get-apiorgsorg_idagent-memories)
List Agent Memories
List agent memories, optionally filtered by agent.
**Parameters**
| Name | In | Type | Required | Description |
| --------- | ----- | --------------- | -------- | --------------- |
| agent\_id | query | `string (uuid)` | no | Filter by agent |
| limit | query | `integer` | no | |
| offset | query | `integer` | no | |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ------------------------- |
| 200 | Successful Response | `AgentMemoryListResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/agent-memories/search`
[Section titled “GET /api/orgs/{org\_id}/agent-memories/search”](#get-apiorgsorg_idagent-memoriessearch)
Search Agent Memories
Vector search agent memories by semantic similarity.
**Parameters**
| Name | In | Type | Required | Description |
| --------- | ----- | --------------- | -------- | ----------------- |
| agent\_id | query | `string (uuid)` | no | Filter by agent |
| limit | query | `integer` | no | |
| org\_id | path | `string (uuid)` | yes | |
| q | query | `string` | no | Search query text |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------------- |
| 200 | Successful Response | `AgentMemorySearchResponse` |
| 422 | Validation Error | `HTTPValidationError` |
# Agent Teams
> REST API reference for agent teams.
### GET `/api/orgs/{org_id}/agent-teams`
[Section titled “GET /api/orgs/{org\_id}/agent-teams”](#get-apiorgsorg_idagent-teams)
List Teams
List all agent teams in the organization. Requires membership.
Omit `limit` to get every team; `total` is the full count either way.
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ----- | --------------- | -------- | ---------------------------------------------------------- |
| limit | query | `integer` | no | Max rows to return (1-100). Omit to return every row. |
| offset | query | `integer` | no | Rows to skip — pass the previous response’s `next_offset`. |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `Page_TeamResponse_` |
| 422 | Validation Error | `HTTPValidationError` |
### POST `/api/orgs/{org_id}/agent-teams`
[Section titled “POST /api/orgs/{org\_id}/agent-teams”](#post-apiorgsorg_idagent-teams)
Create Team
Create a new agent team. Requires ADMIN or OWNER role.
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
**Request body** (required)
| Field | Type | Required | Description |
| ----------------------- | ---------- | -------- | ----------- |
| avatar\_seed | `string` | no | |
| description | `string` | no | |
| name | `string` | yes | |
| shared\_allowed\_tools | `string[]` | no | |
| shared\_instruction | `string` | no | |
| shared\_mounted\_skills | `string[]` | no | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 201 | Successful Response | `TeamResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/agent-teams/{team_id}`
[Section titled “GET /api/orgs/{org\_id}/agent-teams/{team\_id}”](#get-apiorgsorg_idagent-teamsteam_id)
Get Team
Get an agent team by UUID or slug. Requires membership.
**Parameters**
| Name | In | Type | Required | Description |
| -------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
| team\_id | path | `string` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `TeamResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### PATCH `/api/orgs/{org_id}/agent-teams/{team_id}`
[Section titled “PATCH /api/orgs/{org\_id}/agent-teams/{team\_id}”](#patch-apiorgsorg_idagent-teamsteam_id)
Update Team
Update an agent team. Requires ADMIN or OWNER role.
**Parameters**
| Name | In | Type | Required | Description |
| -------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
| team\_id | path | `string` | yes | |
**Request body** (required)
| Field | Type | Required | Description |
| ----------------------- | ---------- | -------- | ----------- |
| avatar\_seed | `string` | no | |
| description | `string` | no | |
| name | `string` | no | |
| shared\_allowed\_tools | `string[]` | no | |
| shared\_instruction | `string` | no | |
| shared\_mounted\_skills | `string[]` | no | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `TeamResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### DELETE `/api/orgs/{org_id}/agent-teams/{team_id}`
[Section titled “DELETE /api/orgs/{org\_id}/agent-teams/{team\_id}”](#delete-apiorgsorg_idagent-teamsteam_id)
Delete Team
Delete an agent team. Agents become ungrouped. Requires ADMIN or OWNER role.
**Parameters**
| Name | In | Type | Required | Description |
| -------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
| team\_id | path | `string` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 204 | Successful Response | |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/agent-teams/{team_id}/memories`
[Section titled “GET /api/orgs/{org\_id}/agent-teams/{team\_id}/memories”](#get-apiorgsorg_idagent-teamsteam_idmemories)
List Team Memories
List memories owned by this team. Requires org membership.
**Parameters**
| Name | In | Type | Required | Description |
| -------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
| team\_id | path | `string` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ------------------------ |
| 200 | Successful Response | `TeamMemoryListResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### POST `/api/orgs/{org_id}/agent-teams/{team_id}/memories`
[Section titled “POST /api/orgs/{org\_id}/agent-teams/{team\_id}/memories”](#post-apiorgsorg_idagent-teamsteam_idmemories)
Create Team Memory
Create a memory owned by this team. Requires ADMIN or OWNER role.
**Parameters**
| Name | In | Type | Required | Description |
| -------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
| team\_id | path | `string` | yes | |
**Request body** (required)
| Field | Type | Required | Description |
| ------- | -------- | -------- | ----------- |
| content | `string` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 201 | Successful Response | `AgentMemoryResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### DELETE `/api/orgs/{org_id}/agent-teams/{team_id}/memories/{memory_id}`
[Section titled “DELETE /api/orgs/{org\_id}/agent-teams/{team\_id}/memories/{memory\_id}”](#delete-apiorgsorg_idagent-teamsteam_idmemoriesmemory_id)
Delete Team Memory
Delete a team memory. Requires ADMIN or OWNER role.
**Parameters**
| Name | In | Type | Required | Description |
| ---------- | ---- | --------------- | -------- | ----------- |
| memory\_id | path | `string (uuid)` | yes | |
| org\_id | path | `string (uuid)` | yes | |
| team\_id | path | `string` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 204 | Successful Response | |
| 422 | Validation Error | `HTTPValidationError` |
### PUT `/api/orgs/{org_id}/agent-teams/reorder`
[Section titled “PUT /api/orgs/{org\_id}/agent-teams/reorder”](#put-apiorgsorg_idagent-teamsreorder)
Reorder Teams
Reorder teams by setting display\_order. Requires membership.
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
**Request body** (required)
| Field | Type | Required | Description |
| --------- | ----------------- | -------- | ----------- |
| team\_ids | `string (uuid)[]` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 204 | Successful Response | |
| 422 | Validation Error | `HTTPValidationError` |
# Agent Toolkit
> REST API reference for agent toolkit.
### GET `/api/orgs/{org_id}/agent-toolkit`
[Section titled “GET /api/orgs/{org\_id}/agent-toolkit”](#get-apiorgsorg_idagent-toolkit)
Get Agent Toolkit
Return the complete toolkit inventory for an org.
Combines agents, prompt templates (which may carry an extraction schema), custom tools, connected (MCP/system/native-integration) tools, skills, and processes in a single response.
When `agent_slug` is provided the agent must belong to `org_id` (404 otherwise). `connected_tools` is then filtered to only those tools whose name appears in the agent’s `allowed_tools`. If `allowed_tools` is `["*"]`, the full list is returned.
All other lists are always unfiltered.
**Parameters**
| Name | In | Type | Required | Description |
| ----------- | ----- | --------------- | -------- | ----------------------------------------------------------------- |
| agent\_slug | query | `string` | no | When set, filter connected\_tools to this agent’s allowed\_tools. |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ---------------------- |
| 200 | Successful Response | `AgentToolkitResponse` |
| 422 | Validation Error | `HTTPValidationError` |
# Agents
> REST API reference for agents.
### GET `/api/orgs/{org_id}/agents`
[Section titled “GET /api/orgs/{org\_id}/agents”](#get-apiorgsorg_idagents)
List Agents
List agents in the organization. Requires membership.
Omit `limit` to get every agent; `total` is the full count either way.
**Parameters**
| Name | In | Type | Required | Description |
| ----------- | ----- | --------------- | -------- | ---------------------------------------------------------- |
| limit | query | `integer` | no | Max rows to return (1-100). Omit to return every row. |
| offset | query | `integer` | no | Rows to skip — pass the previous response’s `next_offset`. |
| org\_id | path | `string (uuid)` | yes | |
| project\_id | query | `string` | no | Filter by project id, or ‘none’ for uncategorized agents. |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `Page_AgentResponse_` |
| 422 | Validation Error | `HTTPValidationError` |
### POST `/api/orgs/{org_id}/agents`
[Section titled “POST /api/orgs/{org\_id}/agents”](#post-apiorgsorg_idagents)
Create Agent
Create a new agent in the organization. Requires ADMIN or OWNER role.
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
**Request body** (required)
| Field | Type | Required | Description |
| --------------------------- | --------------- | -------- | ----------- |
| allowed\_tools | `string[]` | no | |
| avatar\_seed | `string` | no | |
| description | `string` | no | |
| execution\_mode | `string` | no | |
| instruction | `string` | no | |
| model | `string` | no | |
| mounted\_skills | `string[]` | no | |
| name | `string` | yes | |
| per\_chat\_cost\_limit\_usd | `number` | no | |
| permissions | `object` | no | |
| pinned\_tools | `string[]` | no | |
| provider | `string` | no | |
| reasoning\_effort | `string` | no | |
| reply\_to\_incoming\_email | `boolean` | no | |
| sandbox\_enabled | `boolean` | no | |
| status | `string` | no | |
| system\_prompt | `string` | no | |
| tags | `string[]` | no | |
| team\_id | `string (uuid)` | no | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 201 | Successful Response | `AgentResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/agents/{agent_id}`
[Section titled “GET /api/orgs/{org\_id}/agents/{agent\_id}”](#get-apiorgsorg_idagentsagent_id)
Get Agent
Get agent details. Accepts UUID or slug. Requires membership.
**Parameters**
| Name | In | Type | Required | Description |
| --------- | ---- | --------------- | -------- | ----------- |
| agent\_id | path | `string` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `AgentResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### PATCH `/api/orgs/{org_id}/agents/{agent_id}`
[Section titled “PATCH /api/orgs/{org\_id}/agents/{agent\_id}”](#patch-apiorgsorg_idagentsagent_id)
Update Agent
Update agent settings. Accepts UUID or slug. Instruction edits are routed to the draft revision.
Requires ADMIN or OWNER role.
**Parameters**
| Name | In | Type | Required | Description |
| --------- | ---- | --------------- | -------- | ----------- |
| agent\_id | path | `string` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Request body** (required)
| Field | Type | Required | Description |
| --------------------------- | --------------- | -------- | ----------- |
| allowed\_tools | `string[]` | no | |
| avatar\_seed | `string` | no | |
| description | `string` | no | |
| execution\_mode | `string` | no | |
| instruction | `string` | no | |
| model | `string` | no | |
| mounted\_skills | `string[]` | no | |
| name | `string` | no | |
| per\_chat\_cost\_limit\_usd | `number` | no | |
| permissions | `object` | no | |
| pinned\_tools | `string[]` | no | |
| provider | `string` | no | |
| reasoning\_effort | `string` | no | |
| reply\_to\_incoming\_email | `boolean` | no | |
| sandbox\_enabled | `boolean` | no | |
| settings | `object` | no | |
| status | `string` | no | |
| system\_prompt | `string` | no | |
| tags | `string[]` | no | |
| team\_id | `string (uuid)` | no | |
| tools | `object[]` | no | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `AgentResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### DELETE `/api/orgs/{org_id}/agents/{agent_id}`
[Section titled “DELETE /api/orgs/{org\_id}/agents/{agent\_id}”](#delete-apiorgsorg_idagentsagent_id)
Delete Agent
Soft-delete an agent. Accepts UUID or slug. Requires ADMIN or OWNER role.
**Parameters**
| Name | In | Type | Required | Description |
| --------- | ---- | --------------- | -------- | ----------- |
| agent\_id | path | `string` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 204 | Successful Response | |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/agents/{agent_id}/artifacts`
[Section titled “GET /api/orgs/{org\_id}/agents/{agent\_id}/artifacts”](#get-apiorgsorg_idagentsagent_idartifacts)
Get Agent Artifacts
Get artifacts produced by an agent.
Accepts UUID or slug. Returns artifacts ordered by created\_at desc. Requires membership in the organization.
**Parameters**
| Name | In | Type | Required | Description |
| --------- | ----- | --------------- | -------- | ----------- |
| agent\_id | path | `string` | yes | |
| limit | query | `integer` | no | |
| offset | query | `integer` | no | |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------------- |
| 200 | Successful Response | `AgentArtifactListResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### POST `/api/orgs/{org_id}/agents/{agent_id}/deploy`
[Section titled “POST /api/orgs/{org\_id}/agents/{agent\_id}/deploy”](#post-apiorgsorg_idagentsagent_iddeploy)
Deploy Agent
Deploy the draft revision: activate it.
Accepts UUID or slug. Requires ADMIN or OWNER role.
**Parameters**
| Name | In | Type | Required | Description |
| --------- | ---- | --------------- | -------- | ----------- |
| agent\_id | path | `string` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `AgentResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### DELETE `/api/orgs/{org_id}/agents/{agent_id}/draft`
[Section titled “DELETE /api/orgs/{org\_id}/agents/{agent\_id}/draft”](#delete-apiorgsorg_idagentsagent_iddraft)
Discard Draft
Discard the draft revision for an agent.
Accepts UUID or slug. Requires ADMIN or OWNER role. Returns 422 if no draft exists.
**Parameters**
| Name | In | Type | Required | Description |
| --------- | ---- | --------------- | -------- | ----------- |
| agent\_id | path | `string` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `AgentResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/agents/{agent_id}/events`
[Section titled “GET /api/orgs/{org\_id}/agents/{agent\_id}/events”](#get-apiorgsorg_idagentsagent_idevents)
Get Agent Events
Get the activity timeline for an agent.
Accepts UUID or slug. Returns events ordered by created\_at desc (newest first). Requires membership in the organization.
**Parameters**
| Name | In | Type | Required | Description |
| --------- | ----- | --------------- | -------- | -------------------- |
| agent\_id | path | `string` | yes | |
| limit | query | `integer` | no | Max events to return |
| offset | query | `integer` | no | Pagination offset |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ---------------------------- |
| 200 | Successful Response | `AgentEventTimelineResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### POST `/api/orgs/{org_id}/agents/{agent_id}/regenerate-inbox-token`
[Section titled “POST /api/orgs/{org\_id}/agents/{agent\_id}/regenerate-inbox-token”](#post-apiorgsorg_idagentsagent_idregenerate-inbox-token)
Regenerate Inbox Token
Regenerate the inbox token for an agent, invalidating the old webhook URL and future email address.
Accepts UUID or slug. Requires ADMIN or OWNER role.
**Parameters**
| Name | In | Type | Required | Description |
| --------- | ---- | --------------- | -------- | ----------- |
| agent\_id | path | `string` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ------------------------------ |
| 200 | Successful Response | `RegenerateInboxTokenResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/agents/{agent_id}/revisions`
[Section titled “GET /api/orgs/{org\_id}/agents/{agent\_id}/revisions”](#get-apiorgsorg_idagentsagent_idrevisions)
List Revisions
List all revisions for an agent, newest first.
Accepts UUID or slug. Requires membership in the organization.
**Parameters**
| Name | In | Type | Required | Description |
| --------- | ---- | --------------- | -------- | ----------- |
| agent\_id | path | `string` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------------- |
| 200 | Successful Response | `AgentRevisionListResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/agents/{agent_id}/tokens`
[Section titled “GET /api/orgs/{org\_id}/agents/{agent\_id}/tokens”](#get-apiorgsorg_idagentsagent_idtokens)
List Agent Tokens
List all non-revoked tokens for an agent. Accepts UUID or slug. Requires membership.
**Parameters**
| Name | In | Type | Required | Description |
| --------- | ---- | --------------- | -------- | ----------- |
| agent\_id | path | `string` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ------------------------ |
| 200 | Successful Response | `AgentTokenListResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### POST `/api/orgs/{org_id}/agents/{agent_id}/tokens`
[Section titled “POST /api/orgs/{org\_id}/agents/{agent\_id}/tokens”](#post-apiorgsorg_idagentsagent_idtokens)
Create Agent Token
Create a new token for an agent. Accepts UUID or slug. Returns plaintext once. Requires ADMIN or OWNER role.
**Parameters**
| Name | In | Type | Required | Description |
| --------- | ---- | --------------- | -------- | ----------- |
| agent\_id | path | `string` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Request body** (required)
| Field | Type | Required | Description |
| ----------- | -------- | -------- | ----------- |
| description | `string` | no | |
| name | `string` | yes | |
| scope | `string` | no | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | -------------------------- |
| 201 | Successful Response | `CreateAgentTokenResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### DELETE `/api/orgs/{org_id}/agents/{agent_id}/tokens/{token_id}`
[Section titled “DELETE /api/orgs/{org\_id}/agents/{agent\_id}/tokens/{token\_id}”](#delete-apiorgsorg_idagentsagent_idtokenstoken_id)
Revoke Agent Token
Revoke an agent token. Accepts UUID or slug. Requires ADMIN or OWNER role.
**Parameters**
| Name | In | Type | Required | Description |
| --------- | ---- | --------------- | -------- | ----------- |
| agent\_id | path | `string` | yes | |
| org\_id | path | `string (uuid)` | yes | |
| token\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 204 | Successful Response | |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/agents/deleted`
[Section titled “GET /api/orgs/{org\_id}/agents/deleted”](#get-apiorgsorg_idagentsdeleted)
List Deleted Agents
List soft-deleted agents in the organization. Requires ADMIN or OWNER role.
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ----- | --------------- | -------- | ---------------------------------------------------------- |
| limit | query | `integer` | no | Max rows to return (1-100). Omit to return every row. |
| offset | query | `integer` | no | Rows to skip — pass the previous response’s `next_offset`. |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `Page_AgentResponse_` |
| 422 | Validation Error | `HTTPValidationError` |
# Artifacts
> REST API reference for artifacts.
### GET `/api/orgs/{org_id}/artifacts/{artifact_id}`
[Section titled “GET /api/orgs/{org\_id}/artifacts/{artifact\_id}”](#get-apiorgsorg_idartifactsartifact_id)
Get Artifact
Get a single artifact by ID.
Requires membership in the organization.
**Parameters**
| Name | In | Type | Required | Description |
| ------------ | ---- | --------------- | -------- | ----------- |
| artifact\_id | path | `string (uuid)` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ------------------------ |
| 200 | Successful Response | `ArtifactDetailResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/artifacts/{artifact_id}/download`
[Section titled “GET /api/orgs/{org\_id}/artifacts/{artifact\_id}/download”](#get-apiorgsorg_idartifactsartifact_iddownload)
Download Artifact
Download the raw bytes of a FILE-type artifact.
Only valid for artifacts with artifact\_type == “file”. For all other types (code, markdown, text, json) the content is already inline in the `GET /{artifact_id}` response.
Returns the file bytes with appropriate Content-Type and Content-Disposition headers so browsers trigger a native download.
**Parameters**
| Name | In | Type | Required | Description |
| ------------ | ---- | --------------- | -------- | ----------- |
| artifact\_id | path | `string (uuid)` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `object` |
| 422 | Validation Error | `HTTPValidationError` |
# Authentication
> REST API reference for authentication.
### GET `/api/auth/me`
[Section titled “GET /api/auth/me”](#get-apiauthme)
Get Me
Get identity info for the authenticated principal.
Works for both user tokens (JWT / agd\_\* user token) and agent tokens.
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `PrincipalResponse` |
| 422 | Validation Error | `HTTPValidationError` |
# Chat Files
> REST API reference for chat files.
### GET `/api/orgs/{org_id}/agents/{agent_id}/chats/{chat_id}/files/`
[Section titled “GET /api/orgs/{org\_id}/agents/{agent\_id}/chats/{chat\_id}/files/”](#get-apiorgsorg_idagentsagent_idchatschat_idfiles)
List Chat Files
List all files attached to a chat conversation.
**Parameters**
| Name | In | Type | Required | Description |
| --------- | ---- | --------------- | -------- | ----------- |
| agent\_id | path | `string (uuid)` | yes | |
| chat\_id | path | `string (uuid)` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `FileListResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### POST `/api/orgs/{org_id}/agents/{agent_id}/chats/{chat_id}/files/`
[Section titled “POST /api/orgs/{org\_id}/agents/{agent\_id}/chats/{chat\_id}/files/”](#post-apiorgsorg_idagentsagent_idchatschat_idfiles)
Attach Chat Files
Attach previously uploaded temp files to a chat conversation.
**Parameters**
| Name | In | Type | Required | Description |
| --------- | ---- | --------------- | -------- | ----------- |
| agent\_id | path | `string (uuid)` | yes | |
| chat\_id | path | `string (uuid)` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Request body** (required)
| Field | Type | Required | Description |
| ---------- | ------------------------------------------------ | -------- | ----------- |
| file\_refs | `agentdepot_api__routers__chat_files__FileRef[]` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 201 | Successful Response | `FileListResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### DELETE `/api/orgs/{org_id}/agents/{agent_id}/chats/{chat_id}/files/{file_id}`
[Section titled “DELETE /api/orgs/{org\_id}/agents/{agent\_id}/chats/{chat\_id}/files/{file\_id}”](#delete-apiorgsorg_idagentsagent_idchatschat_idfilesfile_id)
Delete Chat File
Delete a chat file from S3 (when not shared) and the database.
**Parameters**
| Name | In | Type | Required | Description |
| --------- | ---- | --------------- | -------- | ----------- |
| agent\_id | path | `string (uuid)` | yes | |
| chat\_id | path | `string (uuid)` | yes | |
| file\_id | path | `string (uuid)` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 204 | Successful Response | |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/agents/{agent_id}/chats/{chat_id}/files/{file_id}/download`
[Section titled “GET /api/orgs/{org\_id}/agents/{agent\_id}/chats/{chat\_id}/files/{file\_id}/download”](#get-apiorgsorg_idagentsagent_idchatschat_idfilesfile_iddownload)
Download Chat File
Download a chat file’s content.
**Parameters**
| Name | In | Type | Required | Description |
| --------- | ---- | --------------- | -------- | ----------- |
| agent\_id | path | `string (uuid)` | yes | |
| chat\_id | path | `string (uuid)` | yes | |
| file\_id | path | `string (uuid)` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `object` |
| 422 | Validation Error | `HTTPValidationError` |
# Chats
> REST API reference for chats.
### GET `/api/orgs/{org_id}/chats`
[Section titled “GET /api/orgs/{org\_id}/chats”](#get-apiorgsorg_idchats)
List Work Chats
List work chats with pagination and outcome-based stats.
Stats: throughput = count(SUCCESS outcomes), efficiency = avg cost per SUCCESS outcome.
**Parameters**
| Name | In | Type | Required | Description |
| ----------- | ----- | --------------- | -------- | --------------------------------------------------------------- |
| agent\_id | query | `string (uuid)` | no | |
| org\_id | path | `string (uuid)` | yes | |
| page | query | `integer` | no | |
| per\_page | query | `integer` | no | |
| since | query | `string` | no | Time period for stats: 24h, 7d, 30d |
| sort\_by | query | `string` | no | Sort field: created\_at, completed\_at, total\_cost\_usd, title |
| sort\_order | query | `string` | no | asc or desc |
| status | query | `string` | no | |
| tags | query | `string[]` | no | Filter by tags (ALL must match) |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ---------------------- |
| 200 | Successful Response | `ChatWorkListResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### POST `/api/orgs/{org_id}/chats`
[Section titled “POST /api/orgs/{org\_id}/chats”](#post-apiorgsorg_idchats)
Create Work Chat
Create a new work chat (manual trigger).
Validates the agent, checks for prompt injection, determines initial ChatStatus based on execution mode, and emits `chat.work_created` to Hatchet when the chat is ACTIVE.
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
**Request body** (required)
| Field | Type | Required | Description |
| ----------- | --------------- | -------- | ----------- |
| agent\_id | `string (uuid)` | yes | |
| description | `string` | no | |
| tags | `string[]` | no | |
| title | `string` | no | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 201 | Successful Response | `ChatWorkResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/chats/{chat_id}`
[Section titled “GET /api/orgs/{org\_id}/chats/{chat\_id}”](#get-apiorgsorg_idchatschat_id)
Get Work Chat
Get a single work chat detail.
**Parameters**
| Name | In | Type | Required | Description |
| -------- | ---- | --------------- | -------- | ----------- |
| chat\_id | path | `string (uuid)` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `ChatWorkResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### DELETE `/api/orgs/{org_id}/chats/{chat_id}`
[Section titled “DELETE /api/orgs/{org\_id}/chats/{chat\_id}”](#delete-apiorgsorg_idchatschat_id)
Delete Work Chat
Soft-delete a work chat.
**Parameters**
| Name | In | Type | Required | Description |
| -------- | ---- | --------------- | -------- | ----------- |
| chat\_id | path | `string (uuid)` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 204 | Successful Response | |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/chats/{chat_id}/outcomes`
[Section titled “GET /api/orgs/{org\_id}/chats/{chat\_id}/outcomes”](#get-apiorgsorg_idchatschat_idoutcomes)
List Outcomes
List all outcomes recorded for a chat.
**Parameters**
| Name | In | Type | Required | Description |
| -------- | ---- | --------------- | -------- | ----------- |
| chat\_id | path | `string (uuid)` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `OutcomeListResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### POST `/api/orgs/{org_id}/chats/{chat_id}/outcomes`
[Section titled “POST /api/orgs/{org\_id}/chats/{chat\_id}/outcomes”](#post-apiorgsorg_idchatschat_idoutcomes)
Create Outcome
Record an outcome against a chat (manual / override).
**Parameters**
| Name | In | Type | Required | Description |
| -------- | ---- | --------------- | -------- | ----------- |
| chat\_id | path | `string (uuid)` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Request body** (required)
| Field | Type | Required | Description |
| -------- | -------- | -------- | ----------- |
| evidence | `string` | no | |
| goal | `string` | yes | |
| status | `string` | no | |
| summary | `string` | no | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 201 | Successful Response | `OutcomeResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### PATCH `/api/orgs/{org_id}/chats/{chat_id}/tags`
[Section titled “PATCH /api/orgs/{org\_id}/chats/{chat\_id}/tags”](#patch-apiorgsorg_idchatschat_idtags)
Update Chat Tags
Update tags on a work chat.
**Parameters**
| Name | In | Type | Required | Description |
| -------- | ---- | --------------- | -------- | ----------- |
| chat\_id | path | `string (uuid)` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Request body** (required)
| Field | Type | Required | Description |
| ----- | ---------- | -------- | ----------- |
| tags | `string[]` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `string[]` |
| 422 | Validation Error | `HTTPValidationError` |
# Connections
> REST API reference for connections.
### GET `/api/orgs/{org_id}/connections`
[Section titled “GET /api/orgs/{org\_id}/connections”](#get-apiorgsorg_idconnections)
List Connections
List connections for the organisation, visible to the caller.
PRIVATE connections owned by someone else are omitted entirely (not just redacted). `wildcard_agent_count` is the number of org agents with a `"*"` tool grant — excluded from every connection’s `used_by_agent_ids`.
Omit `limit` to get every connection; `total` is a real `COUNT` of the visible set either way — never the size of the page.
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ----- | --------------- | -------- | ---------------------------------------------------------- |
| limit | query | `integer` | no | Max rows to return (1-100). Omit to return every row. |
| offset | query | `integer` | no | Rows to skip — pass the previous response’s `next_offset`. |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | -------------------------------------------------------------- |
| 200 | Successful Response | `agentdepot_api__routers__connections__ConnectionListResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/connections/{connection_id}`
[Section titled “GET /api/orgs/{org\_id}/connections/{connection\_id}”](#get-apiorgsorg_idconnectionsconnection_id)
Get Connection
Get a single connection by its prefixed ID.
A PRIVATE connection owned by someone else 404s — indistinguishable from a connection that doesn’t exist.
**Parameters**
| Name | In | Type | Required | Description |
| -------------- | ---- | --------------- | -------- | ----------- |
| connection\_id | path | `string` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ---------------------------------------------------------- |
| 200 | Successful Response | `agentdepot_api__routers__connections__ConnectionResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### PATCH `/api/orgs/{org_id}/connections/{connection_id}`
[Section titled “PATCH /api/orgs/{org\_id}/connections/{connection\_id}”](#patch-apiorgsorg_idconnectionsconnection_id)
Update Connection
Update a connection’s status (enable/disable) and/or display label.
Any org member may manage connections for now — see issue #260. A PRIVATE connection owned by someone else 404s.
**Parameters**
| Name | In | Type | Required | Description |
| -------------- | ---- | --------------- | -------- | ----------- |
| connection\_id | path | `string` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Request body** (required)
| Field | Type | Required | Description |
| ------ | -------- | -------- | ----------- |
| label | `string` | no | |
| status | `string` | no | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ---------------------------------------------------------- |
| 200 | Successful Response | `agentdepot_api__routers__connections__ConnectionResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### DELETE `/api/orgs/{org_id}/connections/{connection_id}`
[Section titled “DELETE /api/orgs/{org\_id}/connections/{connection\_id}”](#delete-apiorgsorg_idconnectionsconnection_id)
Delete Connection
Disconnect / remove a connection.
Any org member may remove a connection visible to them for now — see issue #260. A PRIVATE connection owned by someone else 404s.
**Parameters**
| Name | In | Type | Required | Description |
| -------------- | ---- | --------------- | -------- | ----------- |
| connection\_id | path | `string` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 204 | Successful Response | |
| 422 | Validation Error | `HTTPValidationError` |
### PATCH `/api/orgs/{org_id}/connections/{connection_id}/scope`
[Section titled “PATCH /api/orgs/{org\_id}/connections/{connection\_id}/scope”](#patch-apiorgsorg_idconnectionsconnection_idscope)
Update Connection Scope
Convert a connection’s visibility scope (private ⇄ org).
Any org member who can see the connection may change its scope (same permission model as editing its label / disconnecting it). A private row is only visible to its owner, so only the owner can re-scope it; an org-scoped row is re-scopable by any member. Making a connection with no recorded owner (`owner_user_id` NULL — e.g. a pre-existing row) private assigns ownership to the member performing the change.
**Parameters**
| Name | In | Type | Required | Description |
| -------------- | ---- | --------------- | -------- | ----------- |
| connection\_id | path | `string` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Request body** (required)
| Field | Type | Required | Description |
| ----- | -------- | -------- | ----------- |
| scope | `string` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ---------------------------------------------------------- |
| 200 | Successful Response | `agentdepot_api__routers__connections__ConnectionResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/connections/by-slug/{slug}`
[Section titled “GET /api/orgs/{org\_id}/connections/by-slug/{slug}”](#get-apiorgsorg_idconnectionsby-slugslug)
Get Connection By Slug
Get a single connection by its URL slug.
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
| slug | path | `string` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ---------------------------------------------------------- |
| 200 | Successful Response | `agentdepot_api__routers__connections__ConnectionResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/connections/catalog`
[Section titled “GET /api/orgs/{org\_id}/connections/catalog”](#get-apiorgsorg_idconnectionscatalog)
Get Catalog
Return the app-level connections catalog: one card per product.
Merges the static apps (:func:`iter_static_apps`) with dynamic Composio apps (every ENABLED auth-config toolkit not already covered by a static app’s Composio method, e.g. Freshdesk) and a synthetic “Custom MCP” entry. `connected` reflects whether the org has a connection (visible to the caller) whose `provider_key` matches the app.
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `CatalogResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/connections/catalog/{app_key}/methods`
[Section titled “GET /api/orgs/{org\_id}/connections/catalog/{app\_key}/methods”](#get-apiorgsorg_idconnectionscatalogapp_keymethods)
Get Catalog App Methods
Return the ranked connect methods for one catalog app.
`app_key` is either a static app key (:data:`APP_MAP`), the synthetic `"mcp_server"` key, or an ENABLED Composio toolkit slug not covered by a static app.
**Parameters**
| Name | In | Type | Required | Description |
| -------- | ---- | --------------- | -------- | ----------- |
| app\_key | path | `string` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `MethodListResponse` |
| 422 | Validation Error | `HTTPValidationError` |
# Conversation Resources
> REST API reference for conversation resources.
### GET `/api/orgs/{org_id}/chats/{chat_id}/artifacts`
[Section titled “GET /api/orgs/{org\_id}/chats/{chat\_id}/artifacts”](#get-apiorgsorg_idchatschat_idartifacts)
List Conversation Artifacts
List all artifacts produced within a conversation (conversation-wide).
Phase 2 (chat-outcomes model): `Artifact.chat_id` is the sole NOT-NULL anchor; the old `assignment_id` subquery path is gone.
Requires membership in the organization.
**Parameters**
| Name | In | Type | Required | Description |
| -------- | ---- | --------------- | -------- | ----------- |
| chat\_id | path | `string (uuid)` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ---------------------------------- |
| 200 | Successful Response | `ConversationArtifactListResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/chats/{chat_id}/files`
[Section titled “GET /api/orgs/{org\_id}/chats/{chat\_id}/files”](#get-apiorgsorg_idchatschat_idfiles)
List Conversation Files
List all files attached to a conversation (conversation-wide).
Returns every `File` row where `chat_id` matches the conversation. Because `chat_id` is the required NOT-NULL owner (Phase 2 chat-outcomes model), this is the authoritative read for all files in a conversation.
Requires membership in the organization.
**Parameters**
| Name | In | Type | Required | Description |
| -------- | ---- | --------------- | -------- | ----------- |
| chat\_id | path | `string (uuid)` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ------------------------------ |
| 200 | Successful Response | `ConversationFileListResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/chats/{chat_id}/files/{file_id}/download`
[Section titled “GET /api/orgs/{org\_id}/chats/{chat\_id}/files/{file\_id}/download”](#get-apiorgsorg_idchatschat_idfilesfile_iddownload)
Download Conversation File
Download a file that belongs to this conversation.
The owning column is `files.chat_id` — membership in the conversation is sufficient to download any file attached to it.
Validates that the file belongs to both this conversation and this organisation before streaming the bytes from S3.
Requires membership in the organization.
**Parameters**
| Name | In | Type | Required | Description |
| -------- | ---- | --------------- | -------- | ----------- |
| chat\_id | path | `string (uuid)` | yes | |
| file\_id | path | `string (uuid)` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `object` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/chats/{chat_id}/logs`
[Section titled “GET /api/orgs/{org\_id}/chats/{chat\_id}/logs”](#get-apiorgsorg_idchatschat_idlogs)
List Conversation Logs
List all log entries for a conversation.
Phase 2 (chat-outcomes model): `ChatLog.chat_id` is the direct owner (table renamed from `assignment_logs` → `chat_logs`; `assignment_id` column renamed to `chat_id`). Queries directly without any subquery.
Results are ordered by `created_at` ascending.
Requires membership in the organization.
**Parameters**
| Name | In | Type | Required | Description |
| -------- | ---- | --------------- | -------- | ----------- |
| chat\_id | path | `string (uuid)` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | -------------------------- |
| 200 | Successful Response | `ConversationLogsResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/chats/{chat_id}/related-memories`
[Section titled “GET /api/orgs/{org\_id}/chats/{chat\_id}/related-memories”](#get-apiorgsorg_idchatschat_idrelated-memories)
Get Conversation Related Memories
Return memories related to a conversation.
Delegates to `get_chat_related_memories` in agent\_memories.py. The legacy `/api/orgs/{org_id}/assignments/{chat_id}/related-memories` path has been removed; this is now the only endpoint for this resource.
Requires membership in the organization.
**Parameters**
| Name | In | Type | Required | Description |
| -------- | ---- | --------------- | -------- | ----------- |
| chat\_id | path | `string (uuid)` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `object` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/chats/{chat_id}/todos`
[Section titled “GET /api/orgs/{org\_id}/chats/{chat\_id}/todos”](#get-apiorgsorg_idchatschat_idtodos)
List Conversation Todos
List all todo items for a conversation, ordered by position then created\_at.
Mirrors the list the agent manages via the `write_todos` internal agent tool. All todo items are anchored on `chat_id` (`assignment_id` was dropped in Phase 2).
Requires membership in the organization.
**Parameters**
| Name | In | Type | Required | Description |
| -------- | ---- | --------------- | -------- | ----------- |
| chat\_id | path | `string (uuid)` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ------------------------------ |
| 200 | Successful Response | `ConversationTodoListResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/chats/{chat_id}/transcripts`
[Section titled “GET /api/orgs/{org\_id}/chats/{chat\_id}/transcripts”](#get-apiorgsorg_idchatschat_idtranscripts)
Get Conversation Transcripts
Lightweight index of per-step LLM transcripts for an entire conversation.
Returns all `agent_transcripts` rows ordered by `created_at` ascending then `step` ascending. Only scalar columns are selected — the heavy `request_messages`, `response_message`, `tool_definitions`, and `model_params` JSONB columns are **never loaded**. Instead, `request_message_count` gives the number of messages in `request_messages` (computed in Postgres via `jsonb_array_length`).
Use `GET /transcripts/steps/{step_id}` to lazy-load the full payload for any individual step.
Gated to ADMIN or OWNER role.
**Parameters**
| Name | In | Type | Required | Description |
| -------- | ---- | --------------- | -------- | ----------- |
| chat\_id | path | `string (uuid)` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ------------------------------------- |
| 200 | Successful Response | `ConversationTranscriptIndexResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/chats/{chat_id}/transcripts/steps/{step_id}`
[Section titled “GET /api/orgs/{org\_id}/chats/{chat\_id}/transcripts/steps/{step\_id}”](#get-apiorgsorg_idchatschat_idtranscriptsstepsstep_id)
Get Transcript Step Detail
Full detail for a single transcript step — heavy JSONB included.
Returns `request_messages`, `response_message`, `tool_definitions`, and `model_params` for a single `agent_transcripts` row. Designed to be called lazily (on scroll / on selection) from the transcript debug page so the index renders instantly and the heavy payload is fetched only for the step being inspected.
The step must belong to the specified `chat_id` (i.e. `agent_transcripts.chat_id == chat_id`). Returns 404 if the step is not found or does not belong to this conversation.
Gated to ADMIN or OWNER role.
**Parameters**
| Name | In | Type | Required | Description |
| -------- | ---- | --------------- | -------- | ----------- |
| chat\_id | path | `string (uuid)` | yes | |
| org\_id | path | `string (uuid)` | yes | |
| step\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ------------------------------------ |
| 200 | Successful Response | `ConversationTranscriptStepResponse` |
| 422 | Validation Error | `HTTPValidationError` |
# Custom Tools
> REST API reference for custom tools.
### GET `/api/orgs/{org_id}/custom-tools`
[Section titled “GET /api/orgs/{org\_id}/custom-tools”](#get-apiorgsorg_idcustom-tools)
List Custom Tools
List custom tools for the organization.
Omit `limit` to get every tool; `total` is the full count either way.
**Parameters**
| Name | In | Type | Required | Description |
| ----------- | ----- | --------------- | -------- | ---------------------------------------------------------- |
| limit | query | `integer` | no | Max rows to return (1-100). Omit to return every row. |
| offset | query | `integer` | no | Rows to skip — pass the previous response’s `next_offset`. |
| org\_id | path | `string (uuid)` | yes | |
| project\_id | query | `string` | no | Filter by project id, or ‘none’ for uncategorized tools. |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | -------------------------- |
| 200 | Successful Response | `Page_CustomToolResponse_` |
| 422 | Validation Error | `HTTPValidationError` |
### POST `/api/orgs/{org_id}/custom-tools`
[Section titled “POST /api/orgs/{org\_id}/custom-tools”](#post-apiorgsorg_idcustom-tools)
Create Custom Tool
Create a new custom tool. Requires admin/owner role.
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
**Request body** (required)
| Field | Type | Required | Description |
| ------------ | ---------- | -------- | ----------- |
| env\_vars | `string[]` | no | |
| name | `string` | yes | |
| source\_code | `string` | yes | |
| tags | `string[]` | no | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 201 | Successful Response | `CustomToolResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/custom-tools/{id_or_slug}`
[Section titled “GET /api/orgs/{org\_id}/custom-tools/{id\_or\_slug}”](#get-apiorgsorg_idcustom-toolsid_or_slug)
Get Custom Tool
Get a custom tool by ID or slug.
**Parameters**
| Name | In | Type | Required | Description |
| ------------ | ---- | --------------- | -------- | ----------- |
| id\_or\_slug | path | `string` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `CustomToolResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### PUT `/api/orgs/{org_id}/custom-tools/{id_or_slug}`
[Section titled “PUT /api/orgs/{org\_id}/custom-tools/{id\_or\_slug}”](#put-apiorgsorg_idcustom-toolsid_or_slug)
Update Custom Tool
Update a custom tool. Requires admin/owner role.
**Parameters**
| Name | In | Type | Required | Description |
| ------------ | ---- | --------------- | -------- | ----------- |
| id\_or\_slug | path | `string` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Request body** (required)
| Field | Type | Required | Description |
| ------------ | ---------- | -------- | ----------- |
| env\_vars | `string[]` | no | |
| is\_enabled | `boolean` | no | |
| name | `string` | no | |
| source\_code | `string` | no | |
| tags | `string[]` | no | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `CustomToolResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### DELETE `/api/orgs/{org_id}/custom-tools/{id_or_slug}`
[Section titled “DELETE /api/orgs/{org\_id}/custom-tools/{id\_or\_slug}”](#delete-apiorgsorg_idcustom-toolsid_or_slug)
Delete Custom Tool
Delete a custom tool. Requires admin/owner role.
**Parameters**
| Name | In | Type | Required | Description |
| ------------ | ---- | --------------- | -------- | ----------- |
| id\_or\_slug | path | `string` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 204 | Successful Response | |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/custom-tools/{id_or_slug}/runs`
[Section titled “GET /api/orgs/{org\_id}/custom-tools/{id\_or\_slug}/runs”](#get-apiorgsorg_idcustom-toolsid_or_slugruns)
List Tool Runs
List recent runs for a custom tool.
**Parameters**
| Name | In | Type | Required | Description |
| ------------ | ----- | --------------- | -------- | ----------- |
| id\_or\_slug | path | `string` | yes | |
| limit | query | `integer` | no | |
| offset | query | `integer` | no | |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ------------------------- |
| 200 | Successful Response | `CustomToolRunResponse[]` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/custom-tools/{id_or_slug}/runs/{run_id}`
[Section titled “GET /api/orgs/{org\_id}/custom-tools/{id\_or\_slug}/runs/{run\_id}”](#get-apiorgsorg_idcustom-toolsid_or_slugrunsrun_id)
Get Tool Run
Get a specific tool run by ID.
**Parameters**
| Name | In | Type | Required | Description |
| ------------ | ---- | --------------- | -------- | ----------- |
| id\_or\_slug | path | `string` | yes | |
| org\_id | path | `string (uuid)` | yes | |
| run\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ----------------------- |
| 200 | Successful Response | `CustomToolRunResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### POST `/api/orgs/{org_id}/custom-tools/{tool_id}/execute`
[Section titled “POST /api/orgs/{org\_id}/custom-tools/{tool\_id}/execute”](#post-apiorgsorg_idcustom-toolstool_idexecute)
Execute Custom Tool
Execute a custom tool directly with provided arg bindings. Requires admin/owner role.
**Parameters**
| Name | In | Type | Required | Description |
| -------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
| tool\_id | path | `string (uuid)` | yes | |
**Request body** (required)
| Field | Type | Required | Description |
| ------------- | -------- | -------- | ----------- |
| arg\_bindings | `object` | no | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ----------------------- |
| 200 | Successful Response | `CustomToolRunResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### POST `/api/orgs/{org_id}/custom-tools/validate`
[Section titled “POST /api/orgs/{org\_id}/custom-tools/validate”](#post-apiorgsorg_idcustom-toolsvalidate)
Validate Source
Validate Python source code without saving. Requires admin/owner role.
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
**Request body** (required)
| Field | Type | Required | Description |
| ------------ | ---------- | -------- | ----------- |
| env\_vars | `string[]` | no | |
| source\_code | `string` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ------------------------ |
| 200 | Successful Response | `ValidateSourceResponse` |
| 422 | Validation Error | `HTTPValidationError` |
# Files
> REST API reference for files.
### GET `/api/orgs/{org_id}/files/{file_id}`
[Section titled “GET /api/orgs/{org\_id}/files/{file\_id}”](#get-apiorgsorg_idfilesfile_id)
Get File
Get a single file’s metadata by ID.
Requires membership in the organization.
**Parameters**
| Name | In | Type | Required | Description |
| -------- | ---- | --------------- | -------- | ----------- |
| file\_id | path | `string (uuid)` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `FileDetailResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/files/{file_id}/download`
[Section titled “GET /api/orgs/{org\_id}/files/{file\_id}/download”](#get-apiorgsorg_idfilesfile_iddownload)
Download File
Download a file (forces a native browser download).
Requires membership in the organization.
**Parameters**
| Name | In | Type | Required | Description |
| -------- | ---- | --------------- | -------- | ----------- |
| file\_id | path | `string (uuid)` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `object` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/files/{file_id}/view`
[Section titled “GET /api/orgs/{org\_id}/files/{file\_id}/view”](#get-apiorgsorg_idfilesfile_idview)
View File
Serve a file inline so it renders in a browser tab / iframe / img.
Identical to /download but uses `Content-Disposition: inline`.
Requires membership in the organization.
**Parameters**
| Name | In | Type | Required | Description |
| -------- | ---- | --------------- | -------- | ----------- |
| file\_id | path | `string (uuid)` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `object` |
| 422 | Validation Error | `HTTPValidationError` |
# Human-in-the-Loop
> REST API reference for human-in-the-loop.
### GET `/api/orgs/{org_id}/hitl-requests`
[Section titled “GET /api/orgs/{org\_id}/hitl-requests”](#get-apiorgsorg_idhitl-requests)
List Hitl Requests
List HITL requests for an organization.
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ----- | --------------- | -------- | ----------- |
| limit | query | `integer` | no | |
| offset | query | `integer` | no | |
| org\_id | path | `string (uuid)` | yes | |
| status | query | `string` | no | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `HitlListResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/hitl-requests/{request_id}`
[Section titled “GET /api/orgs/{org\_id}/hitl-requests/{request\_id}”](#get-apiorgsorg_idhitl-requestsrequest_id)
Get Hitl Request
Get a single HITL request.
**Parameters**
| Name | In | Type | Required | Description |
| ----------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
| request\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `HitlRequestResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### POST `/api/orgs/{org_id}/hitl-requests/{request_id}/respond`
[Section titled “POST /api/orgs/{org\_id}/hitl-requests/{request\_id}/respond”](#post-apiorgsorg_idhitl-requestsrequest_idrespond)
Respond To Hitl Request
Respond to a pending HITL request and resume the chat.
**Parameters**
| Name | In | Type | Required | Description |
| ----------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
| request\_id | path | `string (uuid)` | yes | |
**Request body** (required)
| Field | Type | Required | Description |
| --------- | -------- | -------- | ----------- |
| action | `string` | no | |
| selection | `string` | no | |
| text | `string` | no | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `HitlRequestResponse` |
| 422 | Validation Error | `HTTPValidationError` |
# Inbox
> REST API reference for inbox.
### POST `/api/inbox/{agent_slug}/{code}`
[Section titled “POST /api/inbox/{agent\_slug}/{code}”](#post-apiinboxagent_slugcode)
Receive Webhook Short
Create a work chat via public webhook inbox (simplified URL without org slug).
**Parameters**
| Name | In | Type | Required | Description |
| ----------- | ---- | -------- | -------- | ----------- |
| agent\_slug | path | `string` | yes | |
| code | path | `string` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 201 | Successful Response | `InboxResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### POST `/api/inbox/{org_slug}/{agent_slug}/{code}`
[Section titled “POST /api/inbox/{org\_slug}/{agent\_slug}/{code}”](#post-apiinboxorg_slugagent_slugcode)
Receive Webhook
Create a work chat via public webhook inbox. No authentication required.
Accepts two content types:
* `application/json`: JSON body with title, description, links, file\_urls
* `multipart/form-data`: form field `metadata` (JSON string) + file parts
**Parameters**
| Name | In | Type | Required | Description |
| ----------- | ---- | -------- | -------- | ----------- |
| agent\_slug | path | `string` | yes | |
| code | path | `string` | yes | |
| org\_slug | path | `string` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 201 | Successful Response | `InboxResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### POST `/api/inbox/hitl/{token}`
[Section titled “POST /api/inbox/hitl/{token}”](#post-apiinboxhitltoken)
Receive Hitl Reply
Ingest a human’s email reply to a HITL request (no auth — token + secret).
Resolves the signed reply-address token back to the originating request. If it is still pending, the reply becomes the HITL response and the chat resumes; if it was already answered, the reply continues the conversation as a new message.
**Parameters**
| Name | In | Type | Required | Description |
| ----- | ---- | -------- | -------- | ----------- |
| token | path | `string` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `InboxResponse` |
| 422 | Validation Error | `HTTPValidationError` |
# Composio Integrations
> REST API reference for composio integrations.
### GET `/api/integrations/composio/callback`
[Section titled “GET /api/integrations/composio/callback”](#get-apiintegrationscomposiocallback)
Composio Callback
Provider OAuth redirect target: verify, flip ACTIVE, bounce to the app.
Trusts only the signed `state` (binds `connection_id` ↔ `org_id`). The connection id itself is read from the (org-scoped) row, never the query, so a forged callback cannot activate another org’s connection. Always redirects to the app — the authenticated status poll remains the source of truth.
**Parameters**
| Name | In | Type | Required | Description |
| ----- | ----- | -------- | -------- | ----------- |
| state | query | `string` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `object` |
| 422 | Validation Error | `HTTPValidationError` |
### POST `/api/orgs/{org_id}/integrations/composio/connect`
[Section titled “POST /api/orgs/{org\_id}/integrations/composio/connect”](#post-apiorgsorg_idintegrationscomposioconnect)
Connect Toolkit
Initiate a Composio connection for a toolkit (any member — see #260).
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
**Request body** (required)
| Field | Type | Required | Description |
| ------------- | -------- | -------- | ----------- |
| credentials | `object` | no | |
| scope | `string` | no | |
| toolkit\_slug | `string` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `ConnectResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/integrations/composio/connect-fields`
[Section titled “GET /api/orgs/{org\_id}/integrations/composio/connect-fields”](#get-apiorgsorg_idintegrationscomposioconnect-fields)
Get Connect Fields
Return the credential fields required to connect a toolkit (any member — see #260).
For API-key / basic / bearer toolkits (`requires_credentials=True`) this returns the list of fields the user must supply before calling `/connect`. OAuth toolkits return an empty `fields` list with `requires_credentials=False` — no form is needed, the redirect handles it.
Returns 404 when Composio has no enabled auth config for the toolkit, 502 for unexpected upstream failures.
**Parameters**
| Name | In | Type | Required | Description |
| ------------- | ----- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
| toolkit\_slug | query | `string` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ----------------------- |
| 200 | Successful Response | `ConnectSchemaResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/integrations/composio/connections`
[Section titled “GET /api/orgs/{org\_id}/integrations/composio/connections”](#get-apiorgsorg_idintegrationscomposioconnections)
List Connections
List the org’s Composio connections and their lifecycle status.
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ------------------------------------------------------------------------ |
| 200 | Successful Response | `agentdepot_api__routers__integrations_composio__ConnectionListResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### DELETE `/api/orgs/{org_id}/integrations/composio/connections/{integration_id}`
[Section titled “DELETE /api/orgs/{org\_id}/integrations/composio/connections/{integration\_id}”](#delete-apiorgsorg_idintegrationscomposioconnectionsintegration_id)
Disconnect Toolkit
Disconnect a toolkit: delete the Composio account and the row (any member — see #260).
**Parameters**
| Name | In | Type | Required | Description |
| --------------- | ---- | --------------- | -------- | ----------- |
| integration\_id | path | `string (uuid)` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 204 | Successful Response | |
| 422 | Validation Error | `HTTPValidationError` |
### POST `/api/orgs/{org_id}/integrations/composio/connections/{integration_id}/reinitiate`
[Section titled “POST /api/orgs/{org\_id}/integrations/composio/connections/{integration\_id}/reinitiate”](#post-apiorgsorg_idintegrationscomposioconnectionsintegration_idreinitiate)
Reinitiate Connection
Restart OAuth for a stuck PENDING/ERROR connection (any member — see #260).
The signed callback state expires after `_STATE_MAX_AGE_SECONDS` (30 minutes) and the original `redirect_url` isn’t persisted, so a user who abandons the OAuth flow (or hits a connect error) has no way to resume — this mints a fresh signed state and re-initiates the same toolkit/auth config under the row’s original identity. 409 if the row isn’t PENDING or ERROR (e.g. already ACTIVE).
**Parameters**
| Name | In | Type | Required | Description |
| --------------- | ---- | --------------- | -------- | ----------- |
| integration\_id | path | `string (uuid)` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `ConnectResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/integrations/composio/connections/{integration_id}/status`
[Section titled “GET /api/orgs/{org\_id}/integrations/composio/connections/{integration\_id}/status”](#get-apiorgsorg_idintegrationscomposioconnectionsintegration_idstatus)
Get Connection Status
Poll Composio for a connection’s status and reconcile the row.
The authenticated source of truth the frontend polls after redirecting the user to OAuth — independent of whether the public callback fired.
**Parameters**
| Name | In | Type | Required | Description |
| --------------- | ---- | --------------- | -------- | ----------- |
| integration\_id | path | `string (uuid)` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | -------------------------- |
| 200 | Successful Response | `ConnectionStatusResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/integrations/composio/toolkits`
[Section titled “GET /api/orgs/{org\_id}/integrations/composio/toolkits”](#get-apiorgsorg_idintegrationscomposiotoolkits)
List Toolkits
List only the toolkits the org’s Composio account has an auth config for.
Instead of returning the entire Composio catalog, this fetches the set of auth configs the account has registered (e.g. `outlook`, `microsoft_teams`), restricts the catalog to those slugs, and annotates each with the org’s connection state. Any configured toolkit not found in the catalog page is included as a minimal entry so nothing is silently dropped.
The Composio catalog (`list_auth_configs` + `list_toolkits`) is cached in-process (see `services/composio_catalog.py`) because it is account-global and changes rarely. The `search` filter is applied in Python against the cached unfiltered data so caching does not break search. Per-org connection state is always fetched live from the DB.
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ----- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
| search | query | `string` | no | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `ToolkitListResponse` |
| 422 | Validation Error | `HTTPValidationError` |
# Knowledge
> REST API reference for knowledge.
### GET `/api/orgs/{org_id}/knowledge`
[Section titled “GET /api/orgs/{org\_id}/knowledge”](#get-apiorgsorg_idknowledge)
List Knowledge Bases
List knowledge bases for the organization, with source/chunk counts.
Omit `limit` to get every KB; `total` is the full count either way.
**Parameters**
| Name | In | Type | Required | Description |
| ----------- | ----- | --------------- | -------- | ------------------------------------------------------------------ |
| limit | query | `integer` | no | Max rows to return (1-100). Omit to return every row. |
| offset | query | `integer` | no | Rows to skip — pass the previous response’s `next_offset`. |
| org\_id | path | `string (uuid)` | yes | |
| project\_id | query | `string` | no | Filter by project id, or ‘none’ for uncategorized knowledge bases. |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ----------------------------- |
| 200 | Successful Response | `Page_KnowledgeBaseResponse_` |
| 422 | Validation Error | `HTTPValidationError` |
### POST `/api/orgs/{org_id}/knowledge`
[Section titled “POST /api/orgs/{org\_id}/knowledge”](#post-apiorgsorg_idknowledge)
Create Knowledge Base
Create a new knowledge base. Requires admin/owner role.
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
**Request body** (required)
| Field | Type | Required | Description |
| ----------- | -------- | -------- | ----------- |
| description | `string` | no | |
| name | `string` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ----------------------- |
| 201 | Successful Response | `KnowledgeBaseResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/knowledge/{kb_id}`
[Section titled “GET /api/orgs/{org\_id}/knowledge/{kb\_id}”](#get-apiorgsorg_idknowledgekb_id)
Get Knowledge Base
Get a knowledge base’s detail (with source/chunk counts).
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ---- | --------------- | -------- | ----------- |
| kb\_id | path | `string (uuid)` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ----------------------- |
| 200 | Successful Response | `KnowledgeBaseResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### PATCH `/api/orgs/{org_id}/knowledge/{kb_id}`
[Section titled “PATCH /api/orgs/{org\_id}/knowledge/{kb\_id}”](#patch-apiorgsorg_idknowledgekb_id)
Update Knowledge Base
Rename / re-describe a knowledge base. Requires admin/owner role.
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ---- | --------------- | -------- | ----------- |
| kb\_id | path | `string (uuid)` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Request body** (required)
| Field | Type | Required | Description |
| ----------- | -------- | -------- | ----------- |
| description | `string` | no | |
| name | `string` | no | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ----------------------- |
| 200 | Successful Response | `KnowledgeBaseResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### DELETE `/api/orgs/{org_id}/knowledge/{kb_id}`
[Section titled “DELETE /api/orgs/{org\_id}/knowledge/{kb\_id}”](#delete-apiorgsorg_idknowledgekb_id)
Delete Knowledge Base
Soft-delete a knowledge base. Requires admin/owner role.
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ---- | --------------- | -------- | ----------- |
| kb\_id | path | `string (uuid)` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 204 | Successful Response | |
| 422 | Validation Error | `HTTPValidationError` |
### POST `/api/orgs/{org_id}/knowledge/{kb_id}/search`
[Section titled “POST /api/orgs/{org\_id}/knowledge/{kb\_id}/search”](#post-apiorgsorg_idknowledgekb_idsearch)
Search Knowledge Base
Test-search a single knowledge base.
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ---- | --------------- | -------- | ----------- |
| kb\_id | path | `string (uuid)` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Request body** (required)
| Field | Type | Required | Description |
| ----- | --------- | -------- | ----------- |
| limit | `integer` | no | |
| query | `string` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ---------------------------------------------------- |
| 200 | Successful Response | `agentdepot_api__routers__knowledge__SearchResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/knowledge/{kb_id}/sources`
[Section titled “GET /api/orgs/{org\_id}/knowledge/{kb\_id}/sources”](#get-apiorgsorg_idknowledgekb_idsources)
List Sources
List a knowledge base’s sources, including sync status.
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ---- | --------------- | -------- | ----------- |
| kb\_id | path | `string (uuid)` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------------- |
| 200 | Successful Response | `KnowledgeSourceResponse[]` |
| 422 | Validation Error | `HTTPValidationError` |
### DELETE `/api/orgs/{org_id}/knowledge/{kb_id}/sources/{source_id}`
[Section titled “DELETE /api/orgs/{org\_id}/knowledge/{kb\_id}/sources/{source\_id}”](#delete-apiorgsorg_idknowledgekb_idsourcessource_id)
Delete Source
Delete a source. Chunks cascade via the DB foreign key.
**Parameters**
| Name | In | Type | Required | Description |
| ---------- | ---- | --------------- | -------- | ----------- |
| kb\_id | path | `string (uuid)` | yes | |
| org\_id | path | `string (uuid)` | yes | |
| source\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 204 | Successful Response | |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/knowledge/{kb_id}/sources/{source_id}/chunks`
[Section titled “GET /api/orgs/{org\_id}/knowledge/{kb\_id}/sources/{source\_id}/chunks”](#get-apiorgsorg_idknowledgekb_idsourcessource_idchunks)
List Source Chunks
Paginated chunk preview for a source, ordered by position.
**Parameters**
| Name | In | Type | Required | Description |
| ---------- | ----- | --------------- | -------- | ----------- |
| kb\_id | path | `string (uuid)` | yes | |
| limit | query | `integer` | no | |
| offset | query | `integer` | no | |
| org\_id | path | `string (uuid)` | yes | |
| source\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `ChunkListResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### POST `/api/orgs/{org_id}/knowledge/{kb_id}/sources/{source_id}/resync`
[Section titled “POST /api/orgs/{org\_id}/knowledge/{kb\_id}/sources/{source\_id}/resync”](#post-apiorgsorg_idknowledgekb_idsourcessource_idresync)
Resync Source
Reset a source to PENDING and re-trigger ingestion.
**Parameters**
| Name | In | Type | Required | Description |
| ---------- | ---- | --------------- | -------- | ----------- |
| kb\_id | path | `string (uuid)` | yes | |
| org\_id | path | `string (uuid)` | yes | |
| source\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ------------------------- |
| 200 | Successful Response | `KnowledgeSourceResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### POST `/api/orgs/{org_id}/knowledge/{kb_id}/sources/file`
[Section titled “POST /api/orgs/{org\_id}/knowledge/{kb\_id}/sources/file”](#post-apiorgsorg_idknowledgekb_idsourcesfile)
Create File Sources
Stage one or more previously-uploaded temp files into the knowledge base.
Mirrors `chat_files.py::attach_chat_files`: each `file_ref` points at a file already sitting in the temp S3 bucket (via a presigned upload); this endpoint downloads it, re-uploads it to permanent storage under the KB’s namespace, creates one `FILE` source per file (title = filename), and pushes `KNOWLEDGE_SOURCE_ADDED` for each.
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ---- | --------------- | -------- | ----------- |
| kb\_id | path | `string (uuid)` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Request body** (required)
| Field | Type | Required | Description |
| ---------- | ----------------------------------------------- | -------- | ----------- |
| file\_refs | `agentdepot_api__routers__knowledge__FileRef[]` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------------- |
| 201 | Successful Response | `KnowledgeSourceResponse[]` |
| 422 | Validation Error | `HTTPValidationError` |
### POST `/api/orgs/{org_id}/knowledge/{kb_id}/sources/text`
[Section titled “POST /api/orgs/{org\_id}/knowledge/{kb\_id}/sources/text”](#post-apiorgsorg_idknowledgekb_idsourcestext)
Create Text Source
Add manually-entered text as a source.
The content is staged to permanent S3 as `text/markdown` (mirroring the file path — the ingestion workflow downloads and extracts it the same way) rather than stored inline on the row.
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ---- | --------------- | -------- | ----------- |
| kb\_id | path | `string (uuid)` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Request body** (required)
| Field | Type | Required | Description |
| ------- | -------- | -------- | ----------- |
| content | `string` | yes | |
| title | `string` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ------------------------- |
| 201 | Successful Response | `KnowledgeSourceResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### POST `/api/orgs/{org_id}/knowledge/{kb_id}/sources/url`
[Section titled “POST /api/orgs/{org\_id}/knowledge/{kb\_id}/sources/url”](#post-apiorgsorg_idknowledgekb_idsourcesurl)
Create Url Source
Add a website URL as a source (title starts as the URL; the ingestion workflow may refine it once the page is fetched).
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ---- | --------------- | -------- | ----------- |
| kb\_id | path | `string (uuid)` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Request body** (required)
| Field | Type | Required | Description |
| ----- | -------- | -------- | ----------- |
| url | `string` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ------------------------- |
| 201 | Successful Response | `KnowledgeSourceResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/knowledge/{kb_id}/sync-configs`
[Section titled “GET /api/orgs/{org\_id}/knowledge/{kb\_id}/sync-configs”](#get-apiorgsorg_idknowledgekb_idsync-configs)
List Sync Configs
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ---- | --------------- | -------- | ----------- |
| kb\_id | path | `string (uuid)` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ---------------------- |
| 200 | Successful Response | `SyncConfigResponse[]` |
| 422 | Validation Error | `HTTPValidationError` |
### POST `/api/orgs/{org_id}/knowledge/{kb_id}/sync-configs`
[Section titled “POST /api/orgs/{org\_id}/knowledge/{kb\_id}/sync-configs”](#post-apiorgsorg_idknowledgekb_idsync-configs)
Create Sync Config
Connect a remote collection to the KB and trigger the initial sync.
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ---- | --------------- | -------- | ----------- |
| kb\_id | path | `string (uuid)` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Request body** (required)
| Field | Type | Required | Description |
| ---------------- | --------------- | -------- | ----------- |
| collection\_id | `string` | yes | |
| collection\_name | `string` | yes | |
| integration\_id | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 201 | Successful Response | `SyncConfigResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### DELETE `/api/orgs/{org_id}/knowledge/{kb_id}/sync-configs/{config_id}`
[Section titled “DELETE /api/orgs/{org\_id}/knowledge/{kb\_id}/sync-configs/{config\_id}”](#delete-apiorgsorg_idknowledgekb_idsync-configsconfig_id)
Delete Sync Config
Disconnect a collection. Its synced sources (and chunks) are deleted.
**Parameters**
| Name | In | Type | Required | Description |
| ---------- | ---- | --------------- | -------- | ----------- |
| config\_id | path | `string (uuid)` | yes | |
| kb\_id | path | `string (uuid)` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 204 | Successful Response | |
| 422 | Validation Error | `HTTPValidationError` |
### POST `/api/orgs/{org_id}/knowledge/{kb_id}/sync-configs/{config_id}/sync`
[Section titled “POST /api/orgs/{org\_id}/knowledge/{kb\_id}/sync-configs/{config\_id}/sync”](#post-apiorgsorg_idknowledgekb_idsync-configsconfig_idsync)
Trigger Sync
Manually trigger a sync of one connected collection.
**Parameters**
| Name | In | Type | Required | Description |
| ---------- | ---- | --------------- | -------- | ----------- |
| config\_id | path | `string (uuid)` | yes | |
| kb\_id | path | `string (uuid)` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `SyncConfigResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/knowledge/integrations/{integration_id}/collections`
[Section titled “GET /api/orgs/{org\_id}/knowledge/integrations/{integration\_id}/collections”](#get-apiorgsorg_idknowledgeintegrationsintegration_idcollections)
List Remote Collections
List the syncable collections of a knowledge-capable connection.
**Parameters**
| Name | In | Type | Required | Description |
| --------------- | ---- | --------------- | -------- | ----------- |
| integration\_id | path | `string (uuid)` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ---------------------------- |
| 200 | Successful Response | `RemoteCollectionResponse[]` |
| 422 | Validation Error | `HTTPValidationError` |
### POST `/api/orgs/{org_id}/knowledge/search`
[Section titled “POST /api/orgs/{org\_id}/knowledge/search”](#post-apiorgsorg_idknowledgesearch)
Search Org Knowledge
Test-search across every knowledge base in the org (no `kb_id` scope).
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
**Request body** (required)
| Field | Type | Required | Description |
| ----- | --------- | -------- | ----------- |
| limit | `integer` | no | |
| query | `string` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ---------------------------------------------------- |
| 200 | Successful Response | `agentdepot_api__routers__knowledge__SearchResponse` |
| 422 | Validation Error | `HTTPValidationError` |
# Members
> REST API reference for members.
### GET `/api/orgs/{org_id}/members`
[Section titled “GET /api/orgs/{org\_id}/members”](#get-apiorgsorg_idmembers)
List Members
List all members of the organization.
Requires membership in the organization.
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `MemberListResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/members/{member_id}`
[Section titled “GET /api/orgs/{org\_id}/members/{member\_id}”](#get-apiorgsorg_idmembersmember_id)
Get Member
Get details of a specific member.
Requires membership in the organization.
**Parameters**
| Name | In | Type | Required | Description |
| ---------- | ---- | --------------- | -------- | ----------- |
| member\_id | path | `string (uuid)` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `MemberResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### PATCH `/api/orgs/{org_id}/members/{member_id}`
[Section titled “PATCH /api/orgs/{org\_id}/members/{member\_id}”](#patch-apiorgsorg_idmembersmember_id)
Update Member
Update a member’s role.
Requires ADMIN or OWNER role. Only OWNER can promote to ADMIN or OWNER. Cannot change your own role. Cannot demote the last OWNER.
**Parameters**
| Name | In | Type | Required | Description |
| ---------- | ---- | --------------- | -------- | ----------- |
| member\_id | path | `string (uuid)` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Request body** (required)
| Field | Type | Required | Description |
| ----- | -------- | -------- | ----------- |
| role | `string` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `MemberResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### DELETE `/api/orgs/{org_id}/members/{member_id}`
[Section titled “DELETE /api/orgs/{org\_id}/members/{member\_id}”](#delete-apiorgsorg_idmembersmember_id)
Remove Member
Remove a member from the organization.
Requires ADMIN or OWNER role. Cannot remove yourself (use a leave endpoint instead). Cannot remove the last OWNER.
**Parameters**
| Name | In | Type | Required | Description |
| ---------- | ---- | --------------- | -------- | ----------- |
| member\_id | path | `string (uuid)` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 204 | Successful Response | |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/members/invitations`
[Section titled “GET /api/orgs/{org\_id}/members/invitations”](#get-apiorgsorg_idmembersinvitations)
List Invitations
List all pending invitations for the organization.
Requires ADMIN or OWNER role.
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ---------------------- |
| 200 | Successful Response | `InvitationResponse[]` |
| 422 | Validation Error | `HTTPValidationError` |
### PATCH `/api/orgs/{org_id}/members/invitations/{invitation_id}`
[Section titled “PATCH /api/orgs/{org\_id}/members/invitations/{invitation\_id}”](#patch-apiorgsorg_idmembersinvitationsinvitation_id)
Update Invitation
Change the role a pending invitation will grant on redemption.
The create-organization wizard sends every invite as MEMBER and lets the owner adjust roles afterwards, so this is the ordinary path rather than a correction: by then the invitation row already exists.
Requires ADMIN or OWNER; only an OWNER may raise an invitation to ADMIN or OWNER, matching `invite_member`.
**Parameters**
| Name | In | Type | Required | Description |
| -------------- | ---- | --------------- | -------- | ----------- |
| invitation\_id | path | `string (uuid)` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Request body** (required)
| Field | Type | Required | Description |
| ----- | -------- | -------- | ----------- |
| role | `string` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `InvitationResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### DELETE `/api/orgs/{org_id}/members/invitations/{invitation_id}`
[Section titled “DELETE /api/orgs/{org\_id}/members/invitations/{invitation\_id}”](#delete-apiorgsorg_idmembersinvitationsinvitation_id)
Revoke Invitation
Revoke a pending invitation.
Requires ADMIN or OWNER role. Only pending invitations can be revoked.
**Parameters**
| Name | In | Type | Required | Description |
| -------------- | ---- | --------------- | -------- | ----------- |
| invitation\_id | path | `string (uuid)` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 204 | Successful Response | |
| 422 | Validation Error | `HTTPValidationError` |
### POST `/api/orgs/{org_id}/members/invite`
[Section titled “POST /api/orgs/{org\_id}/members/invite”](#post-apiorgsorg_idmembersinvite)
Invite Member
Add a user to the organization by email.
Requires ADMIN or OWNER role. If the user already has an account, they are added directly and a MemberResponse is returned. If they don’t have an account yet, a pending invitation is created and an InvitationResponse is returned (HTTP 201). When the user signs up, the invitation is redeemed automatically.
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
**Request body** (required)
| Field | Type | Required | Description |
| ----- | -------- | -------- | ----------- |
| email | `string` | yes | |
| role | `string` | no | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ---------------------------------------- |
| 201 | Successful Response | `MemberResponse` \| `InvitationResponse` |
| 422 | Validation Error | `HTTPValidationError` |
# Models
> REST API reference for models.
### GET `/api/models/catalog`
[Section titled “GET /api/models/catalog”](#get-apimodelscatalog)
Get Model Catalog
Return the platform’s enabled chat models, in display order.
Replaces the model array that used to be hardcoded in the web app. Only enabled rows are exposed — a model switched off in the admin panel must disappear from every picker, and is rejected server-side regardless. Embedding models share the catalog (same pricing shape, same admin surface) but are never conversational, so they are filtered out here. Readable by any authenticated user; per-org narrowing happens on top of this via `GET /orgs/{id}/model-config`.
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `CatalogModel[]` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/models/pricing`
[Section titled “GET /api/models/pricing”](#get-apimodelspricing)
Get Model Pricing
Return LLM model pricing in per-1-million-token units.
Served from the platform model catalog — the same numbers runs are billed on, so what a picker shows and what a chat costs cannot drift. A model whose catalog row has no input/output price is omitted; admins fill those in (or sync them from the LiteLLM dataset) in the admin panel.
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `object` |
| 422 | Validation Error | `HTTPValidationError` |
# Org Integrations
> REST API reference for org integrations.
### GET `/api/orgs/{org_id}/integrations/check-slug`
[Section titled “GET /api/orgs/{org\_id}/integrations/check-slug”](#get-apiorgsorg_idintegrationscheck-slug)
Check Slug Availability
Check whether a connection slug is valid and not yet taken in this org.
Used by the create/edit dialogs for live validation. Pass `exclude_id` to ignore the integration being edited when checking uniqueness.
**Parameters**
| Name | In | Type | Required | Description |
| ----------- | ----- | --------------- | -------- | ----------- |
| exclude\_id | query | `string (uuid)` | no | |
| org\_id | path | `string (uuid)` | yes | |
| slug | query | `string` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `SlugCheckResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/integrations/configured`
[Section titled “GET /api/orgs/{org\_id}/integrations/configured”](#get-apiorgsorg_idintegrationsconfigured)
List Configured Integrations
List the organization’s configured integrations.
Requires membership in the organization. Secret params are redacted.
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ----------------------------------- |
| 200 | Successful Response | `ConfiguredIntegrationListResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### POST `/api/orgs/{org_id}/integrations/configured`
[Section titled “POST /api/orgs/{org\_id}/integrations/configured”](#post-apiorgsorg_idintegrationsconfigured)
Create Configured Integration
Create a new configured integration.
Any org member may create integrations for now — see issue #260. Validates params against the registry.
For MCP\_SERVER integrations the tool-definition cache is invalidated after creation so that the next tool-discovery read fetches fresh tool metadata from the upstream server.
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
**Request body** (required)
| Field | Type | Required | Description |
| ----------------- | -------- | -------- | ----------- |
| app\_name | `string` | no | |
| description | `string` | no | |
| integration\_type | `string` | yes | |
| name | `string` | yes | |
| params | `object` | yes | |
| scope | `string` | no | |
| slug | `string` | no | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ------------------------------- |
| 201 | Successful Response | `ConfiguredIntegrationResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/integrations/configured/{integration_id}`
[Section titled “GET /api/orgs/{org\_id}/integrations/configured/{integration\_id}”](#get-apiorgsorg_idintegrationsconfiguredintegration_id)
Get Configured Integration
Get a single configured integration.
Requires membership in the organization. Secret params are redacted.
**Parameters**
| Name | In | Type | Required | Description |
| --------------- | ---- | --------------- | -------- | ----------- |
| integration\_id | path | `string (uuid)` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ------------------------------- |
| 200 | Successful Response | `ConfiguredIntegrationResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### PATCH `/api/orgs/{org_id}/integrations/configured/{integration_id}`
[Section titled “PATCH /api/orgs/{org\_id}/integrations/configured/{integration\_id}”](#patch-apiorgsorg_idintegrationsconfiguredintegration_id)
Update Configured Integration
Update a configured integration.
Any org member may update integrations for now — see issue #260. A PRIVATE row owned by someone else 404s. Params are merged (partial update).
For MCP\_SERVER integrations the tool-definition cache is invalidated after a successful update so that stale metadata (e.g. from a URL or credential change) is not served to agents.
**Parameters**
| Name | In | Type | Required | Description |
| --------------- | ---- | --------------- | -------- | ----------- |
| integration\_id | path | `string (uuid)` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Request body** (required)
| Field | Type | Required | Description |
| ----------- | -------- | -------- | ----------- |
| app\_name | `string` | no | |
| description | `string` | no | |
| name | `string` | no | |
| params | `object` | no | |
| slug | `string` | no | |
| status | `string` | no | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ------------------------------- |
| 200 | Successful Response | `ConfiguredIntegrationResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### DELETE `/api/orgs/{org_id}/integrations/configured/{integration_id}`
[Section titled “DELETE /api/orgs/{org\_id}/integrations/configured/{integration\_id}”](#delete-apiorgsorg_idintegrationsconfiguredintegration_id)
Delete Configured Integration
Delete a configured integration.
Any org member may delete integrations for now — see issue #260. A PRIVATE row owned by someone else 404s.
**Parameters**
| Name | In | Type | Required | Description |
| --------------- | ---- | --------------- | -------- | ----------- |
| integration\_id | path | `string (uuid)` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 204 | Successful Response | |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/integrations/types`
[Section titled “GET /api/orgs/{org\_id}/integrations/types”](#get-apiorgsorg_idintegrationstypes)
List Integration Types
List available integration types from the registry.
Requires membership in the organization.
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ----------------------------- |
| 200 | Successful Response | `IntegrationTypeListResponse` |
| 422 | Validation Error | `HTTPValidationError` |
# Org Settings
> REST API reference for org settings.
### GET `/api/orgs/{org_id}/model-config`
[Section titled “GET /api/orgs/{org\_id}/model-config”](#get-apiorgsorg_idmodel-config)
Get Model Config
Return the org’s model policy (allowlists + defaults) per scope.
Readable by any org member — it drives client-side model-picker filtering and default selection. The real enforcement is server-side (agent CRUD + chat send), so this endpoint carries no secrets and no budget data.
Requires membership.
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `ModelConfigResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/settings/ai`
[Section titled “GET /api/orgs/{org\_id}/settings/ai”](#get-apiorgsorg_idsettingsai)
Get Ai Settings
Get AI provider settings for the organization (secrets redacted).
Requires ADMIN or OWNER role.
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ---------------------------- |
| 200 | Successful Response | `AIProviderSettingsResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### PATCH `/api/orgs/{org_id}/settings/ai`
[Section titled “PATCH /api/orgs/{org\_id}/settings/ai”](#patch-apiorgsorg_idsettingsai)
Update Ai Settings
Update AI provider settings for the organization.
Requires ADMIN or OWNER role. Only fields present in the request body are updated; omitted fields are left unchanged.
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
**Request body** (required)
| Field | Type | Required | Description |
| ----------------------------- | ------------------------------------- | -------- | ----------- |
| ai\_gateway\_account\_id | `string` | no | |
| ai\_gateway\_gateway\_id | `string` | no | |
| ai\_gateway\_log\_payloads | `string` | no | |
| ai\_gateway\_mode | `""` \| `"custom"` \| `"off"` | no | |
| ai\_gateway\_token | `string` | no | |
| anthropic\_api\_key | `string` | no | |
| anthropic\_base\_url | `string` | no | |
| anthropic\_credential\_source | `""` \| `"api_key"` \| `"cloudflare"` | no | |
| anthropic\_enabled | `""` \| `"true"` \| `"false"` | no | |
| openai\_api\_key | `string` | no | |
| openai\_base\_url | `string` | no | |
| openai\_credential\_source | `""` \| `"api_key"` \| `"cloudflare"` | no | |
| openai\_enabled | `""` \| `"true"` \| `"false"` | no | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ---------------------------- |
| 200 | Successful Response | `AIProviderSettingsResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/settings/limits`
[Section titled “GET /api/orgs/{org\_id}/settings/limits”](#get-apiorgsorg_idsettingslimits)
Get Org Limits
Get model governance (two allowlists + defaults) and budget for the org.
Requires ADMIN or OWNER role.
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `OrgLimitsResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### PATCH `/api/orgs/{org_id}/settings/limits`
[Section titled “PATCH /api/orgs/{org\_id}/settings/limits”](#patch-apiorgsorg_idsettingslimits)
Update Org Limits
Update the org’s two model allowlists, default models, and/or budget.
Only fields present in the request body are updated; omitted fields are left unchanged. For default-model fields, an explicit `null` clears the default.
Invariant: when a scope’s allowlist is non-empty, its default model must be set and within the allowlist (422 otherwise). Response `affected_agents` lists agents left outside the (new) agent allowlist — they downgrade to the agent default at run time.
Requires ADMIN or OWNER role.
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
**Request body** (required)
| Field | Type | Required | Description |
| ---------------------------- | ------------------------ | -------- | ----------- |
| agent\_default\_model | `DefaultModel` | no | |
| agent\_model\_allowlist | `string[]` | no | |
| budget\_limit\_usd | `string` | no | |
| chat\_default\_model | `DefaultModel` | no | |
| chat\_model\_allowlist | `string[]` | no | |
| process\_default\_model | `DefaultModel` | no | |
| prompt\_model\_allowlist | `string[]` | no | |
| tool\_router\_default\_model | `ToolRouterDefaultModel` | no | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `OrgLimitsResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/settings/limits/usage`
[Section titled “GET /api/orgs/{org\_id}/settings/limits/usage”](#get-apiorgsorg_idsettingslimitsusage)
Get Org Limits Usage
Get the org’s current spend vs. its configured budget cap.
Returns two spend figures (M11 — see `OrgLimitsUsageResponse`): the chat-attributed total the budget cap enforces against (`spend_usd`) and the fuller metered total including chat-less LLM calls (`metered_spend_usd`), so the two no longer read as unlabelled disagreeing numbers. Useful for the admin limits panel.
Requires ADMIN or OWNER role.
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ------------------------ |
| 200 | Successful Response | `OrgLimitsUsageResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/settings/runtime`
[Section titled “GET /api/orgs/{org\_id}/settings/runtime”](#get-apiorgsorg_idsettingsruntime)
Get Runtime Settings
Get the org’s AI runtime overrides (compaction + model thinking).
A null field means the org inherits; `platform_defaults` says what that inheritance currently resolves to.
Requires ADMIN or OWNER role.
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ---------------------------- |
| 200 | Successful Response | `OrgRuntimeSettingsResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### PATCH `/api/orgs/{org_id}/settings/runtime`
[Section titled “PATCH /api/orgs/{org\_id}/settings/runtime”](#patch-apiorgsorg_idsettingsruntime)
Update Runtime Settings
Set (or clear) the org’s AI runtime overrides.
Omitted fields are left unchanged; an explicit `null` drops the override so the setting falls back to the platform tier. Values are re-read at the start of every run, so a change here lands on the next turn.
Requires ADMIN or OWNER role.
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
**Request body** (required)
| Field | Type | Required | Description |
| --------------------- | --------- | -------- | ----------- |
| compaction\_enabled | `boolean` | no | |
| compaction\_threshold | `number` | no | |
| thinking\_enabled | `boolean` | no | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ---------------------------- |
| 200 | Successful Response | `OrgRuntimeSettingsResponse` |
| 422 | Validation Error | `HTTPValidationError` |
# Org Variables
> REST API reference for org variables.
### GET `/api/orgs/{org_id}/variables`
[Section titled “GET /api/orgs/{org\_id}/variables”](#get-apiorgsorg_idvariables)
List Variables
List all user-defined variables for the organization (secrets redacted).
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ----------------------- |
| 200 | Successful Response | `OrgVariableResponse[]` |
| 422 | Validation Error | `HTTPValidationError` |
### POST `/api/orgs/{org_id}/variables`
[Section titled “POST /api/orgs/{org\_id}/variables”](#post-apiorgsorg_idvariables)
Create Variable
Create a new user-defined variable.
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
**Request body** (required)
| Field | Type | Required | Description |
| ----------- | --------- | -------- | ----------- |
| description | `string` | no | |
| is\_secret | `boolean` | no | |
| key | `string` | yes | |
| value | `string` | no | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 201 | Successful Response | `OrgVariableResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### PUT `/api/orgs/{org_id}/variables/{variable_id}`
[Section titled “PUT /api/orgs/{org\_id}/variables/{variable\_id}”](#put-apiorgsorg_idvariablesvariable_id)
Update Variable
Update the value of a variable.
**Parameters**
| Name | In | Type | Required | Description |
| ------------ | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
| variable\_id | path | `string (uuid)` | yes | |
**Request body** (required)
| Field | Type | Required | Description |
| ----------- | -------- | -------- | ----------- |
| description | `string` | no | |
| value | `string` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `OrgVariableResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### DELETE `/api/orgs/{org_id}/variables/{variable_id}`
[Section titled “DELETE /api/orgs/{org\_id}/variables/{variable\_id}”](#delete-apiorgsorg_idvariablesvariable_id)
Delete Variable
Delete a user-defined variable. System variables cannot be deleted.
**Parameters**
| Name | In | Type | Required | Description |
| ------------ | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
| variable\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 204 | Successful Response | |
| 422 | Validation Error | `HTTPValidationError` |
# Organizations
> REST API reference for organizations.
### GET `/api/orgs`
[Section titled “GET /api/orgs”](#get-apiorgs)
List Orgs
List all organizations the authenticated user belongs to.
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `OrgResponse[]` |
| 422 | Validation Error | `HTTPValidationError` |
### POST `/api/orgs`
[Section titled “POST /api/orgs”](#post-apiorgs)
Create Org
Create a new organization.
The authenticated user becomes the OWNER of the new organization. With no `slug` the service derives and uniquifies one from the name; an explicit slug is validated (shape, length, reserved words) and must be free.
**Request body** (required)
| Field | Type | Required | Description |
| ----------- | -------- | -------- | ----------- |
| description | `string` | no | |
| name | `string` | yes | |
| slug | `string` | no | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 201 | Successful Response | `OrgResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}`
[Section titled “GET /api/orgs/{org\_id}”](#get-apiorgsorg_id)
Get Org
Get organization details.
Requires membership in the organization (user) or belonging to it (agent).
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `OrgResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### PATCH `/api/orgs/{org_id}`
[Section titled “PATCH /api/orgs/{org\_id}”](#patch-apiorgsorg_id)
Update Org
Update organization details.
Requires ADMIN or OWNER role.
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
**Request body** (required)
| Field | Type | Required | Description |
| ----------- | -------- | -------- | ----------- |
| description | `string` | no | |
| name | `string` | no | |
| slug | `string` | no | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `OrgResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### DELETE `/api/orgs/{org_id}`
[Section titled “DELETE /api/orgs/{org\_id}”](#delete-apiorgsorg_id)
Delete Org
Delete an organization.
Requires OWNER role.
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 204 | Successful Response | |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/slug-rules`
[Section titled “GET /api/orgs/slug-rules”](#get-apiorgsslug-rules)
Get Slug Rules
The rules an organization address must satisfy.
Served so the create-organization wizard can flag a reserved or malformed address as the user types, without a hand-copied duplicate of the reserved list rotting in the frontend. The server-side check in `create_org` is still the authority.
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `SlugRulesResponse` |
| 422 | Validation Error | `HTTPValidationError` |
# Overview
> REST API reference for overview.
### GET `/api/orgs/{org_id}/overview`
[Section titled “GET /api/orgs/{org\_id}/overview”](#get-apiorgsorg_idoverview)
Get Overview
Aggregate dashboard overview for an org.
`since` scopes the work/cost stats and errored-chat count; inventory, recent activity, and the paused-chat breakdown are current-state and window-independent.
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ----- | --------------- | -------- | ---------------------------------------- |
| org\_id | path | `string (uuid)` | yes | |
| since | query | `string` | no | Stats window: 24h, 7d, 30d (default 30d) |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `OverviewResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/overview/recent-chats`
[Section titled “GET /api/orgs/{org\_id}/overview/recent-chats”](#get-apiorgsorg_idoverviewrecent-chats)
List Recent Chats
Paginated recent chats, for infinite-scrolling sidebar lists.
Unlike `recent_chats` on the main overview payload (fixed, capped at 20, attention chats surfaced first), this excludes attention-requiring chats entirely — those are handled by the top-bar “Needs attention” dropdown — and supports paging through the rest.
**Parameters**
| Name | In | Type | Required | Description |
| --------- | ----- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
| page | query | `integer` | no | |
| per\_page | query | `integer` | no | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ------------------------- |
| 200 | Successful Response | `RecentChatsPageResponse` |
| 422 | Validation Error | `HTTPValidationError` |
# Processes
> REST API reference for processes.
### GET `/api/orgs/{org_id}/processes`
[Section titled “GET /api/orgs/{org\_id}/processes”](#get-apiorgsorg_idprocesses)
List Processes
List processes for the organization.
Omit `limit` to get every process; `total` is the full count either way.
**Parameters**
| Name | In | Type | Required | Description |
| ----------- | ----- | --------------- | -------- | ------------------------------------------------------------ |
| limit | query | `integer` | no | Max rows to return (1-100). Omit to return every row. |
| offset | query | `integer` | no | Rows to skip — pass the previous response’s `next_offset`. |
| org\_id | path | `string (uuid)` | yes | |
| project\_id | query | `string` | no | Filter by project id, or ‘none’ for uncategorized processes. |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ----------------------- |
| 200 | Successful Response | `Page_ProcessResponse_` |
| 422 | Validation Error | `HTTPValidationError` |
### POST `/api/orgs/{org_id}/processes`
[Section titled “POST /api/orgs/{org\_id}/processes”](#post-apiorgsorg_idprocesses)
Create Process
Create a process (no revision yet). Requires admin/owner role.
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
**Request body** (required)
| Field | Type | Required | Description |
| ----------- | -------- | -------- | ----------- |
| description | `string` | no | |
| name | `string` | yes | |
| title | `string` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 201 | Successful Response | `ProcessResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/processes/{process_id}`
[Section titled “GET /api/orgs/{org\_id}/processes/{process\_id}”](#get-apiorgsorg_idprocessesprocess_id)
Get Process
Get a process, including its current deployed revision (if any).
**Parameters**
| Name | In | Type | Required | Description |
| ----------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
| process\_id | path | `string` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `ProcessResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### PATCH `/api/orgs/{org_id}/processes/{process_id}`
[Section titled “PATCH /api/orgs/{org\_id}/processes/{process\_id}”](#patch-apiorgsorg_idprocessesprocess_id)
Update Process
Update a process’s title/description. Requires admin/owner role.
**Parameters**
| Name | In | Type | Required | Description |
| ----------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
| process\_id | path | `string` | yes | |
**Request body** (required)
| Field | Type | Required | Description |
| ----------- | -------- | -------- | ----------- |
| description | `string` | yes | |
| title | `string` | no | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `ProcessResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### DELETE `/api/orgs/{org_id}/processes/{process_id}`
[Section titled “DELETE /api/orgs/{org\_id}/processes/{process\_id}”](#delete-apiorgsorg_idprocessesprocess_id)
Delete Process
Soft-delete a process. Requires admin/owner role.
**Parameters**
| Name | In | Type | Required | Description |
| ----------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
| process\_id | path | `string` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 204 | Successful Response | |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/processes/{process_id}/revisions`
[Section titled “GET /api/orgs/{org\_id}/processes/{process\_id}/revisions”](#get-apiorgsorg_idprocessesprocess_idrevisions)
List Revisions
List a process’s revisions, newest version first.
Not itself in the Phase-1 milestone’s endpoint list, but the CLI’s `deploy --revision N` (and “deploy latest”) need a way to resolve a version to a revision id, so it’s added here as the minimal completion.
**Parameters**
| Name | In | Type | Required | Description |
| ----------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
| process\_id | path | `string` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------------- |
| 200 | Successful Response | `ProcessRevisionResponse[]` |
| 422 | Validation Error | `HTTPValidationError` |
### POST `/api/orgs/{org_id}/processes/{process_id}/revisions`
[Section titled “POST /api/orgs/{org\_id}/processes/{process\_id}/revisions”](#post-apiorgsorg_idprocessesprocess_idrevisions)
Push Revision
Push a draft revision from a definition. Requires admin/owner role.
Parse errors return 422 carrying the validator’s plain wording (step id, field, what is wrong, what is valid) rather than the raw pydantic dump. Pushing a definition whose hash matches the latest revision is a no-op — the existing revision is returned (200) instead of creating a duplicate.
**Parameters**
| Name | In | Type | Required | Description |
| ----------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
| process\_id | path | `string` | yes | |
**Request body** (required)
| Field | Type | Required | Description |
| ---------- | -------- | -------- | ----------- |
| definition | `object` | yes | |
| sop\_text | `string` | no | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ------------------------- |
| 201 | Successful Response | `ProcessRevisionResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### POST `/api/orgs/{org_id}/processes/{process_id}/revisions/{revision_id}/deploy`
[Section titled “POST /api/orgs/{org\_id}/processes/{process\_id}/revisions/{revision\_id}/deploy”](#post-apiorgsorg_idprocessesprocess_idrevisionsrevision_iddeploy)
Deploy Revision
Validate + deploy a draft revision. Requires admin/owner role.
Validation errors return 422 with `{errors, warnings}` in the validator’s plain-language wording, verbatim. On success the revision’s tool snapshot is pinned, the previously-deployed revision is archived, and the process’s `stale_reason` is cleared (a re-deploy is the re-evaluation).
**Parameters**
| Name | In | Type | Required | Description |
| ------------ | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
| process\_id | path | `string` | yes | |
| revision\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `DeployResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/processes/{process_id}/runs`
[Section titled “GET /api/orgs/{org\_id}/processes/{process\_id}/runs”](#get-apiorgsorg_idprocessesprocess_idruns)
List Runs
List runs for a process, newest first. Optional `status` filter.
**Parameters**
| Name | In | Type | Required | Description |
| ----------- | ----- | --------------- | -------- | ----------- |
| limit | query | `integer` | no | |
| offset | query | `integer` | no | |
| org\_id | path | `string (uuid)` | yes | |
| process\_id | path | `string` | yes | |
| status | query | `string` | no | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ------------------------ |
| 200 | Successful Response | `ProcessRunListResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/processes/{process_id}/runs/{run_id}`
[Section titled “GET /api/orgs/{org\_id}/processes/{process\_id}/runs/{run\_id}”](#get-apiorgsorg_idprocessesprocess_idrunsrun_id)
Get Run
Get a run’s detail, including its steps ordered by creation time.
**Parameters**
| Name | In | Type | Required | Description |
| ----------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
| process\_id | path | `string` | yes | |
| run\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | -------------------------- |
| 200 | Successful Response | `ProcessRunDetailResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/processes/{process_id}/runs/{run_id}/agent-calls`
[Section titled “GET /api/orgs/{org\_id}/processes/{process\_id}/runs/{run\_id}/agent-calls”](#get-apiorgsorg_idprocessesprocess_idrunsrun_idagent-calls)
List Run Agent Calls
Scalar-only index of a run’s `agent` block step turns/distill calls.
**Parameters**
| Name | In | Type | Required | Description |
| ----------- | ----- | --------------- | -------- | ----------- |
| limit | query | `integer` | no | |
| offset | query | `integer` | no | |
| org\_id | path | `string (uuid)` | yes | |
| process\_id | path | `string` | yes | |
| run\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ------------------------------ |
| 200 | Successful Response | `ProcessAgentCallListResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/processes/{process_id}/runs/{run_id}/agent-calls/{call_id}`
[Section titled “GET /api/orgs/{org\_id}/processes/{process\_id}/runs/{run\_id}/agent-calls/{call\_id}”](#get-apiorgsorg_idprocessesprocess_idrunsrun_idagent-callscall_id)
Get Run Agent Call
Full detail (incl. request/response messages) for one agent-step call.
**Parameters**
| Name | In | Type | Required | Description |
| ----------- | ---- | --------------- | -------- | ----------- |
| call\_id | path | `string (uuid)` | yes | |
| org\_id | path | `string (uuid)` | yes | |
| process\_id | path | `string` | yes | |
| run\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | -------------------------------- |
| 200 | Successful Response | `ProcessAgentCallDetailResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### POST `/api/orgs/{org_id}/processes/{process_id}/runs/{run_id}/cancel`
[Section titled “POST /api/orgs/{org\_id}/processes/{process\_id}/runs/{run\_id}/cancel”](#post-apiorgsorg_idprocessesprocess_idrunsrun_idcancel)
Cancel Run
Cancel a running / human-waiting run.
Tombstones the run row (step children check it at every step boundary) and cancels the durable Hatchet parent plus any in-flight step children. A run already in a terminal state is a no-op (`cancelled: false`).
**Parameters**
| Name | In | Type | Required | Description |
| ----------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
| process\_id | path | `string` | yes | |
| run\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `CancelRunResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/processes/{process_id}/runs/{run_id}/events`
[Section titled “GET /api/orgs/{org\_id}/processes/{process\_id}/runs/{run\_id}/events”](#get-apiorgsorg_idprocessesprocess_idrunsrun_idevents)
List Run Events
A run’s timeline, ordered oldest first.
**Parameters**
| Name | In | Type | Required | Description |
| ----------- | ----- | --------------- | -------- | ----------- |
| limit | query | `integer` | no | |
| offset | query | `integer` | no | |
| org\_id | path | `string (uuid)` | yes | |
| process\_id | path | `string` | yes | |
| run\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ----------------------------- |
| 200 | Successful Response | `ProcessRunEventListResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/processes/{process_id}/runs/{run_id}/llm-calls`
[Section titled “GET /api/orgs/{org\_id}/processes/{process\_id}/runs/{run\_id}/llm-calls”](#get-apiorgsorg_idprocessesprocess_idrunsrun_idllm-calls)
List Run Llm Calls
Scalar-only index of a run’s `llm`/`prompt` block exchanges.
The heavy `request_messages`/`response_message` JSONB is never loaded — use `GET .../llm-calls/{call_id}` for the full exchange.
**Parameters**
| Name | In | Type | Required | Description |
| ----------- | ----- | --------------- | -------- | ----------- |
| limit | query | `integer` | no | |
| offset | query | `integer` | no | |
| org\_id | path | `string (uuid)` | yes | |
| process\_id | path | `string` | yes | |
| run\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ---------------------------- |
| 200 | Successful Response | `ProcessLlmCallListResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/processes/{process_id}/runs/{run_id}/llm-calls/{call_id}`
[Section titled “GET /api/orgs/{org\_id}/processes/{process\_id}/runs/{run\_id}/llm-calls/{call\_id}”](#get-apiorgsorg_idprocessesprocess_idrunsrun_idllm-callscall_id)
Get Run Llm Call
Full detail (incl. request/response messages) for one LLM call.
**Parameters**
| Name | In | Type | Required | Description |
| ----------- | ---- | --------------- | -------- | ----------- |
| call\_id | path | `string (uuid)` | yes | |
| org\_id | path | `string (uuid)` | yes | |
| process\_id | path | `string` | yes | |
| run\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ------------------------------ |
| 200 | Successful Response | `ProcessLlmCallDetailResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/processes/{process_id}/runs/{run_id}/repairs`
[Section titled “GET /api/orgs/{org\_id}/processes/{process\_id}/runs/{run\_id}/repairs”](#get-apiorgsorg_idprocessesprocess_idrunsrun_idrepairs)
List Run Repairs
Index of a run’s tool-payload repair verdicts.
The scalar/text fields (`tool_slug`/`error`/`fixable`/`reason`/ `payload_diff`) ARE the payload here; the heavy raw exchange is still excluded — use `GET .../repairs/{call_id}` for that.
**Parameters**
| Name | In | Type | Required | Description |
| ----------- | ----- | --------------- | -------- | ----------- |
| limit | query | `integer` | no | |
| offset | query | `integer` | no | |
| org\_id | path | `string (uuid)` | yes | |
| process\_id | path | `string` | yes | |
| run\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ------------------------------- |
| 200 | Successful Response | `ProcessRepairCallListResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/processes/{process_id}/runs/{run_id}/repairs/{call_id}`
[Section titled “GET /api/orgs/{org\_id}/processes/{process\_id}/runs/{run\_id}/repairs/{call\_id}”](#get-apiorgsorg_idprocessesprocess_idrunsrun_idrepairscall_id)
Get Run Repair
Full detail (incl. request/response messages) for one repair call.
**Parameters**
| Name | In | Type | Required | Description |
| ----------- | ---- | --------------- | -------- | ----------- |
| call\_id | path | `string (uuid)` | yes | |
| org\_id | path | `string (uuid)` | yes | |
| process\_id | path | `string` | yes | |
| run\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------------------- |
| 200 | Successful Response | `ProcessRepairCallDetailResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### POST `/api/orgs/{org_id}/processes/{process_id}/runs/{run_id}/restart`
[Section titled “POST /api/orgs/{org\_id}/processes/{process\_id}/runs/{run\_id}/restart”](#post-apiorgsorg_idprocessesprocess_idrunsrun_idrestart)
Restart Run
Restart a terminal run as a brand-new run on the process’s current deployed revision.
Only terminal runs (`completed` / `flagged` / `failed` / `cancelled`) can be restarted — an active run (`running` / `waiting_human`) must be cancelled first. The new run replays the old run’s envelope against whatever revision is *currently* deployed (by design — restart always runs the current revision, not a pinned replay) and does not touch the original run.
**Parameters**
| Name | In | Type | Required | Description |
| ----------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
| process\_id | path | `string` | yes | |
| run\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 201 | Successful Response | `ProcessRunResponse` |
| 422 | Validation Error | `HTTPValidationError` |
# Projects
> REST API reference for projects.
### GET `/api/orgs/{org_id}/projects`
[Section titled “GET /api/orgs/{org\_id}/projects”](#get-apiorgsorg_idprojects)
List Projects
List all projects in the organization, with resource counts by type.
Omit `limit` to get every project; `total` is the full count either way. `uncategorized_count` is always the whole-org count, independent of the page being viewed.
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ----- | --------------- | -------- | ---------------------------------------------------------- |
| limit | query | `integer` | no | Max rows to return (1-100). Omit to return every row. |
| offset | query | `integer` | no | Rows to skip — pass the previous response’s `next_offset`. |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `ProjectListResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### POST `/api/orgs/{org_id}/projects`
[Section titled “POST /api/orgs/{org\_id}/projects”](#post-apiorgsorg_idprojects)
Create Project
Create a new project. Requires admin/owner role.
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
**Request body** (required)
| Field | Type | Required | Description |
| ----------- | -------- | -------- | ----------- |
| color | `string` | no | |
| description | `string` | no | |
| icon | `string` | no | |
| name | `string` | yes | |
| slug | `string` | no | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 201 | Successful Response | `ProjectResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/projects/{project_id}`
[Section titled “GET /api/orgs/{org\_id}/projects/{project\_id}”](#get-apiorgsorg_idprojectsproject_id)
Get Project
Get a project’s detail, including resource counts by type.
**Parameters**
| Name | In | Type | Required | Description |
| ----------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
| project\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `ProjectResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### PATCH `/api/orgs/{org_id}/projects/{project_id}`
[Section titled “PATCH /api/orgs/{org\_id}/projects/{project\_id}”](#patch-apiorgsorg_idprojectsproject_id)
Update Project
Update a project’s name/slug/description/color/icon. Requires admin/owner role.
Only fields present in the request body are applied; pass `null` to clear `description`, `color`, or `icon`.
**Parameters**
| Name | In | Type | Required | Description |
| ----------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
| project\_id | path | `string (uuid)` | yes | |
**Request body** (required)
| Field | Type | Required | Description |
| ----------- | -------- | -------- | ----------- |
| color | `string` | no | |
| description | `string` | no | |
| icon | `string` | no | |
| name | `string` | no | |
| slug | `string` | no | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `ProjectResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### DELETE `/api/orgs/{org_id}/projects/{project_id}`
[Section titled “DELETE /api/orgs/{org\_id}/projects/{project\_id}”](#delete-apiorgsorg_idprojectsproject_id)
Delete Project
Soft-delete a project. Requires admin/owner role.
Membership rows are hard-deleted; bundled resources are NOT deleted — they become uncategorized.
**Parameters**
| Name | In | Type | Required | Description |
| ----------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
| project\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 204 | Successful Response | |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/projects/{project_id}/resources`
[Section titled “GET /api/orgs/{org\_id}/projects/{project\_id}/resources”](#get-apiorgsorg_idprojectsproject_idresources)
List Project Resources
List a project’s member resources, resolved to display data.
Dangling rows (the referenced entity was deleted) are skipped gracefully.
**Parameters**
| Name | In | Type | Required | Description |
| ----------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
| project\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | -------------------------- |
| 200 | Successful Response | `ProjectResourcesResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### POST `/api/orgs/{org_id}/projects/{project_id}/resources`
[Section titled “POST /api/orgs/{org\_id}/projects/{project\_id}/resources”](#post-apiorgsorg_idprojectsproject_idresources)
Add Project Resources
Batch-add resources to a project. Requires admin/owner role.
A resource already in another project is moved (a resource belongs to at most one project). Validates every entity exists in this org; 422 if any don’t (this also rejects system skills, since `org_id IS NULL` skills never match an org-scoped lookup).
**Parameters**
| Name | In | Type | Required | Description |
| ----------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
| project\_id | path | `string (uuid)` | yes | |
**Request body** (required)
| Field | Type | Required | Description |
| --------- | --------------- | -------- | ----------- |
| resources | `ResourceRef[]` | no | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ---------------------- |
| 200 | Successful Response | `AddResourcesResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### DELETE `/api/orgs/{org_id}/projects/{project_id}/resources/{entity_type}/{entity_id}`
[Section titled “DELETE /api/orgs/{org\_id}/projects/{project\_id}/resources/{entity\_type}/{entity\_id}”](#delete-apiorgsorg_idprojectsproject_idresourcesentity_typeentity_id)
Remove Project Resource
Remove one resource from a project. Requires admin/owner role.
The resource is NOT deleted — it becomes uncategorized.
**Parameters**
| Name | In | Type | Required | Description |
| ------------ | ---- | --------------------- | -------- | ----------- |
| entity\_id | path | `string (uuid)` | yes | |
| entity\_type | path | `ProjectResourceType` | yes | |
| org\_id | path | `string (uuid)` | yes | |
| project\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 204 | Successful Response | |
| 422 | Validation Error | `HTTPValidationError` |
# Prompt Templates
> REST API reference for prompt templates.
### GET `/api/orgs/{org_id}/prompt-templates`
[Section titled “GET /api/orgs/{org\_id}/prompt-templates”](#get-apiorgsorg_idprompt-templates)
List Prompt Templates
List prompt templates for the organization.
Omit `limit` to get every template; `total` is the full count either way.
**Parameters**
| Name | In | Type | Required | Description |
| ----------- | ----- | --------------- | -------- | ------------------------------------------------------------ |
| limit | query | `integer` | no | Max rows to return (1-100). Omit to return every row. |
| offset | query | `integer` | no | Rows to skip — pass the previous response’s `next_offset`. |
| org\_id | path | `string (uuid)` | yes | |
| project\_id | query | `string` | no | Filter by project id, or ‘none’ for uncategorized templates. |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ------------------------------ |
| 200 | Successful Response | `Page_PromptTemplateResponse_` |
| 422 | Validation Error | `HTTPValidationError` |
### POST `/api/orgs/{org_id}/prompt-templates`
[Section titled “POST /api/orgs/{org\_id}/prompt-templates”](#post-apiorgsorg_idprompt-templates)
Create Prompt Template
Create a new prompt template. Requires admin/owner role.
`fields` (optional) defines an extraction schema — when present, the template runs as structured extraction instead of free-text generation.
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
**Request body** (required)
| Field | Type | Required | Description |
| ------------------------------ | --------------------------------------------- | -------- | ----------- |
| description | `string` | no | |
| fields | `PromptFieldSchema[]` | no | |
| file\_input\_mode | `"auto"` \| `"image"` \| `"text"` \| `"both"` | no | |
| model | `string` | no | |
| name | `string` | yes | |
| post\_processing\_instructions | `string` | no | |
| provider | `string` | no | |
| reasoning\_effort | `string` | no | |
| tags | `string[]` | no | |
| text | `string` | no | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ------------------------ |
| 201 | Successful Response | `PromptTemplateResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/prompt-templates/{id_or_slug}`
[Section titled “GET /api/orgs/{org\_id}/prompt-templates/{id\_or\_slug}”](#get-apiorgsorg_idprompt-templatesid_or_slug)
Get Prompt Template
Get a prompt template by ID or slug.
**Parameters**
| Name | In | Type | Required | Description |
| ------------ | ---- | --------------- | -------- | ----------- |
| id\_or\_slug | path | `string` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ------------------------ |
| 200 | Successful Response | `PromptTemplateResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### POST `/api/orgs/{org_id}/prompt-templates/{id_or_slug}/test`
[Section titled “POST /api/orgs/{org\_id}/prompt-templates/{id\_or\_slug}/test”](#post-apiorgsorg_idprompt-templatesid_or_slugtest)
Test Prompt Template
Stream a test execution of a prompt template. Requires admin/owner role.
Drives BOTH modes via the unified `stream_prompt_test` runner: a plain prompt (no `fields` on the active revision) streams free-text `token`/`done` events; a schema-bearing prompt streams the structured `extracting`/`result`/`post_processing`/`done` events and requires material input via `input_text` or `input_url`.
**Parameters**
| Name | In | Type | Required | Description |
| ------------ | ---- | --------------- | -------- | ----------- |
| id\_or\_slug | path | `string` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Request body** (required)
| Field | Type | Required | Description |
| ----------------- | --------------------------------------------- | -------- | ----------- |
| attachments | `PromptTestAttachment[]` | no | |
| file\_input\_mode | `"auto"` \| `"image"` \| `"text"` \| `"both"` | no | |
| input\_text | `string` | no | |
| input\_url | `string` | no | |
| model | `string` | yes | |
| provider | `string` | yes | |
| reasoning\_effort | `string` | no | |
| variables | `object` | no | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `object` |
| 422 | Validation Error | `HTTPValidationError` |
### PUT `/api/orgs/{org_id}/prompt-templates/{template_id}`
[Section titled “PUT /api/orgs/{org\_id}/prompt-templates/{template\_id}”](#put-apiorgsorg_idprompt-templatestemplate_id)
Update Prompt Template
Update a prompt template by ID or slug. Requires admin/owner role.
Passing `text`, `fields`, or `post_processing_instructions` creates a new revision (versioned together as one snapshot).
**Parameters**
| Name | In | Type | Required | Description |
| ------------ | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
| template\_id | path | `string` | yes | |
**Request body** (required)
| Field | Type | Required | Description |
| ------------------------------ | --------------------------------------------- | -------- | ----------- |
| description | `string` | yes | |
| fields | `PromptFieldSchema[]` | no | |
| file\_input\_mode | `"auto"` \| `"image"` \| `"text"` \| `"both"` | yes | |
| model | `string` | yes | |
| name | `string` | no | |
| post\_processing\_instructions | `string` | no | |
| provider | `string` | yes | |
| reasoning\_effort | `string` | yes | |
| tags | `string[]` | no | |
| text | `string` | no | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ------------------------ |
| 200 | Successful Response | `PromptTemplateResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### DELETE `/api/orgs/{org_id}/prompt-templates/{template_id}`
[Section titled “DELETE /api/orgs/{org\_id}/prompt-templates/{template\_id}”](#delete-apiorgsorg_idprompt-templatestemplate_id)
Delete Prompt Template
Soft-delete a prompt template by ID or slug. Requires admin/owner role.
**Parameters**
| Name | In | Type | Required | Description |
| ------------ | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
| template\_id | path | `string` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 204 | Successful Response | |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/prompt-templates/{template_id}/revisions`
[Section titled “GET /api/orgs/{org\_id}/prompt-templates/{template\_id}/revisions”](#get-apiorgsorg_idprompt-templatestemplate_idrevisions)
List Prompt Template Revisions
List all revisions for a prompt template (by ID or slug).
**Parameters**
| Name | In | Type | Required | Description |
| ------------ | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
| template\_id | path | `string` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------------------- |
| 200 | Successful Response | `PromptTemplateRevisionSummary[]` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/prompt-templates/{template_id}/runs`
[Section titled “GET /api/orgs/{org\_id}/prompt-templates/{template\_id}/runs”](#get-apiorgsorg_idprompt-templatestemplate_idruns)
List Prompt Template Runs
List runs for a prompt template (by ID or slug).
**Parameters**
| Name | In | Type | Required | Description |
| ------------ | ----- | --------------- | -------- | ----------- |
| limit | query | `integer` | no | |
| offset | query | `integer` | no | |
| org\_id | path | `string (uuid)` | yes | |
| template\_id | path | `string` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ----------------------------- |
| 200 | Successful Response | `PromptTemplateRunResponse[]` |
| 422 | Validation Error | `HTTPValidationError` |
# Resources
> REST API reference for resources.
### GET `/api/orgs/{org_id}/resources`
[Section titled “GET /api/orgs/{org\_id}/resources”](#get-apiorgsorg_idresources)
List Available Resources
List resources available to add to bays.
Discovers resources from connected providers, filtered by capability.
**Parameters**
| Name | In | Type | Required | Description |
| ---------- | ----- | --------------- | -------- | ---------------------------------------------- |
| capability | query | `string` | yes | Filter by resource capability (e.g. ‘context’) |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | -------------------------------- |
| 200 | Successful Response | `AvailableResourcesListResponse` |
| 422 | Validation Error | `HTTPValidationError` |
# Schedules
> REST API reference for schedules.
### GET `/api/orgs/{org_id}/agents/{agent_id}/schedules`
[Section titled “GET /api/orgs/{org\_id}/agents/{agent\_id}/schedules”](#get-apiorgsorg_idagentsagent_idschedules)
List Agent Schedules
List all schedules for one agent, oldest first.
**Parameters**
| Name | In | Type | Required | Description |
| --------- | ---- | --------------- | -------- | ----------- |
| agent\_id | path | `string (uuid)` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `ScheduleResponse[]` |
| 422 | Validation Error | `HTTPValidationError` |
### POST `/api/orgs/{org_id}/agents/{agent_id}/schedules`
[Section titled “POST /api/orgs/{org\_id}/agents/{agent\_id}/schedules”](#post-apiorgsorg_idagentsagent_idschedules)
Create Schedule
Create a recurring cron schedule that fires this agent.
Requires ADMIN or OWNER role. `cron_expr` (standard 5-field) and `timezone` (IANA) are validated together; an invalid combination returns 422.
**Parameters**
| Name | In | Type | Required | Description |
| --------- | ---- | --------------- | -------- | ----------- |
| agent\_id | path | `string (uuid)` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Request body** (required)
| Field | Type | Required | Description |
| --------------- | ----------------------- | -------- | ----------- |
| cron\_expr | `string` | yes | |
| enabled | `boolean` | no | |
| overlap\_policy | `ScheduleOverlapPolicy` | no | |
| prompt | `string` | yes | |
| timezone | `string` | no | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 201 | Successful Response | `ScheduleResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/schedules`
[Section titled “GET /api/orgs/{org\_id}/schedules”](#get-apiorgsorg_idschedules)
List Org Schedules
List schedules in the org, each annotated with its agent’s name/slug.
Omit `limit` to get every schedule; `total` is the full count either way.
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ----- | --------------- | -------- | ---------------------------------------------------------- |
| limit | query | `integer` | no | Max rows to return (1-100). Omit to return every row. |
| offset | query | `integer` | no | Rows to skip — pass the previous response’s `next_offset`. |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------------------- |
| 200 | Successful Response | `Page_ScheduleWithAgentResponse_` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/schedules/{schedule_id}`
[Section titled “GET /api/orgs/{org\_id}/schedules/{schedule\_id}”](#get-apiorgsorg_idschedulesschedule_id)
Get Schedule
Get a single schedule’s detail.
**Parameters**
| Name | In | Type | Required | Description |
| ------------ | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
| schedule\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `ScheduleResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### PATCH `/api/orgs/{org_id}/schedules/{schedule_id}`
[Section titled “PATCH /api/orgs/{org\_id}/schedules/{schedule\_id}”](#patch-apiorgsorg_idschedulesschedule_id)
Update Schedule
Update any of prompt/cron\_expr/timezone/enabled/overlap\_policy.
Requires ADMIN or OWNER role. Recomputes `next_run_at` when `cron_expr`/`timezone`/`enabled` change; an invalid cron/timezone combination returns 422.
**Parameters**
| Name | In | Type | Required | Description |
| ------------ | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
| schedule\_id | path | `string (uuid)` | yes | |
**Request body** (required)
| Field | Type | Required | Description |
| --------------- | ----------------------- | -------- | ----------- |
| cron\_expr | `string` | no | |
| enabled | `boolean` | no | |
| overlap\_policy | `ScheduleOverlapPolicy` | no | |
| prompt | `string` | no | |
| timezone | `string` | no | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `ScheduleResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### DELETE `/api/orgs/{org_id}/schedules/{schedule_id}`
[Section titled “DELETE /api/orgs/{org\_id}/schedules/{schedule\_id}”](#delete-apiorgsorg_idschedulesschedule_id)
Delete Schedule
Soft-delete a schedule. Requires ADMIN or OWNER role.
**Parameters**
| Name | In | Type | Required | Description |
| ------------ | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
| schedule\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 204 | Successful Response | |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/schedules/{schedule_id}/runs`
[Section titled “GET /api/orgs/{org\_id}/schedules/{schedule\_id}/runs”](#get-apiorgsorg_idschedulesschedule_idruns)
List Schedule Runs
List the chats this schedule has fired (the correlation query), newest first.
**Parameters**
| Name | In | Type | Required | Description |
| ------------ | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
| schedule\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ----------------------- |
| 200 | Successful Response | `ScheduleRunResponse[]` |
| 422 | Validation Error | `HTTPValidationError` |
# Search
> REST API reference for search.
### GET `/api/orgs/{org_id}/search`
[Section titled “GET /api/orgs/{org\_id}/search”](#get-apiorgsorg_idsearch)
Global Search
Full-text search across conversations within an org.
**Parameters**
| Name | In | Type | Required | Description |
| --------- | ----- | --------------- | -------- | ----------------------------- |
| agent\_id | query | `string (uuid)` | no | Filter results by agent |
| limit | query | `integer` | no | Maximum results to return |
| offset | query | `integer` | no | Pagination offset |
| org\_id | path | `string (uuid)` | yes | |
| q | query | `string` | yes | Search query text |
| status | query | `ChatStatus[]` | no | Filter results by chat status |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ------------------------------------------------- |
| 200 | Successful Response | `agentdepot_api__routers__search__SearchResponse` |
| 422 | Validation Error | `HTTPValidationError` |
# Skills
> REST API reference for skills.
### GET `/api/orgs/{org_id}/skills`
[Section titled “GET /api/orgs/{org\_id}/skills”](#get-apiorgsorg_idskills)
List Skills
List skills in the organization.
Omit `limit` to get every skill; `total` is the full count either way.
**Parameters**
| Name | In | Type | Required | Description |
| ----------- | ----- | --------------- | -------- | ---------------------------------------------------------- |
| limit | query | `integer` | no | Max rows to return (1-100). Omit to return every row. |
| offset | query | `integer` | no | Rows to skip — pass the previous response’s `next_offset`. |
| org\_id | path | `string (uuid)` | yes | |
| project\_id | query | `string` | no | Filter by project id, or ‘none’ for uncategorized skills. |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `Page_SkillResponse_` |
| 422 | Validation Error | `HTTPValidationError` |
### POST `/api/orgs/{org_id}/skills`
[Section titled “POST /api/orgs/{org\_id}/skills”](#post-apiorgsorg_idskills)
Create Skill
Create a new skill. Requires admin/owner role.
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
**Request body** (required)
| Field | Type | Required | Description |
| ------------------- | ---------- | -------- | ----------- |
| description | `string` | no | |
| instructions | `string` | yes | |
| name | `string` | yes | |
| reference\_material | `string` | no | |
| slug | `string` | no | |
| tool\_slugs | `string[]` | no | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 201 | Successful Response | `SkillResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/skills/{id_or_slug}`
[Section titled “GET /api/orgs/{org\_id}/skills/{id\_or\_slug}”](#get-apiorgsorg_idskillsid_or_slug)
Get Skill
Get a skill by ID or slug, including active and draft revisions.
**Parameters**
| Name | In | Type | Required | Description |
| ------------ | ---- | --------------- | -------- | ----------- |
| id\_or\_slug | path | `string` | yes | |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `SkillResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### PUT `/api/orgs/{org_id}/skills/{skill_id}`
[Section titled “PUT /api/orgs/{org\_id}/skills/{skill\_id}”](#put-apiorgsorg_idskillsskill_id)
Update Skill
Update a skill. name/description update the parent; instructions/tool\_slugs/reference\_material go to a draft revision. Requires admin/owner role.
**Parameters**
| Name | In | Type | Required | Description |
| --------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
| skill\_id | path | `string (uuid)` | yes | |
**Request body** (required)
| Field | Type | Required | Description |
| ------------------- | ---------- | -------- | ----------- |
| description | `string` | no | |
| instructions | `string` | no | |
| name | `string` | no | |
| reference\_material | `string` | no | |
| tool\_slugs | `string[]` | no | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `SkillResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### DELETE `/api/orgs/{org_id}/skills/{skill_id}`
[Section titled “DELETE /api/orgs/{org\_id}/skills/{skill\_id}”](#delete-apiorgsorg_idskillsskill_id)
Delete Skill
Soft-delete a skill. Requires admin/owner role.
**Parameters**
| Name | In | Type | Required | Description |
| --------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
| skill\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 204 | Successful Response | |
| 422 | Validation Error | `HTTPValidationError` |
### POST `/api/orgs/{org_id}/skills/{skill_id}/deploy`
[Section titled “POST /api/orgs/{org\_id}/skills/{skill\_id}/deploy”](#post-apiorgsorg_idskillsskill_iddeploy)
Deploy Skill
Promote the draft revision to active. Requires admin/owner role.
**Parameters**
| Name | In | Type | Required | Description |
| --------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
| skill\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `SkillResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### DELETE `/api/orgs/{org_id}/skills/{skill_id}/draft`
[Section titled “DELETE /api/orgs/{org\_id}/skills/{skill\_id}/draft”](#delete-apiorgsorg_idskillsskill_iddraft)
Discard Skill Draft
Discard the draft revision for a skill. Requires admin/owner role.
**Parameters**
| Name | In | Type | Required | Description |
| --------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
| skill\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `SkillResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/skills/{skill_id}/revisions`
[Section titled “GET /api/orgs/{org\_id}/skills/{skill\_id}/revisions”](#get-apiorgsorg_idskillsskill_idrevisions)
List Skill Revisions
List all revisions for a skill, newest first.
**Parameters**
| Name | In | Type | Required | Description |
| --------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
| skill\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ------------------------- |
| 200 | Successful Response | `SkillRevisionResponse[]` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/skills/{skill_id}/usage`
[Section titled “GET /api/orgs/{org\_id}/skills/{skill\_id}/usage”](#get-apiorgsorg_idskillsskill_idusage)
Get Skill Usage
List activation records for a skill, newest first.
**Parameters**
| Name | In | Type | Required | Description |
| --------- | ----- | --------------- | -------- | ----------- |
| limit | query | `integer` | no | |
| org\_id | path | `string (uuid)` | yes | |
| skill\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------------------- |
| 200 | Successful Response | `SkillActivationRecordResponse[]` |
| 422 | Validation Error | `HTTPValidationError` |
# Tags
> REST API reference for tags.
### GET `/api/orgs/{org_id}/tags`
[Section titled “GET /api/orgs/{org\_id}/tags”](#get-apiorgsorg_idtags)
List Tags
List all tags in the org registry, ordered by name.
Omit `limit` to get every tag; `total` is the full count either way.
**Auth**: org member.
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ----- | --------------- | -------- | ---------------------------------------------------------- |
| limit | query | `integer` | no | Max rows to return (1-100). Omit to return every row. |
| offset | query | `integer` | no | Rows to skip — pass the previous response’s `next_offset`. |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `Page_TagRead_` |
| 422 | Validation Error | `HTTPValidationError` |
### POST `/api/orgs/{org_id}/tags`
[Section titled “POST /api/orgs/{org\_id}/tags”](#post-apiorgsorg_idtags)
Create Tag
Create a new tag in the org registry.
The name is normalized (lowercased, trimmed) before storage. If a tag with the resulting name already exists, the existing tag is returned (idempotent).
**Auth**: org admin/owner.
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
**Request body** (required)
| Field | Type | Required | Description |
| ----------- | -------- | -------- | --------------------------------------------------- |
| color | `string` | no | Optional color hex/name. |
| description | `string` | no | Optional human-readable description. |
| name | `string` | yes | Tag name. Will be normalized (lowercased, trimmed). |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 201 | Successful Response | `TagRead` |
| 422 | Validation Error | `HTTPValidationError` |
### PATCH `/api/orgs/{org_id}/tags/{tag_id}`
[Section titled “PATCH /api/orgs/{org\_id}/tags/{tag\_id}”](#patch-apiorgsorg_idtagstag_id)
Update Tag
Update a tag’s name, color, or description.
Only fields present in the request body are applied. Pass `null` to clear `color` or `description`.
**Auth**: org admin/owner.
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
| tag\_id | path | `string (uuid)` | yes | |
**Request body** (required)
| Field | Type | Required | Description |
| ----------- | -------- | -------- | ----------- |
| color | `string` | no | |
| description | `string` | no | |
| name | `string` | no | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `TagRead` |
| 422 | Validation Error | `HTTPValidationError` |
### DELETE `/api/orgs/{org_id}/tags/{tag_id}`
[Section titled “DELETE /api/orgs/{org\_id}/tags/{tag\_id}”](#delete-apiorgsorg_idtagstag_id)
Delete Tag
Soft-delete a tag from the registry.
Also removes all entity-tag associations for this tag.
**Auth**: org admin/owner.
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
| tag\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 204 | Successful Response | |
| 422 | Validation Error | `HTTPValidationError` |
# API Tokens
> REST API reference for api tokens.
### GET `/api/tokens`
[Section titled “GET /api/tokens”](#get-apitokens)
List Tokens
List all API tokens for the current user.
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `TokenListResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### POST `/api/tokens`
[Section titled “POST /api/tokens”](#post-apitokens)
Create Token
Create a new API token.
The plain token is only returned once in this response. Store it securely - it cannot be retrieved again.
**Request body** (required)
| Field | Type | Required | Description |
| ----------- | -------- | -------- | ----------- |
| description | `string` | no | |
| name | `string` | yes | |
| scope | `string` | no | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 201 | Successful Response | `CreateTokenResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### DELETE `/api/tokens/{token_id}`
[Section titled “DELETE /api/tokens/{token\_id}”](#delete-apitokenstoken_id)
Revoke Token
Revoke an API token.
**Parameters**
| Name | In | Type | Required | Description |
| --------- | ---- | --------------- | -------- | ----------- |
| token\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 204 | Successful Response | |
| 422 | Validation Error | `HTTPValidationError` |
# Tool Sources
> REST API reference for tool sources.
### GET `/api/orgs/{org_id}/tool-sources`
[Section titled “GET /api/orgs/{org\_id}/tool-sources”](#get-apiorgsorg_idtool-sources)
List Tool Sources
List available tool sources for an org.
Returns built-in AgentDepot/system sources and any upstream MCP servers. Requires org membership.
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `ToolSourcesResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/tool-sources/scopes`
[Section titled “GET /api/orgs/{org\_id}/tool-sources/scopes”](#get-apiorgsorg_idtool-sourcesscopes)
List Grantable Scopes
Return the set of coarse capability/integration scopes grantable to an agent.
Enumerates all org tools via the same gateway discovery path used by `GET /tool-sources/tools`, then groups them by `core`/`scope` to produce a short list of toggles the UI renders in the agent scope selector.
**Core group** — always-on tools (`ToolDefinition.core == True`). Shown read-only; never stored in `Agent.allowed_tools`.
**Scope items** — one item per distinct non-null scope string encountered across all non-core tool definitions. Each item carries the scope string (the value to store in `Agent.allowed_tools` when toggled on), a human label, the source kind discriminator, and the tool count + slug list for tooltip/expand.
Requires org membership (JWT bearer or `agd_*` API token).
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ------------------------- |
| 200 | Successful Response | `GrantableScopesResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/tool-sources/tools`
[Section titled “GET /api/orgs/{org\_id}/tool-sources/tools”](#get-apiorgsorg_idtool-sourcestools)
List Tools
List all individual tools available for an org.
Delegates to :class:`~agentdepot_agents.tool_gateway.gateway.ToolGateway` for unified discovery across system, custom, upstream MCP, and native integration tool sources. Requires org membership.
The response is additive-compatible: `name`, `source`, and `description` are byte-identical to the pre-gateway shape; `slug`, `backend_ref`, `access_level`, `is_terminal`, and `is_pausable` are new additive fields.
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `ToolListResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### POST `/api/orgs/{org_id}/tool-sources/tools/refresh`
[Section titled “POST /api/orgs/{org\_id}/tool-sources/tools/refresh”](#post-apiorgsorg_idtool-sourcestoolsrefresh)
Refresh Tools
Force-refresh the org’s upstream MCP tool cache and return the full tool list.
Reconnects to all the org’s upstream MCP servers, re-enumerates their tools, and persists the refreshed definitions to the per-integration cache. Returns the same tool list shape as `GET /tool-sources/tools`.
Per-server failures inside enumeration are isolated — a dead server simply contributes no tools and its prior cache is left untouched; the endpoint still returns 200 with whatever tools resolved.
Requires org membership (JWT bearer or `agd_*` API token).
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ---- | --------------- | -------- | ----------- |
| org\_id | path | `string (uuid)` | yes | |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `ToolListResponse` |
| 422 | Validation Error | `HTTPValidationError` |
# Usage
> REST API reference for usage.
### GET `/api/orgs/{org_id}/usage/cost`
[Section titled “GET /api/orgs/{org\_id}/usage/cost”](#get-apiorgsorg_idusagecost)
Get Usage Cost
COGS breakdown — byo provider spend vs platform cost. **Admin/owner only** (dollar figures are org-sensitive). Checked against the path org, not a header, so it can’t be bypassed with a mismatched `X-Org-Id`.
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ----- | --------------- | -------- | ---------------------------------- |
| org\_id | path | `string (uuid)` | yes | |
| window | query | `string` | no | Window: 24h, 7d, 30d (default 30d) |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ----------------------- |
| 200 | Successful Response | `CostBreakdownResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/usage/series`
[Section titled “GET /api/orgs/{org\_id}/usage/series”](#get-apiorgsorg_idusageseries)
Get Usage Series
Time series for one metric, oldest→newest. 400 on an unknown/derived metric (e.g. `storage_bytes` — use its component metrics) or bad granularity.
**Parameters**
| Name | In | Type | Required | Description |
| ----------- | ----- | --------------- | -------- | -------------------------------------------- |
| granularity | query | `string` | no | One of (‘day’, ‘month’) |
| metric | query | `string` | yes | Rollup metric value (see the metric catalog) |
| org\_id | path | `string (uuid)` | yes | |
| window | query | `string` | no | Window: 24h, 7d, 30d (default 30d) |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | --------------------- |
| 200 | Successful Response | `UsageSeriesResponse` |
| 422 | Validation Error | `HTTPValidationError` |
### GET `/api/orgs/{org_id}/usage/summary`
[Section titled “GET /api/orgs/{org\_id}/usage/summary”](#get-apiorgsorg_idusagesummary)
Get Usage Summary
Current usage for an org: counters summed over the window, gauges at their latest reading (window-independent), derived `storage_bytes`, and cost totals.
Empty while metering is dark — no rollups yet means zeroed maps.
**Parameters**
| Name | In | Type | Required | Description |
| ------- | ----- | --------------- | -------- | ----------------------------------------------- |
| org\_id | path | `string (uuid)` | yes | |
| window | query | `string` | no | Counter/cost window: 24h, 7d, 30d (default 30d) |
**Responses**
| Status | Description | Body |
| ------ | ------------------- | ---------------------- |
| 200 | Successful Response | `UsageSummaryResponse` |
| 422 | Validation Error | `HTTPValidationError` |