Managed Agent API

API documentation

Production HTTP reference for the Managed Agent API: OpenAI Responses–compatible agent runs, durable volumes, workspace management, browser authentication, and API keys. All versioned routes use the /v1 prefix.

Quick start

Create a workspace API key in the console, then call the agent API from your server or SDK.

Set AGENT_API_BASE_URL to your API origin (no /v1 suffix) and AGENT_API_KEY to a workspace key (sk-…).

curl
curl -sS https://api.agentsway.dev/v1/agent \
  -H "Authorization: Bearer $AGENT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "preset": "pro-search",
    "input": "Summarize the latest agent API trends."
  }'
Python (cloudsway-agent)
from agent_api import AgentAPI

client = AgentAPI()  # AGENT_API_KEY, AGENT_API_BASE_URL
response = client.responses.create(
    preset="pro-search",
    input="What changed in AI this week?",
)
print(response["output_text"])
JavaScript (@agent-api/sdk)
import { AgentAPI } from "@agent-api/sdk";

const client = new AgentAPI();
const response = await client.responses.create({
  preset: "pro-search",
  input: "What changed in AI this week?",
});
console.log(response.output_text);
Use POST /v1/agent as the canonical create path. POST /v1/responses is an alias for OpenAI Responses SDK compatibility. Both accept the same body and return the same shapes. For install steps, streaming, and pagination, see Official SDKs.

Official SDKs

Production client libraries published on npm and PyPI (v1.0.2). They cover agent runs, durable volumes, discovery endpoints, retries, streaming, and cursor pagination.

Two packages ship from the same public API contract documented below. Source lives in github.com/scalebox-dev/agent-api under sdk/javascript and sdk/python.

  • JavaScript @agent-api/sdk on npm
  • Python cloudsway-agent on PyPI (import with from agent_api import AgentAPI)

Install

Requires Node.js 18+ (JavaScript) or Python 3.10+ (Python). Pin a version with @1.0.2 or ==1.0.2 when you need reproducible builds.

JavaScript — @agent-api/sdk
npm install @agent-api/sdk
Python — cloudsway-agent
pip install cloudsway-agent

Configuration

Pass apiKey / baseURL (JavaScript) or api_key / base_url (Python), or set AGENT_API_KEY and AGENT_API_BASE_URL in the environment. Default base URL is https://api.agentsway.dev. Python also exposes AsyncAgentAPI for async applications.

JavaScript
const client = new AgentAPI({
  apiKey: process.env.AGENT_API_KEY,
  baseURL: "https://api.agentsway.dev",
  timeout: 600_000,        // 10 min request timeout
  streamTimeout: 3_600_000, // 1 h stream timeout
  maxRetries: 2,           // exponential backoff on 429/5xx
});
Python
client = AgentAPI(
    api_key="sk-...",
    base_url="https://api.agentsway.dev",
    timeout=600.0,
    stream_timeout=3600.0,
    max_retries=2,
)

Resources

JavaScript

ResourceMethods
client.responses / client.agentcreate, list, listPage, listIterator, retrieve, cancel, listChildren, listEvents
client.modelslist
client.presetslist
client.toolslist
client.volumeslist, create, retrieve, update, delete, listEntries, searchEntries, readFile, writeFile, deleteFile, reconcileUsage, createDirectory, deleteDirectory

Python

ResourceMethods
client.responses / client.agentcreate, list, list_page, list_iterator, retrieve, cancel, list_children, list_events
client.modelslist
client.presetslist
client.toolslist
client.volumeslist, create, retrieve, update, delete, list_entries, search_entries, read_file, write_file, delete_path, reconcile_usage, create_directory, download_archive, summarize, read_lines, patch_lines, grep

Streaming

Set stream: true on client.responses.create. The client parses SSE events and yields typed objects — use the patterns in Streaming for event types.

JavaScript
const stream = await client.responses.create({
  preset: "fast-search",
  input: "Summarize today's AI news.",
  stream: true,
});

for await (const event of stream) {
  if (event.type === "response.output_text.delta") {
    process.stdout.write(event.delta ?? "");
  }
}
Python
for event in client.responses.create(
    preset="fast-search",
    input="Summarize today's AI news.",
    stream=True,
):
    if event["type"] == "response.output_text.delta":
        print(event.get("delta", ""), end="")

Pagination

List endpoints return cursor pages. Use listPage / list_page for manual paging, or listIterator / list_iterator to walk all pages.

JavaScript
for await (const item of client.responses.listIterator({ limit: 20 })) {
  console.log(item.id, item.status);
}
Python
for item in client.responses.list_iterator(limit=20):
    print(item["id"], item["status"])

Errors and retries

Both SDKs raise typed errors mapped from the API envelope — for example AuthenticationError, RateLimitError, NotFoundError, and BadRequestError. Transient network failures, HTTP 429, and 5xx responses are retried with exponential backoff (default two retries). Respect Retry-After when the API returns it.

SDKs cover agent runs, durable volumes, and discovery endpoints (models, presets, tools) — not console browser auth, workspace administration, or API key management. Use the HTTP endpoints in Endpoint reference when you need those flows from a custom client.

Base URL

The base URL is the origin only: scheme, host, and optional port. Append paths such as /v1/agent or /healthz.
  • Production API host https://api.agentsway.dev (or api.<your-domain>). Recommended for server-side clients and SDKs.
  • Site / console hosts www, apex, and console subdomains also proxy /v1/* for same-origin browser calls; the dedicated API host remains the stable contract.

Example: GET https://api.agentsway.dev/v1/models. Liveness: GET /healthz at the host root.

Authentication

Protected routes require Authorization: Bearer followed by a workspace API key or a short-lived access JWT from browser auth.

API keys

Create keys under Console → API keys or via POST /v1/api_keys. Keys are shown once at creation; store them securely. Scope keys narrowly when possible (see table below).

Browser sessions

Sign-up and sign-in return an AuthSession with access_token, token_type: bearer, expiry, workspace id/name/role, and scopes. Refresh uses an HTTP-only cookie on POST /v1/auth/refresh — not a Bearer header.

Scopes

ScopeGrants
responses:createPOST /v1/agent, POST /v1/responses
responses:readGET response, list, /children, /events
responses:cancelPOST /v1/responses/{id}/cancel
models:readGET /v1/models
volumes:readList, read, search, and reconcile durable volumes
volumes:writeCreate, update, delete volumes and volume files/directories
api_keys:readList and read API key metadata
api_keys:writeCreate, activate, deactivate, delete keys
workspace_members:readWorkspaces, members, invitations, usage
workspace_members:writeCreate or mutate workspaces, members, invitations

Routes without a scope in the gateway still require a valid Bearer. Pass X-Request-ID on support tickets when the gateway returns one.

Agent runs

Create runs with a JSON body (CreateResponseRequest). input is required; provide exactly one of model, models (fallback chain), or preset.
Minimal create body
{
  "input": "Your question or message",
  "preset": "pro-search",
  "stream": false,
  "tools": [{ "name": "web_search", "type": "search" }],
  "memory": { "enabled": true, "read": true, "write": false }
}

Presets

Presets bundle model defaults, tools, and limits. Built-in values include fast-search, pro-search, deep-research, and advanced-deep-research, or code-agent for software engineering. Call GET /v1/presets for the live catalog (prompt version, default model, policy). Request fields override preset defaults within platform caps.

Tools and extensions

  • Built-in tools: web_search, smart_web_search, lite_web_search, fetch_url, custom function, and server skill tools.
  • volume_id attaches a durable workspace volume so the agent can read and write files during the run. Manage volumes via /v1/volumes/* or client.volumes in the SDK.
  • previous_response_id threads conversation turns. parent_response_id is rejected on create — sub-agents are spawned via run_sub_agent on the parent response.
  • plan_mode_preference / sub_agent_preference off | auto | preferred | required for roadmap and delegation behavior.
  • Multimodal input supports inline images and documents (gateway-enforced size limits; see OpenAPI).
  • language_preference — ISO 639-1 code (e.g. en, zh) when supported.

Retrieval and control

Poll GET /v1/responses/{id} or stream (below). List history with GET /v1/responses. Sub-agent runs appear under GET /v1/responses/{id}/children or in run_sub_agent tool results. Cancel with POST /v1/responses/{id}/cancel when a run is still executing on a replica.

Streaming

Set stream: true on create to receive Server-Sent Events instead of a single JSON body.

The gateway returns Content-Type: text/event-stream. Each event is a JSON object with a type field. Common types include response.output_text.delta, response.tool.invocation.completed, response.plan.updated, response.step.completed, and lifecycle events such as response.completed. Only documented event shapes are returned on the wire and in GET …/events.

SDKs accept stream: true on client.responses.create and iterate events asynchronously.

Errors

Non-2xx responses use a stable JSON envelope.
{
  "error": {
    "type": "api_error",
    "code": "unauthorized",
    "message": "…",
    "request_id": "…"
  }
}

Common code values include invalid_request, unauthorized, forbidden, not_found, and service_unavailable when a platform dependency is temporarily unavailable. Streaming failures may emit an SSE error event before the connection closes.

Endpoint reference

Each endpoint is documented with its auth requirements, request parameters, and response format.

Health

GET/healthzNone

Liveness probe for load balancers and orchestrators.

Request params

None

Response format

GET /healthz
HTTP 200 application/json
{
  "status": "ok"
}

Catalog

GET/v1/modelsBearer · models:read

List models available to the workspace with provider capability flags.

Request params

None

Response format

GET /v1/models
HTTP 200 application/json
{
  "object": "list",
  "data": [
    {
      "id": "openai/gpt-4.1",
      "object": "model",
      "owned_by": "openai",
      "capabilities": {
        "provider": "openai",
        "supports_streaming": true,
        "supports_tools": true,
        "supports_json_schema": true,
        "supports_reasoning": false,
        "context_window": 128000,
        "pricing": { },
        "metadata": { }
      }
    }
  ]
}

HTTP 503 — service_unavailable
GET/v1/toolsBearer

List built-in and registered tools the agent can invoke.

Request params

None

Response format

GET /v1/tools
HTTP 200 application/json
{
  "object": "list",
  "data": [
    {
      "object": "tool",
      "name": "web_search",
      "type": "search",
      "description": "Search the web for current information.",
      "max_tokens": 4096,
      "max_tokens_per_page": 3000
    }
  ]
}

HTTP 503 — service_unavailable
GET/v1/presetsBearer

List managed presets (model defaults, tool policy, prompt version).

Request params

None

Response format

GET /v1/presets
HTTP 200 application/json
{
  "object": "list",
  "data": [
    {
      "preset": "pro-search",
      "prompt_version": "v1",
      "default_model": "openai/gpt-4.1",
      "model_chain": ["openai/gpt-4.1"],
      "max_output_tokens": 4096,
      "policy": {
        "plan_mode_preference": "auto",
        "sub_agent_preference": "auto",
        "allowed_tools": ["web_search", "fetch_url"],
        "max_steps": 10
      }
    }
  ]
}

HTTP 503 — service_unavailable

Durable volumes

GET/v1/volumesBearer · volumes:read

List durable workspace volumes with usage counters.

Request params

Query parameters

NameTypeRequiredDescription
limitintegernoPage size. Default 50.
page_tokenstringnoOpaque cursor from a prior next_page_token.

Response format

GET /v1/volumes
HTTP 200 application/json
{
  "object": "list",
  "data": [
    {
      "volume_id": "vol_abc",
      "tenant_id": "wrk_xyz",
      "name": "research-notes",
      "oss_prefix": "tenants/wrk_xyz/volumes/vol_abc/",
      "bytes_used": 4096,
      "object_count": 3,
      "created_at_unix": 1710000000,
      "updated_at_unix": 1710003600
    }
  ],
  "next_page_token": null
}

HTTP 503 — service_unavailable
POST/v1/volumesBearer · volumes:write

Create a durable volume for agent file I/O.

Request params

Body parameters

NameTypeRequiredDescription
namestringnoHuman-readable label.

Response format

POST /v1/volumes
HTTP 201 application/json — Volume row (same shape as list item)

HTTP 503 — service_unavailable
GET/v1/volumes/{volume_id}Bearer · volumes:read

Fetch volume metadata and usage.

Request params

Path parameters

NameTypeRequiredDescription
volume_idstringyesVolume id matching vol_*.

Response format

GET /v1/volumes/{volume_id}
HTTP 200 application/json — Volume row
PATCH/v1/volumes/{volume_id}Bearer · volumes:write

Rename a volume.

Request params

Path parameters

NameTypeRequiredDescription
volume_idstringyesvol_*

Body parameters

NameTypeRequiredDescription
namestringyesNew display name.

Response format

PATCH /v1/volumes/{volume_id}
HTTP 200 application/json — updated Volume row
DELETE/v1/volumes/{volume_id}Bearer · volumes:write

Delete a volume and its stored objects.

Request params

Path parameters

NameTypeRequiredDescription
volume_idstringyesvol_*

Response format

DELETE /v1/volumes/{volume_id}
HTTP 204 No Content
POST/v1/volumes/{volume_id}/usage/reconcileBearer · volumes:read

Recompute bytes_used and object_count from object storage.

Request params

Path parameters

NameTypeRequiredDescription
volume_idstringyesvol_*

Response format

POST /v1/volumes/{volume_id}/usage/reconcile
HTTP 200 application/json — Volume row with usage_reconciled_at_unix when set
GET/v1/volumes/{volume_id}/entriesBearer · volumes:read

List files and directories under a path.

Request params

Path parameters

NameTypeRequiredDescription
volume_idstringyesvol_*

Query parameters

NameTypeRequiredDescription
pathstringnoDirectory path (default root).
limitintegernoPage size. Default 200.
page_tokenstringnoPagination cursor.

Response format

GET /v1/volumes/{volume_id}/entries
HTTP 200 application/json
{
  "object": "list",
  "entries": [
    { "path": "notes/summary.md", "is_dir": false, "size": 128, "modified_at_unix": 1710000000 }
  ],
  "next_page_token": null
}
GET/v1/volumes/{volume_id}/files/{path}Bearer · volumes:read

Deliver a file with smart encoding (text, extracted document text, image URL, or base64). Use format=raw for direct binary bytes.

Request params

Path parameters

NameTypeRequiredDescription
volume_idstringyesvol_*
pathstringyesFile path within the volume.

Query parameters

NameTypeRequiredDescription
max_bytesintegernoRead cap in bytes (0 = server default).
formatstringnoSet to raw for binary bytes with X-Volume-Size and X-Volume-Truncated headers.

Response format

GET /v1/volumes/{volume_id}/files/{path}
HTTP 200 application/json
{
  "path": "notes/summary.md",
  "encoding": "text",
  "mime_type": "text/markdown",
  "size": 128,
  "truncated": false,
  "content": "# Summary\n"
}

HTTP 200 (format=raw) — raw bytes with Content-Type and X-Volume-* headers
PUT/v1/volumes/{volume_id}/files/{path}Bearer · volumes:write

Write or overwrite a file. Request body is raw file bytes.

Request params

Path parameters

NameTypeRequiredDescription
volume_idstringyesvol_*
pathstringyesDestination file path.

Response format

PUT /v1/volumes/{volume_id}/files/{path}
HTTP 200 application/json
{ "path": "notes/summary.md", "size": 128 }
DELETE/v1/volumes/{volume_id}/paths/{path}Bearer · volumes:write

Delete a file or directory tree at path.

Request params

Path parameters

NameTypeRequiredDescription
volume_idstringyesvol_*
pathstringyesFile or directory prefix to delete.

Response format

DELETE /v1/volumes/{volume_id}/paths/{path}
HTTP 200 application/json
{ "path": "notes/archive", "recursive": true }
POST/v1/volumes/{volume_id}/summarizeBearer · volumes:read

Scan the volume and return stats plus text previews. Writes .agent-volume/summary.json.

Request params

Path parameters

NameTypeRequiredDescription
volume_idstringyesvol_*

Body parameters

NameTypeRequiredDescription
pathstringnoOptional path prefix to limit the scan.

Response format

POST /v1/volumes/{volume_id}/summarize
HTTP 200 application/json — summary_path, file_count, total_bytes, top_paths_by_size, text_previews
GET/v1/volumes/{volume_id}/grepBearer · volumes:read

Search file contents for a literal substring.

Request params

Path parameters

NameTypeRequiredDescription
volume_idstringyesvol_*

Query parameters

NameTypeRequiredDescription
patternstringyesLiteral substring to find.
pathstringnoDirectory prefix to search under.

Response format

GET /v1/volumes/{volume_id}/grep
HTTP 200 application/json — object=list, matches[{path,line_number,line}], files_scanned, scan_truncated
GET/v1/volumes/{volume_id}/file_lines/{path}Bearer · volumes:read

Read a 1-based inclusive line range from a text file.

Request params

Path parameters

NameTypeRequiredDescription
volume_idstringyesvol_*
pathstringyesFile path.

Query parameters

NameTypeRequiredDescription
start_lineintegeryes1-based start line.
end_lineintegernoInclusive end line; 0 = EOF.

Response format

GET /v1/volumes/{volume_id}/file_lines/{path}
HTTP 200 application/json — path, start_line, end_line, total_lines, lines[]
PATCH/v1/volumes/{volume_id}/file_lines/{path}Bearer · volumes:write

Replace an inclusive line range in a text file.

Request params

Path parameters

NameTypeRequiredDescription
volume_idstringyesvol_*
pathstringyesFile path.

Body parameters

NameTypeRequiredDescription
start_lineintegeryes1-based start line.
end_lineintegernoInclusive end line; 0 = EOF.
replacementstringnoReplacement text.

Response format

PATCH /v1/volumes/{volume_id}/file_lines/{path}
HTTP 200 application/json — path, start_line, end_line, total_lines, size
GET/v1/volumes/{volume_id}/archiveBearer · volumes:read

Download a directory tree as a ZIP archive.

Request params

Path parameters

NameTypeRequiredDescription
volume_idstringyesvol_*

Query parameters

NameTypeRequiredDescription
pathstringnoDirectory path to archive (default root).

Response format

GET /v1/volumes/{volume_id}/archive
HTTP 200 application/zip
POST/v1/volumes/{volume_id}/directoriesBearer · volumes:write

Create a directory (and parents as needed).

Request params

Path parameters

NameTypeRequiredDescription
volume_idstringyesvol_*

Body parameters

NameTypeRequiredDescription
pathstringyesDirectory path to create.

Response format

POST /v1/volumes/{volume_id}/directories
HTTP 201 application/json
{ "path": "notes/archive" }

Agent responses

POST/v1/agentBearer · responses:create

Create an agent run (canonical path). Returns a stored Response or an SSE stream when stream is true.

Request params

Body parameters

NameTypeRequiredDescription
inputInputyesUser message or multimodal input array (string, message items with input_text/input_image/input_document, function_call, function_call_output).
modelstringnoSingle provider/model id. Ignored when models is set. Required if neither models nor preset is provided.
modelsstring[]noOrdered fallback chain (1–5 model ids). Required if neither model nor preset is provided.
presetstringnoManaged bundle: fast-search | pro-search | deep-research | advanced-deep-research | code-agent. Required if neither model nor models is provided.
instructionsstringnoSystem-level instructions prepended to the run.
language_preferencestringnoISO 639-1 code from server allowlist (e.g. en, zh). Two lowercase letters.
streambooleannoWhen true, returns text/event-stream instead of JSON. Default false.
toolsTool[]noTools to expose: web_search, smart_web_search, lite_web_search, fetch_url, function, skill.
tool_choicestring | objectnoTool selection policy: "auto", "none", "required", or a named-tool object.
parallel_tool_callsbooleannoAllow parallel tool calls. Default true.
memoryMemoryOptionsnoLong-term memory opts: { enabled?, read?, write? }. Thread with previous_response_id.
plan_mode_preferenceAgentCapabilityPreferencenoRoadmap/plan steering: off | auto | preferred | required.
sub_agent_preferenceAgentCapabilityPreferencenoDelegation steering for run_sub_agent: off | auto | preferred | required.
max_output_tokensintegernoCap on model output tokens (≥ 1).
max_stepsintegernoAgent loop step limit (1–10).
reasoningReasoningConfignoReasoning effort: { effort: low | medium | high }.
response_formatResponseFormatnoStructured output: { type: json_schema, json_schema: { … } }.
previous_response_idstringnoPrior response id for conversation threading (resp_*).
prompt_cache_keystringnoOptional cache key for prompt reuse.
metadataobjectnoArbitrary string-keyed metadata stored on the response.
storebooleannoPersist the response for later retrieval. Default true.
userstringnoEnd-user identifier for attribution. When using API keys, the authenticated user id is used instead.
volume_idstringnoAttach a durable workspace volume (vol_*) so the agent can read and write files during the run.

Response format

POST /v1/agent
HTTP 200 application/json (stream: false)
{
  "id": "resp_abc123",
  "object": "response",
  "created_at": 1710000000,
  "completed_at": 1710000060,
  "status": "completed",
  "model": "openai/gpt-4.1",
  "output": [ … ],
  "output_text": "…",
  "usage": { "input_tokens": 120, "output_tokens": 340, "total_tokens": 460 },
  "tool_results": [
    {
      "id": "tir_abc",
      "tool_call_id": "call_abc",
      "tool_name": "web_search",
      "status": "completed",
      "response_summary": "…"
    }
  ],
  "plan": { },
  "background": false,
  "parent_response_id": null,
  "root_response_id": "resp_abc123",
  "store": true
}

HTTP 200 text/event-stream (stream: true)
data: {"type":"response.output_text.delta","sequence_number":1,"delta":"Hello"}
data: {"type":"response.tool.invocation.completed","sequence_number":2,"tool_result":{…}}
data: {"type":"response.step.completed","sequence_number":3,"step":{…}}

HTTP 200 text/event-stream on error mid-stream
data: {"error":"…"}
POST/v1/responsesBearer · responses:create

OpenAI Responses SDK alias for POST /v1/agent — identical request and response shapes.

Request params

Body parameters

NameTypeRequiredDescription
inputInputyesUser message or multimodal input array (string, message items with input_text/input_image/input_document, function_call, function_call_output).
modelstringnoSingle provider/model id. Ignored when models is set. Required if neither models nor preset is provided.
modelsstring[]noOrdered fallback chain (1–5 model ids). Required if neither model nor preset is provided.
presetstringnoManaged bundle: fast-search | pro-search | deep-research | advanced-deep-research | code-agent. Required if neither model nor models is provided.
instructionsstringnoSystem-level instructions prepended to the run.
language_preferencestringnoISO 639-1 code from server allowlist (e.g. en, zh). Two lowercase letters.
streambooleannoWhen true, returns text/event-stream instead of JSON. Default false.
toolsTool[]noTools to expose: web_search, smart_web_search, lite_web_search, fetch_url, function, skill.
tool_choicestring | objectnoTool selection policy: "auto", "none", "required", or a named-tool object.
parallel_tool_callsbooleannoAllow parallel tool calls. Default true.
memoryMemoryOptionsnoLong-term memory opts: { enabled?, read?, write? }. Thread with previous_response_id.
plan_mode_preferenceAgentCapabilityPreferencenoRoadmap/plan steering: off | auto | preferred | required.
sub_agent_preferenceAgentCapabilityPreferencenoDelegation steering for run_sub_agent: off | auto | preferred | required.
max_output_tokensintegernoCap on model output tokens (≥ 1).
max_stepsintegernoAgent loop step limit (1–10).
reasoningReasoningConfignoReasoning effort: { effort: low | medium | high }.
response_formatResponseFormatnoStructured output: { type: json_schema, json_schema: { … } }.
previous_response_idstringnoPrior response id for conversation threading (resp_*).
prompt_cache_keystringnoOptional cache key for prompt reuse.
metadataobjectnoArbitrary string-keyed metadata stored on the response.
storebooleannoPersist the response for later retrieval. Default true.
userstringnoEnd-user identifier for attribution. When using API keys, the authenticated user id is used instead.
volume_idstringnoAttach a durable workspace volume (vol_*) so the agent can read and write files during the run.

Response format

POST /v1/responses
Same as POST /v1/agent.
GET/v1/responsesBearer · responses:read

Paginated list of top-level orchestrator runs for the authenticated user. Sub-agent children are excluded.

Request params

Query parameters

NameTypeRequiredDescription
limitintegernoPage size, 1–100. Default 20.
page_tokenstringnoOpaque cursor from a prior response next_page_token.

Response format

GET /v1/responses
HTTP 200 application/json
{
  "object": "list",
  "data": [
    {
      "id": "resp_abc123",
      "status": "completed",
      "created_at": 1710000000,
      "completed_at": 1710000060,
      "model": "openai/gpt-4.1",
      "preset": "pro-search",
      "input_preview": "Summarize…",
      "root_response_id": "resp_abc123",
      "background": false
    }
  ],
  "has_more": false,
  "next_page_token": null
}
GET/v1/responses/{response_id}Bearer · responses:read

Retrieve a stored response including output, usage, and lineage fields.

Request params

Path parameters

NameTypeRequiredDescription
response_idstringyesResponse id matching resp_*.

Response format

GET /v1/responses/{response_id}
HTTP 200 application/json
{
  "id": "resp_abc123",
  "object": "response",
  "status": "completed",
  "model": "openai/gpt-4.1",
  "output": [ … ],
  "output_text": "…",
  "usage": { … },
  "metadata": { },
  "parent_response_id": null,
  "root_response_id": "resp_abc123"
}
POST/v1/responses/{response_id}/cancelBearer · responses:cancel

Abort an in-flight run while it is still executing. Idempotent.

Request params

Path parameters

NameTypeRequiredDescription
response_idstringyesResponse id matching resp_*.

Response format

POST /v1/responses/{response_id}/cancel
HTTP 200 application/json
{
  "interrupted": true
}
GET/v1/responses/{response_id}/childrenBearer · responses:read

List sub-agent runs spawned by run_sub_agent on the parent response.

Request params

Path parameters

NameTypeRequiredDescription
response_idstringyesParent response id matching resp_*.

Response format

GET /v1/responses/{response_id}/children
HTTP 200 application/json
{
  "object": "list",
  "data": [
    {
      "id": "resp_child1",
      "status": "completed",
      "created_at": 1710000010,
      "completed_at": 1710000030,
      "root_response_id": "resp_abc123",
      "model": "openai/gpt-4.1"
    }
  ]
}
GET/v1/responses/{response_id}/volumeBearer · responses:read · volumes:read

Resolve the durable workspace volume for a response thread.

Request params

Path parameters

NameTypeRequiredDescription
response_idstringyesResponse id matching resp_*.

Response format

GET /v1/responses/{response_id}/volume
HTTP 200 application/json — Volume row (volume_id, name, bytes_used, ...)

HTTP 404 — no workspace volume for this response
GET/v1/responses/{response_id}/eventsBearer · responses:read

Replay SSE event shapes for a response.

Request params

Path parameters

NameTypeRequiredDescription
response_idstringyesResponse id matching resp_*.

Query parameters

NameTypeRequiredDescription
after_sequenceintegernoReturn events with sequence_number strictly greater than this value.
viewstringnotimeline (default) or full — full includes tool_result.body on tool events.

Response format

GET /v1/responses/{response_id}/events
HTTP 200 application/json
{
  "data": [
    {
      "type": "response.output_text.delta",
      "sequence_number": 42,
      "delta": "Hello"
    }
  ]
}

With view=full, tool completion events may include tool_result.body.

Browser auth

POST/v1/auth/signupNone

Register a new user. Sends an email verification code when SMTP is configured.

Request params

Body parameters

NameTypeRequiredDescription
emailstringyesValid email address.
passwordstringyes8–32 ASCII chars (A–Z, a–z, 0–9, and !@#$%^&*()-_=+[]{};:,.?/~).
display_namestringnoOptional display name.

Response format

POST /v1/auth/signup
HTTP 201 application/json
{
  "user_id": "usr_abc",
  "email": "you@example.com",
  "verification_required": true,
  "code_expires_at": 1710003600
}
POST/v1/auth/verify_emailNone

Confirm signup with the emailed verification code.

Request params

Body parameters

NameTypeRequiredDescription
emailstringyesAccount email.
codestringyesVerification code from email.

Response format

POST /v1/auth/verify_email
HTTP 200 application/json
Set-Cookie: agent_api_refresh=… (when configured)

{
  "access_token": "eyJ…",
  "token_type": "bearer",
  "access_token_expires_at": 1710003600,
  "user_id": "usr_abc",
  "workspace_id": "wrk_xyz",
  "workspace_name": "My Team",
  "workspace_role": "owner",
  "scopes": ["responses:create", "responses:read", …]
}
POST/v1/auth/signinNone

Sign in with email and password.

Request params

Body parameters

NameTypeRequiredDescription
emailstringyesAccount email.
passwordstringyesAccount password.

Response format

POST /v1/auth/signin
HTTP 200 application/json — AuthSession (same shape as verify_email)
POST/v1/auth/refreshRefresh cookie

Rotate the browser session using the HTTP-only refresh cookie.

Request params

Cookie parameters

NameTypeRequiredDescription
agent_api_refreshstringyesHTTP-only refresh cookie. No Authorization header.

Response format

POST /v1/auth/refresh
HTTP 200 application/json — rotated AuthSession + Set-Cookie
POST/v1/auth/signoutNone

Clear the refresh session server-side.

Request params

None

Response format

POST /v1/auth/signout
HTTP 200 application/json
{
  "status": "ok",
  "message": "signed out"
}
POST/v1/auth/password_reset/requestNone

Request a password reset link. Always returns a generic success message (anti-enumeration).

Request params

Body parameters

NameTypeRequiredDescription
emailstringyesAccount email.

Response format

POST /v1/auth/password_reset/request
HTTP 200 application/json
{
  "status": "ok",
  "message": "If an account exists, a reset link was sent."
}
POST/v1/auth/password_reset/confirmNone

Set a new password using the token from the emailed reset link.

Request params

Body parameters

NameTypeRequiredDescription
tokenstringyesToken from /reset-password?token=…
new_passwordstringyesSame password policy as signup.

Response format

POST /v1/auth/password_reset/confirm
HTTP 200 application/json
{
  "status": "ok",
  "message": "password updated"
}
GET/v1/auth/oauth/{provider}/startNone

Begin OAuth sign-in and return the provider authorization URL.

Request params

Path parameters

NameTypeRequiredDescription
providerstringyesgoogle or github.

Query parameters

NameTypeRequiredDescription
redirect_urlstringnoOverride OAuth callback origin when allowed.

Response format

GET /v1/auth/oauth/{provider}/start
HTTP 200 application/json
{
  "authorization_url": "https://…",
  "state": "…",
  "expires_at": 1710003600
}
GET/v1/auth/oauth/{provider}/callbackNone

Complete OAuth and issue an AuthSession.

Request params

Path parameters

NameTypeRequiredDescription
providerstringyesgoogle or github.

Query parameters

NameTypeRequiredDescription
codestringyesProvider authorization code.
statestringyesState from /start.
redirect_urlstringnoOptional callback override.

Response format

GET /v1/auth/oauth/{provider}/callback
HTTP 200 application/json — AuthSession (browser/API clients)

HTTP 302 Found — browser redirect to the console with Set-Cookie when Accept prefers HTML

Identity

GET/v1/meBearer

Return the authenticated identity and active workspace context.

Request params

None

Response format

GET /v1/me
HTTP 200 application/json
{
  "object": "identity",
  "user_id": "usr_abc",
  "workspace_id": "wrk_xyz",
  "workspace_name": "My Team",
  "workspace_role": "owner",
  "api_key_id": "key_123",
  "scopes": ["responses:create", "responses:read"]
}
GET/v1/me/profileBearer

Profile fields for the user in the active workspace.

Request params

None

Response format

GET /v1/me/profile
HTTP 200 application/json
{
  "object": "user_profile",
  "user_id": "usr_abc",
  "email": "you@example.com",
  "display_name": "Alex",
  "email_verified": true,
  "has_password": true
}
PATCH/v1/me/profileBearer

Update the authenticated user's display name.

Request params

Body parameters

NameTypeRequiredDescription
display_namestringyesNew display name.

Response format

PATCH /v1/me/profile
HTTP 200 application/json — updated user_profile object
POST/v1/me/passwordBearer

Add or rotate the account password while signed in.

Request params

Body parameters

NameTypeRequiredDescription
new_passwordstringyesNew password (signup policy).
current_passwordstringnoRequired when the account already has a password.

Response format

POST /v1/me/password
HTTP 200 application/json
{
  "status": "ok",
  "message": "password updated"
}

Workspaces

GET/v1/workspacesBearer · workspace_members:read

List workspaces where the caller is an active member.

Request params

None

Response format

GET /v1/workspaces
HTTP 200 application/json
{
  "object": "list",
  "data": [ { "id": "wrk_xyz", "object": "workspace", "name": "…", "type": "team", "status": "active", "role": "owner" } ]
}
POST/v1/workspacesBearer · workspace_members:write

Create a workspace; the caller becomes owner.

Request params

Body parameters

NameTypeRequiredDescription
namestringyesWorkspace display name.
slugstringnoURL-safe slug.
typestringnopersonal | team | organization.
billing_emailstringnoBilling contact email.

Response format

POST /v1/workspaces
HTTP 201 application/json — Workspace object
GET/v1/workspaces/{workspace_id}Bearer · workspace_members:read

Fetch workspace details including plan and billing hints.

Request params

Path parameters

NameTypeRequiredDescription
workspace_idstringyesWorkspace id matching wrk_*.

Response format

GET /v1/workspaces/{workspace_id}
HTTP 200 application/json — Workspace object
PATCH/v1/workspaces/{workspace_id}Bearer · workspace_members:write

Partially update workspace metadata.

Request params

Path parameters

NameTypeRequiredDescription
workspace_idstringyeswrk_*

Body parameters

NameTypeRequiredDescription
namestringnoWorkspace display name.
slugstringnoURL-safe slug.
typestringnopersonal | team | organization.
statusstringnoactive | inactive.
billing_account_idstringnoExternal billing account reference.
billing_customer_refstringnoExternal customer reference.
planstringnoPlan identifier.
usage_limit_monthlyintegernoMonthly usage cap.
billing_emailstringnoBilling contact email.

Response format

PATCH /v1/workspaces/{workspace_id}
HTTP 200 application/json — updated Workspace
POST/v1/workspaces/{workspace_id}/switchBearer · workspace_members:read

Issue a new AuthSession scoped to the selected workspace (browser/console clients).

Request params

Path parameters

NameTypeRequiredDescription
workspace_idstringyeswrk_*

Response format

POST /v1/workspaces/{workspace_id}/switch
HTTP 200 application/json — AuthSession
GET/v1/workspaces/{workspace_id}/usageBearer · workspace_members:read

Workspace usage summary for the current calendar month (identity-core usage facts).

Request params

Path parameters

NameTypeRequiredDescription
workspace_idstringyeswrk_*

Query parameters

NameTypeRequiredDescription
periodstringnoYYYY-MM-DD month start (UTC)

Response format

GET /v1/workspaces/{workspace_id}/usage
HTTP 200 application/json
{
  "object": "workspace_usage",
  "workspace_id": "wrk_xyz",
  "period_start": 1711929600,
  "response_count": 12,
  "input_tokens": 45000,
  "output_tokens": 12000,
  "total_tokens": 57000,
  "tool_calls_total": 8
}
GET/v1/workspaces/{workspace_id}/usage/eventsBearer · workspace_members:read

Paginated usage events for the workspace (one row per recorded agent response). Each event includes input, output, and cache token breakdown when reported by the provider.

Request params

Path parameters

NameTypeRequiredDescription
workspace_idstringyeswrk_*

Query parameters

NameTypeRequiredDescription
periodstringnoYYYY-MM-DD month start (UTC)
limitintegerno1–100, default 25
page_tokenstringnoCursor from next_page_token

Response format

GET /v1/workspaces/{workspace_id}/usage/events
HTTP 200 application/json
{
  "object": "list",
  "data": [
    {
      "object": "usage_event",
      "response_id": "resp_abc",
      "workspace_id": "wrk_xyz",
      "user_id": "user_xyz",
      "auth_method": "jwt",
      "input_tokens": 1200,
      "output_tokens": 400,
      "total_tokens": 1600,
      "cache_read_input_tokens": 320,
      "cache_creation_input_tokens": 0,
      "tool_calls_total": 1,
      "recorded_at": 1710000000
    }
  ],
  "next_page_token": null
}

Members and invitations

GET/v1/workspaces/{workspace_id}/membersBearer · workspace_members:read

List members of a workspace.

Request params

Path parameters

NameTypeRequiredDescription
workspace_idstringyeswrk_*

Response format

GET /v1/workspaces/{workspace_id}/members
HTTP 200 application/json
{ "object": "list", "data": [ WorkspaceMember ] }
POST/v1/workspaces/{workspace_id}/membersBearer · workspace_members:write

Add an existing user to a workspace.

Request params

Path parameters

NameTypeRequiredDescription
workspace_idstringyeswrk_*

Body parameters

NameTypeRequiredDescription
user_idstringyesExisting user id to add.
rolestringnoowner | admin | member.

Response format

POST /v1/workspaces/{workspace_id}/members
HTTP 201 application/json
{
  "workspace_id": "wrk_xyz",
  "user_id": "usr_abc",
  "role": "member",
  "status": "active",
  "created_at": 1710000000
}
PATCH/v1/workspaces/{workspace_id}/members/{user_id}Bearer · workspace_members:write

Update a member's role or status.

Request params

Path parameters

NameTypeRequiredDescription
workspace_idstringyeswrk_*
user_idstringyesMember user id.

Body parameters

NameTypeRequiredDescription
rolestringnoNew role.
statusstringnoactive | inactive.

Response format

PATCH /v1/workspaces/{workspace_id}/members/{user_id}
HTTP 200 application/json — WorkspaceMember
DELETE/v1/workspaces/{workspace_id}/members/{user_id}Bearer · workspace_members:write

Deactivate a workspace member.

Request params

Path parameters

NameTypeRequiredDescription
workspace_idstringyeswrk_*
user_idstringyesMember user id.

Response format

DELETE /v1/workspaces/{workspace_id}/members/{user_id}
HTTP 200 application/json — WorkspaceMember with status inactive
GET/v1/workspace_membersBearer · workspace_members:read

List members of the caller's active workspace.

Request params

None

Response format

GET /v1/workspace_members
HTTP 200 application/json
{ "object": "list", "data": [ WorkspaceMember ] }
POST/v1/workspace_membersBearer · workspace_members:write

Add a member to the active workspace.

Request params

Body parameters

NameTypeRequiredDescription
user_idstringyesExisting user id.
rolestringnoOptional role.

Response format

POST /v1/workspace_members
HTTP 201 application/json — WorkspaceMember
PATCH/v1/workspace_members/{user_id}Bearer · workspace_members:write

Update a member on the active workspace.

Request params

Path parameters

NameTypeRequiredDescription
user_idstringyesMember user id.

Body parameters

NameTypeRequiredDescription
rolestringnoOptional role.
statusstringnoOptional status.

Response format

PATCH /v1/workspace_members/{user_id}
HTTP 200 application/json — WorkspaceMember
DELETE/v1/workspace_members/{user_id}Bearer · workspace_members:write

Remove a member from the active workspace.

Request params

Path parameters

NameTypeRequiredDescription
user_idstringyesMember user id.

Response format

DELETE /v1/workspace_members/{user_id}
HTTP 200 application/json — WorkspaceMember inactive
GET/v1/workspaces/{workspace_id}/invitationsBearer · workspace_members:read

List pending invitations.

Request params

Path parameters

NameTypeRequiredDescription
workspace_idstringyeswrk_*

Response format

GET /v1/workspaces/{workspace_id}/invitations
HTTP 200 application/json
{ "object": "list", "data": [ WorkspaceInvitation ] }
POST/v1/workspaces/{workspace_id}/invitationsBearer · workspace_members:write

Invite a user by email.

Request params

Path parameters

NameTypeRequiredDescription
workspace_idstringyeswrk_*

Body parameters

NameTypeRequiredDescription
emailstringyesInvitee email.
rolestringnoOptional role.
expires_atintegernoUnix expiry.

Response format

POST /v1/workspaces/{workspace_id}/invitations
HTTP 201 application/json
{
  "id": "inv_abc",
  "email": "friend@example.com",
  "invitation_token": "…"
}
DELETE/v1/workspaces/{workspace_id}/invitations/{invitation_id}Bearer · workspace_members:write

Revoke a pending invitation.

Request params

Path parameters

NameTypeRequiredDescription
workspace_idstringyeswrk_*
invitation_idstringyesInvitation id.

Response format

DELETE /v1/workspaces/{workspace_id}/invitations/{invitation_id}
HTTP 200 application/json — revoked WorkspaceInvitation
POST/v1/workspace_invitations/acceptBearer · workspace_members:write

Accept an invitation and join the workspace.

Request params

Body parameters

NameTypeRequiredDescription
invitation_tokenstringyesToken from the invitation.

Response format

POST /v1/workspace_invitations/accept
HTTP 200 application/json — WorkspaceMember

API keys

GET/v1/api_keysBearer · api_keys:read

List API keys for the workspace (metadata only — no secrets).

Request params

None

Response format

GET /v1/api_keys
HTTP 200 application/json
{
  "object": "list",
  "data": [
    {
      "id": "key_abc",
      "object": "api_key",
      "key_prefix": "sk-abcd",
      "name": "prod",
      "status": "active",
      "scopes": ["responses:create"],
      "created_at": 1710000000
    }
  ]
}
POST/v1/api_keysBearer · api_keys:write

Create a workspace API key. The raw secret is returned once.

Request params

Body parameters

NameTypeRequiredDescription
namestringnoHuman-readable label.
scopesstring[]noOAuth-style scopes.
expires_atintegernoUnix expiry timestamp.

Response format

POST /v1/api_keys
HTTP 201 application/json
Send {} when no optional fields are needed (empty body is rejected).

{
  "id": "key_abc",
  "object": "api_key",
  "api_key": "sk-…",
  "key_prefix": "sk-abcd",
  "workspace_id": "wrk_xyz",
  "user_id": "usr_abc",
  "scopes": ["responses:create"],
  "created_at": 1710000000
}
GET/v1/api_keys/{api_key_id}Bearer · api_keys:read

Fetch API key metadata.

Request params

Path parameters

NameTypeRequiredDescription
api_key_idstringyeskey_*

Response format

GET /v1/api_keys/{api_key_id}
HTTP 200 application/json — APIKeyInfo
POST/v1/api_keys/{api_key_id}/activateBearer · api_keys:write

Re-enable a deactivated key.

Request params

Path parameters

NameTypeRequiredDescription
api_key_idstringyeskey_*

Response format

POST /v1/api_keys/{api_key_id}/activate
HTTP 200 application/json
{ "id": "key_abc", "status": "active", "updated_at": 1710000000 }
POST/v1/api_keys/{api_key_id}/deactivateBearer · api_keys:write

Disable a key without deleting it.

Request params

Path parameters

NameTypeRequiredDescription
api_key_idstringyeskey_*

Response format

POST /v1/api_keys/{api_key_id}/deactivate
HTTP 200 application/json
{ "id": "key_abc", "status": "inactive", "updated_at": 1710000000 }
DELETE/v1/api_keys/{api_key_id}Bearer · api_keys:write

Permanently delete an API key.

Request params

Path parameters

NameTypeRequiredDescription
api_key_idstringyeskey_*

Response format

DELETE /v1/api_keys/{api_key_id}
HTTP 200 application/json
{ "id": "key_abc", "status": "deleted", "updated_at": 1710000000 }
Shared objects: AuthSession (access_token, token_type, workspace_id, workspace_name, workspace_role, scopes), WorkspaceMember (workspace_id, user_id, role, status, created_at). Field-level details are listed under each endpoint below.

OpenAPI

Machine-readable request and response schemas for tools, volumes, multimodal input, SSE events, and workspace objects.

The OpenAPI 3.1 spec (api/openapi/agent-api.v1.yaml in the agent-api repository) tracks the same public HTTP contract as this page. Official SDKs are described in Official SDKs (@agent-api/sdk on npm, cloudsway-agent on PyPI). Contact support if you need a hosted copy or early access to schema changes.