Files
goclaw/internal/http/openapi_spec.json
T
Kai (Tam Nhu) TranandGitHub 30708ae79d feat(providers): support Codex OAuth pools with inherited routing defaults
* feat(auth): support named chatgpt oauth providers

- add provider-scoped ChatGPT OAuth routes and CLI support

- persist refresh tokens per provider and reject provider-type collisions

- wire provider OAuth setup flows in the dashboard and setup UI

Refs #448

* feat(agent): add chatgpt oauth account routing

- add agent other_config routing for manual and round-robin selection

- reuse routed provider resolution across resolver and pending loaders

- add router, parser, and agent advanced dialog coverage for multi-account use

Refs #448

* docs(api): describe chatgpt oauth routing

- document named-provider ChatGPT OAuth auth routes

- describe agent-side account routing and round-robin behavior

- update OpenAPI agent config schema and provider type enum

Refs #448

* fix(store): add missing agent key context helpers

* feat(ui): clarify chatgpt oauth account setup and routing

* docs(providers): align chatgpt oauth alias examples

* feat(agent): add codex pool activity dashboard

* fix(providers): harden codex oauth alias setup

* feat(codex-pool): improve routing dashboard UX

- redesign the Codex/OpenAI pool page around saved-pool checkpoints and live evidence

- add clearer selection, attention, and recent-proof states for pool members

- make the lower panels fill the remaining desktop viewport while staying responsive

* fix(store): resolve context helper merge duplication

* feat(oauth): add codex pool quota and observation APIs

- add quota inspection and observation endpoints for ChatGPT Subscription (OAuth) providers

- teach codex routing to surface pool activity, observation metadata, and quota-aware readiness

- extend tests and HTTP docs/OpenAPI for the new pool monitoring flows

* feat(web): add codex pool quota monitor and controls

- add provider quota fetching, readiness badges, and live routing evidence on the account pool page

- redesign pool setup and activity panels for multi-account management with localized copy updates

- keep the live monitor internally scrollable and compact the account cards for better viewport fit

* fix(web): clarify pool routing labels

- rename the recent request badge from Direct to Selected

- restore compact quota bars in the live pool cards

* feat(codex-pool): add runtime health dashboard

- derive per-provider success and failure health from routed Codex traces

- surface routing, quota, and recent request evidence in the pool UI

- align provider alias guidance and owner access with the dashboard role model

* docs(auth): document tenant scoping and key roles

* fix(auth): harden tenant and codex pool access control

* fix(providers): align codex pool runtime defaults

* feat(ui): tighten codex pool responsive layout

* feat(chatgpt-oauth): refine codex pool management UX

* feat(chatgpt-oauth): surface quota bars on provider pages

- add compact quota bars to Codex provider rows and provider detail

- fetch quota only for ready visible provider rows and ready detail aliases

- fix managed-member detail visibility and tighten provider locale copy
2026-03-27 09:35:57 +07:00

897 lines
40 KiB
JSON

{
"openapi": "3.0.3",
"info": {
"title": "GoClaw Gateway API",
"description": "PostgreSQL multi-tenant AI agent gateway with WebSocket RPC + HTTP API.\n\n## Authentication\n\nAll endpoints require a Bearer token in the `Authorization` header:\n\n```\nAuthorization: Bearer <gateway-token-or-api-key>\n```\n\nYou can use either the **gateway token** (grants admin access) or an **API key** created via the API Keys endpoints (grants scoped access).\n\nIf no token is configured on the server, authentication is disabled (backward compatibility).\n\n## Common Headers\n\n| Header | Description |\n|--------|-------------|\n| `X-GoClaw-User-Id` | External user ID for multi-tenant context |\n| `X-GoClaw-Agent-Id` | Target agent ID (alternative to model prefix) |\n| `X-GoClaw-Tenant-Id` | Tenant scope — UUID or slug (gateway token / cross-tenant API keys) |\n| `Accept-Language` | Locale for error messages (`en`, `vi`, `zh`) |\n\n## WebSocket Protocol\n\nConnect via `POST /ws` (upgrade). Protocol v3 uses frame types: `req`, `res`, `event`.\nFirst request must be `connect` with `{\"token\": \"...\", \"user_id\": \"...\", \"locale\": \"en\"}`.",
"version": "0.2.0",
"contact": {
"name": "GoClaw",
"url": "https://github.com/nextlevelbuilder/goclaw"
}
},
"servers": [
{
"url": "/",
"description": "Current server"
}
],
"tags": [
{ "name": "Chat", "description": "OpenAI-compatible chat completions" },
{ "name": "API Keys", "description": "Gateway API key management (admin only)" },
{ "name": "Agents", "description": "Agent CRUD and configuration" },
{ "name": "Sessions", "description": "Chat session management (via WebSocket RPC)" },
{ "name": "Providers", "description": "LLM provider configuration" },
{ "name": "OAuth", "description": "Provider-scoped OAuth status and quota endpoints" },
{ "name": "Skills", "description": "Skill management and grants" },
{ "name": "MCP Servers", "description": "MCP server configuration and grants" },
{ "name": "Custom Tools", "description": "Custom tool definitions" },
{ "name": "Built-in Tools", "description": "Built-in tool configuration" },
{ "name": "Memory", "description": "Agent memory (pgvector) management" },
{ "name": "Knowledge Graph", "description": "Entity knowledge graph" },
{ "name": "Channels", "description": "Channel instance management" },
{ "name": "Traces", "description": "LLM call tracing" },
{ "name": "Usage", "description": "Usage analytics" },
{ "name": "Activity", "description": "Audit activity log" },
{ "name": "Storage", "description": "Workspace file management" },
{ "name": "Media", "description": "Media upload and serving" },
{ "name": "System", "description": "Health check and system info" }
],
"security": [{ "bearerAuth": [] }],
"paths": {
"/health": {
"get": {
"tags": ["System"],
"summary": "Health check",
"security": [],
"responses": {
"200": {
"description": "Server health status",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"status": { "type": "string", "example": "ok" },
"uptime_ms": { "type": "integer" },
"mode": { "type": "string", "example": "managed" },
"database": { "type": "string", "example": "ok" }
}
}
}
}
}
}
}
},
"/v1/chat/completions": {
"post": {
"tags": ["Chat"],
"summary": "OpenAI-compatible chat completions",
"description": "Send messages to an agent and get a response. Compatible with OpenAI's chat completions API.\n\nUse the `model` field to target a specific agent: `goclaw:<agent-id>` or `agent:<agent-id>`.",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["messages"],
"properties": {
"model": {
"type": "string",
"description": "Agent targeting: `goclaw:<id>` or `agent:<id>`. Defaults to `default`.",
"example": "goclaw:default"
},
"messages": {
"type": "array",
"items": {
"type": "object",
"required": ["role", "content"],
"properties": {
"role": { "type": "string", "enum": ["system", "user", "assistant"] },
"content": { "type": "string" }
}
}
},
"stream": { "type": "boolean", "default": false },
"user": { "type": "string", "description": "External user ID" }
}
}
}
}
},
"responses": {
"200": { "description": "Chat completion response (or SSE stream if stream=true)" },
"401": { "$ref": "#/components/responses/Unauthorized" },
"429": { "description": "Rate limit exceeded" }
}
}
},
"/v1/api-keys": {
"get": {
"tags": ["API Keys"],
"summary": "List all API keys",
"description": "Returns all API keys (active and revoked). Key hashes are never included in responses. Requires admin access.",
"responses": {
"200": {
"description": "List of API keys",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": { "$ref": "#/components/schemas/ApiKey" }
}
}
}
},
"401": { "$ref": "#/components/responses/Unauthorized" }
}
},
"post": {
"tags": ["API Keys"],
"summary": "Create a new API key",
"description": "Creates a new API key with the specified scopes. The raw key is returned **only once** in the response — store it securely.\n\nAvailable scopes:\n- `operator.admin` — Full admin access\n- `operator.read` — Read-only access\n- `operator.write` — Read + write access\n- `operator.approvals` — Manage exec approvals\n- `operator.pairing` — Manage device pairing",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["name", "scopes"],
"properties": {
"name": { "type": "string", "example": "ci-deploy" },
"scopes": {
"type": "array",
"items": { "type": "string", "enum": ["operator.admin", "operator.read", "operator.write", "operator.approvals", "operator.pairing"] },
"example": ["operator.read", "operator.write"]
},
"expires_in": {
"type": "integer",
"description": "Expiry in seconds. Omit or 0 for never.",
"example": 2592000
}
}
}
}
}
},
"responses": {
"201": {
"description": "API key created. The `key` field is shown only once.",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"id": { "type": "string", "format": "uuid" },
"name": { "type": "string" },
"prefix": { "type": "string", "example": "goclaw_a" },
"key": { "type": "string", "description": "Raw API key (shown once)", "example": "goclaw_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4" },
"scopes": { "type": "array", "items": { "type": "string" } },
"expires_at": { "type": "string", "format": "date-time", "nullable": true },
"created_at": { "type": "string", "format": "date-time" }
}
}
}
}
},
"400": { "$ref": "#/components/responses/BadRequest" },
"401": { "$ref": "#/components/responses/Unauthorized" }
}
}
},
"/v1/api-keys/{id}": {
"delete": {
"tags": ["API Keys"],
"summary": "Revoke an API key",
"description": "Revokes an API key. Revoked keys can no longer be used for authentication. This action cannot be undone.",
"parameters": [
{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }
],
"responses": {
"200": {
"description": "Key revoked",
"content": { "application/json": { "schema": { "type": "object", "properties": { "status": { "type": "string", "example": "revoked" } } } } }
},
"401": { "$ref": "#/components/responses/Unauthorized" },
"404": { "$ref": "#/components/responses/NotFound" }
}
}
},
"/v1/auth/chatgpt/{provider}/quota": {
"get": {
"tags": ["OAuth"],
"summary": "Fetch OpenAI Codex OAuth quota for a provider",
"description": "Returns structured Codex/OpenAI quota state for a specific OpenAI Codex OAuth (`chatgpt_oauth`) provider. Missing provider returns `404`, provider type conflicts return `409`, and upstream quota problems return `200` with `success=false` so dashboards can render inline action states.",
"parameters": [
{
"name": "provider",
"in": "path",
"required": true,
"schema": { "type": "string" },
"description": "Provider alias (for example `openai-codex` or `codex-work`)."
}
],
"responses": {
"200": {
"description": "Provider quota payload",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["provider_name", "success", "windows", "last_updated"],
"properties": {
"provider_name": { "type": "string", "example": "openai-codex" },
"success": { "type": "boolean" },
"plan_type": { "type": "string", "nullable": true, "example": "team" },
"windows": {
"type": "array",
"items": {
"type": "object",
"properties": {
"label": { "type": "string", "example": "Primary" },
"used_percent": { "type": "integer", "example": 24 },
"remaining_percent": { "type": "integer", "example": 76 },
"reset_after_seconds": { "type": "integer", "nullable": true, "example": 3600 },
"reset_at": { "type": "string", "format": "date-time", "nullable": true }
}
}
},
"core_usage": {
"type": "object",
"nullable": true,
"properties": {
"five_hour": {
"type": "object",
"nullable": true,
"properties": {
"label": { "type": "string" },
"remaining_percent": { "type": "integer" },
"reset_after_seconds": { "type": "integer", "nullable": true },
"reset_at": { "type": "string", "format": "date-time", "nullable": true }
}
},
"weekly": {
"type": "object",
"nullable": true,
"properties": {
"label": { "type": "string" },
"remaining_percent": { "type": "integer" },
"reset_after_seconds": { "type": "integer", "nullable": true },
"reset_at": { "type": "string", "format": "date-time", "nullable": true }
}
}
}
},
"last_updated": { "type": "string", "format": "date-time" },
"error": { "type": "string" },
"error_code": { "type": "string" },
"action_hint": { "type": "string" },
"needs_reauth": { "type": "boolean" },
"is_forbidden": { "type": "boolean" },
"retryable": { "type": "boolean" }
}
}
}
}
},
"400": { "$ref": "#/components/responses/BadRequest" },
"401": { "$ref": "#/components/responses/Unauthorized" },
"404": { "$ref": "#/components/responses/NotFound" },
"409": { "$ref": "#/components/responses/Conflict" }
}
}
},
"/v1/auth/openai/quota": {
"get": {
"tags": ["OAuth"],
"summary": "Fetch quota for the default OpenAI Codex OAuth provider",
"description": "Compatibility alias for `/v1/auth/chatgpt/openai-codex/quota`.",
"responses": {
"200": {
"description": "Provider quota payload",
"content": {
"application/json": {
"schema": {
"$ref": "#/paths/~1v1~1auth~1chatgpt~1{provider}~1quota/get/responses/200/content/application~1json/schema"
}
}
}
},
"401": { "$ref": "#/components/responses/Unauthorized" },
"404": { "$ref": "#/components/responses/NotFound" },
"409": { "$ref": "#/components/responses/Conflict" }
}
}
},
"/v1/agents": {
"get": {
"tags": ["Agents"],
"summary": "List agents",
"description": "List all agents accessible to the current user. Owners see all agents.",
"parameters": [
{ "name": "X-GoClaw-User-Id", "in": "header", "required": true, "schema": { "type": "string" } }
],
"responses": {
"200": { "description": "Agent list" },
"401": { "$ref": "#/components/responses/Unauthorized" }
}
},
"post": {
"tags": ["Agents"],
"summary": "Create agent",
"description": "Create a new agent with the specified configuration.",
"requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AgentInput" } } } },
"responses": {
"201": { "description": "Agent created" },
"400": { "$ref": "#/components/responses/BadRequest" },
"401": { "$ref": "#/components/responses/Unauthorized" }
}
}
},
"/v1/agents/{id}": {
"get": {
"tags": ["Agents"],
"summary": "Get agent",
"parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string" } }],
"responses": { "200": { "description": "Agent details" }, "404": { "$ref": "#/components/responses/NotFound" } }
},
"put": {
"tags": ["Agents"],
"summary": "Update agent",
"parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string" } }],
"requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AgentInput" } } } },
"responses": { "200": { "description": "Agent updated" }, "404": { "$ref": "#/components/responses/NotFound" } }
},
"delete": {
"tags": ["Agents"],
"summary": "Delete agent",
"parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string" } }],
"responses": { "200": { "description": "Agent deleted" }, "404": { "$ref": "#/components/responses/NotFound" } }
}
},
"/v1/agents/{id}/codex-pool-activity": {
"get": {
"tags": ["Agents"],
"summary": "Summarize recent OpenAI Codex OAuth pool activity for an agent",
"description": "Returns explicit router-backed evidence for recent OpenAI Codex OAuth calls in the configured provider pool. Direct router selections are reported separately from failover serves, and each recent request shows both the selected alias and the alias that actually served the call.",
"parameters": [
{ "name": "id", "in": "path", "required": true, "schema": { "type": "string" } },
{
"name": "limit",
"in": "query",
"required": false,
"schema": { "type": "integer", "default": 18, "minimum": 1, "maximum": 50 },
"description": "Maximum number of recent routed Codex LLM calls to include."
}
],
"responses": {
"200": {
"description": "Codex pool activity payload",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["strategy", "pool_providers", "stats_sample_size", "provider_counts", "recent_requests"],
"properties": {
"strategy": { "type": "string", "enum": ["primary_first", "round_robin", "priority_order"] },
"pool_providers": {
"type": "array",
"items": { "type": "string" }
},
"stats_sample_size": {
"type": "integer",
"description": "Number of recent routed llm_call spans used to derive runtime health. The server samples max(limit, 120) spans even when recent_requests remains capped by limit."
},
"provider_counts": {
"type": "array",
"items": {
"type": "object",
"required": ["provider_name", "request_count", "direct_selection_count", "failover_serve_count", "success_count", "failure_count", "consecutive_failures", "success_rate", "health_score", "health_state"],
"properties": {
"provider_name": { "type": "string", "description": "Provider alias in the configured pool." },
"request_count": { "type": "integer", "description": "Backward-compatible count of requests where this alias was directly selected by the router." },
"direct_selection_count": { "type": "integer", "description": "Number of recent requests where the router selected this alias first." },
"failover_serve_count": { "type": "integer", "description": "Number of recent requests this alias served after another alias was selected first." },
"success_count": { "type": "integer", "description": "Trace-backed successes attributed to the alias that actually served the request." },
"failure_count": { "type": "integer", "description": "Trace-backed failures attributed to earlier attempted aliases on successful failover, or to every attempted alias on terminal error." },
"consecutive_failures": { "type": "integer", "description": "Newest-first failure streak for this alias." },
"success_rate": { "type": "integer", "description": "Success rate percent derived from recent runtime outcomes." },
"health_score": { "type": "integer", "description": "Heuristic runtime health score from 0 to 100." },
"health_state": { "type": "string", "description": "Health band derived from recent runtime outcomes: idle when there are no outcomes, critical at 3+ consecutive failures or score < 40, degraded below 80, otherwise healthy.", "enum": ["idle", "healthy", "degraded", "critical"] },
"last_selected_at": { "type": "string", "format": "date-time", "nullable": true },
"last_failover_at": { "type": "string", "format": "date-time", "nullable": true },
"last_used_at": { "type": "string", "format": "date-time", "nullable": true },
"last_success_at": { "type": "string", "format": "date-time", "nullable": true },
"last_failure_at": { "type": "string", "format": "date-time", "nullable": true }
}
}
},
"recent_requests": {
"type": "array",
"items": {
"type": "object",
"required": ["span_id", "trace_id", "started_at", "status", "duration_ms", "provider_name", "model", "attempt_count", "used_failover"],
"properties": {
"span_id": { "type": "string", "format": "uuid" },
"trace_id": { "type": "string", "format": "uuid" },
"started_at": { "type": "string", "format": "date-time" },
"status": { "type": "string" },
"duration_ms": { "type": "integer" },
"provider_name": { "type": "string", "description": "Alias that actually served the request. Empty when a terminal failure completed without any alias serving successfully." },
"selected_provider": { "type": "string", "description": "Alias chosen first by the router before any failover." },
"model": { "type": "string" },
"attempt_count": { "type": "integer" },
"used_failover": { "type": "boolean" },
"failover_providers": {
"type": "array",
"items": { "type": "string" }
}
}
}
}
}
}
}
}
},
"401": { "$ref": "#/components/responses/Unauthorized" },
"404": { "$ref": "#/components/responses/NotFound" }
}
}
},
"/v1/agents/{id}/wake": {
"post": {
"tags": ["Agents"],
"summary": "Wake/trigger agent externally",
"description": "Trigger an agent run from an external webhook or automation.",
"parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string" } }],
"requestBody": { "content": { "application/json": { "schema": { "type": "object", "properties": { "message": { "type": "string" }, "user_id": { "type": "string" } } } } } },
"responses": { "200": { "description": "Agent triggered" } }
}
},
"/v1/providers": {
"get": {
"tags": ["Providers"],
"summary": "List LLM providers",
"responses": { "200": { "description": "Provider list (API keys masked)" } }
},
"post": {
"tags": ["Providers"],
"summary": "Create LLM provider",
"requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ProviderInput" } } } },
"responses": { "201": { "description": "Provider created" } }
}
},
"/v1/providers/{id}": {
"get": {
"tags": ["Providers"],
"summary": "Get provider",
"parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }],
"responses": { "200": { "description": "Provider details (API key masked)" } }
},
"put": {
"tags": ["Providers"],
"summary": "Update provider",
"parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }],
"responses": { "200": { "description": "Provider updated" } }
},
"delete": {
"tags": ["Providers"],
"summary": "Delete provider",
"parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }],
"responses": { "200": { "description": "Provider deleted" } }
}
},
"/v1/providers/{id}/models": {
"get": {
"tags": ["Providers"],
"summary": "List available models",
"parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }],
"responses": { "200": { "description": "Model list" } }
}
},
"/v1/providers/{id}/verify": {
"post": {
"tags": ["Providers"],
"summary": "Verify provider connection",
"description": "Test provider connectivity with a minimal LLM call.",
"parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }],
"requestBody": { "content": { "application/json": { "schema": { "type": "object", "properties": { "model": { "type": "string" } } } } } },
"responses": { "200": { "description": "Verification result", "content": { "application/json": { "schema": { "type": "object", "properties": { "valid": { "type": "boolean" }, "error": { "type": "string" } } } } } } }
}
},
"/v1/skills": {
"get": {
"tags": ["Skills"],
"summary": "List all skills",
"responses": { "200": { "description": "Skill list" } }
},
"post": {
"tags": ["Skills"],
"summary": "Upload skill",
"requestBody": { "content": { "multipart/form-data": {} } },
"responses": { "201": { "description": "Skill uploaded" } }
}
},
"/v1/skills/{id}": {
"get": {
"tags": ["Skills"],
"summary": "Get skill",
"parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string" } }],
"responses": { "200": { "description": "Skill details" } }
},
"put": {
"tags": ["Skills"],
"summary": "Update skill",
"parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string" } }],
"responses": { "200": { "description": "Skill updated" } }
},
"delete": {
"tags": ["Skills"],
"summary": "Delete skill",
"parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string" } }],
"responses": { "200": { "description": "Skill deleted" } }
}
},
"/v1/tools/custom": {
"get": {
"tags": ["Custom Tools"],
"summary": "List custom tools",
"responses": { "200": { "description": "Custom tool list" } }
},
"post": {
"tags": ["Custom Tools"],
"summary": "Create custom tool",
"responses": { "201": { "description": "Tool created" } }
}
},
"/v1/tools/custom/{id}": {
"get": {
"tags": ["Custom Tools"],
"summary": "Get custom tool",
"parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }],
"responses": { "200": { "description": "Tool details" } }
},
"put": {
"tags": ["Custom Tools"],
"summary": "Update custom tool",
"parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }],
"responses": { "200": { "description": "Tool updated" } }
},
"delete": {
"tags": ["Custom Tools"],
"summary": "Delete custom tool",
"parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }],
"responses": { "200": { "description": "Tool deleted" } }
}
},
"/v1/tools/builtin": {
"get": {
"tags": ["Built-in Tools"],
"summary": "List built-in tools",
"responses": { "200": { "description": "Built-in tool list" } }
}
},
"/v1/tools/builtin/{name}": {
"get": {
"tags": ["Built-in Tools"],
"summary": "Get built-in tool",
"parameters": [{ "name": "name", "in": "path", "required": true, "schema": { "type": "string" } }],
"responses": { "200": { "description": "Tool details" } }
},
"put": {
"tags": ["Built-in Tools"],
"summary": "Update tool settings",
"parameters": [{ "name": "name", "in": "path", "required": true, "schema": { "type": "string" } }],
"responses": { "200": { "description": "Tool updated" } }
}
},
"/v1/mcp/servers": {
"get": {
"tags": ["MCP Servers"],
"summary": "List MCP servers",
"responses": { "200": { "description": "MCP server list" } }
},
"post": {
"tags": ["MCP Servers"],
"summary": "Create MCP server",
"responses": { "201": { "description": "Server created" } }
}
},
"/v1/mcp/servers/{id}": {
"get": {
"tags": ["MCP Servers"],
"summary": "Get MCP server",
"parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }],
"responses": { "200": { "description": "Server details" } }
},
"put": {
"tags": ["MCP Servers"],
"summary": "Update MCP server",
"parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }],
"responses": { "200": { "description": "Server updated" } }
},
"delete": {
"tags": ["MCP Servers"],
"summary": "Delete MCP server",
"parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }],
"responses": { "200": { "description": "Server deleted" } }
}
},
"/v1/mcp/servers/{id}/tools": {
"get": {
"tags": ["MCP Servers"],
"summary": "List server tools",
"parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }],
"responses": { "200": { "description": "Tool list" } }
}
},
"/v1/memory/documents": {
"get": {
"tags": ["Memory"],
"summary": "List all memory documents",
"responses": { "200": { "description": "Document list" } }
}
},
"/v1/agents/{agentID}/memory/search": {
"post": {
"tags": ["Memory"],
"summary": "Search agent memory",
"parameters": [{ "name": "agentID", "in": "path", "required": true, "schema": { "type": "string" } }],
"requestBody": { "content": { "application/json": { "schema": { "type": "object", "properties": { "query": { "type": "string" }, "limit": { "type": "integer", "default": 10 } } } } } },
"responses": { "200": { "description": "Search results" } }
}
},
"/v1/agents/{agentID}/kg/entities": {
"get": {
"tags": ["Knowledge Graph"],
"summary": "List KG entities",
"parameters": [{ "name": "agentID", "in": "path", "required": true, "schema": { "type": "string" } }],
"responses": { "200": { "description": "Entity list" } }
},
"post": {
"tags": ["Knowledge Graph"],
"summary": "Upsert KG entity",
"parameters": [{ "name": "agentID", "in": "path", "required": true, "schema": { "type": "string" } }],
"responses": { "200": { "description": "Entity upserted" } }
}
},
"/v1/agents/{agentID}/kg/traverse": {
"post": {
"tags": ["Knowledge Graph"],
"summary": "Traverse knowledge graph",
"parameters": [{ "name": "agentID", "in": "path", "required": true, "schema": { "type": "string" } }],
"responses": { "200": { "description": "Traversal results" } }
}
},
"/v1/channels/instances": {
"get": {
"tags": ["Channels"],
"summary": "List channel instances",
"responses": { "200": { "description": "Instance list" } }
},
"post": {
"tags": ["Channels"],
"summary": "Create channel instance",
"responses": { "201": { "description": "Instance created" } }
}
},
"/v1/channels/instances/{id}": {
"get": {
"tags": ["Channels"],
"summary": "Get channel instance",
"parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }],
"responses": { "200": { "description": "Instance details" } }
},
"put": {
"tags": ["Channels"],
"summary": "Update channel instance",
"parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }],
"responses": { "200": { "description": "Instance updated" } }
},
"delete": {
"tags": ["Channels"],
"summary": "Delete channel instance",
"parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }],
"responses": { "200": { "description": "Instance deleted" } }
}
},
"/v1/contacts": {
"get": {
"tags": ["Channels"],
"summary": "List channel contacts",
"responses": { "200": { "description": "Contact list" } }
}
},
"/v1/traces": {
"get": {
"tags": ["Traces"],
"summary": "List LLM traces",
"parameters": [
{ "name": "limit", "in": "query", "schema": { "type": "integer", "default": 50 } },
{ "name": "offset", "in": "query", "schema": { "type": "integer", "default": 0 } },
{ "name": "agent_id", "in": "query", "schema": { "type": "string" } }
],
"responses": { "200": { "description": "Trace list" } }
}
},
"/v1/traces/{traceID}": {
"get": {
"tags": ["Traces"],
"summary": "Get trace detail",
"parameters": [{ "name": "traceID", "in": "path", "required": true, "schema": { "type": "string" } }],
"responses": { "200": { "description": "Trace detail with messages" } }
}
},
"/v1/costs/summary": {
"get": {
"tags": ["Traces"],
"summary": "Get cost summary",
"responses": { "200": { "description": "Cost summary" } }
}
},
"/v1/usage/timeseries": {
"get": {
"tags": ["Usage"],
"summary": "Usage timeseries analytics",
"parameters": [
{ "name": "period", "in": "query", "schema": { "type": "string", "enum": ["1h", "24h", "7d", "30d"] } }
],
"responses": { "200": { "description": "Timeseries data" } }
}
},
"/v1/usage/summary": {
"get": {
"tags": ["Usage"],
"summary": "Usage summary",
"responses": { "200": { "description": "Usage summary" } }
}
},
"/v1/activity": {
"get": {
"tags": ["Activity"],
"summary": "List audit activity logs",
"parameters": [
{ "name": "limit", "in": "query", "schema": { "type": "integer", "default": 50 } },
{ "name": "offset", "in": "query", "schema": { "type": "integer", "default": 0 } }
],
"responses": { "200": { "description": "Activity log entries" } }
}
},
"/v1/delegations": {
"get": {
"tags": ["Activity"],
"summary": "List delegation history",
"responses": { "200": { "description": "Delegation list" } }
}
},
"/v1/storage/files": {
"get": {
"tags": ["Storage"],
"summary": "List workspace files",
"parameters": [
{ "name": "path", "in": "query", "schema": { "type": "string" }, "description": "Subdirectory path" }
],
"responses": { "200": { "description": "File listing" } }
}
},
"/v1/media/upload": {
"post": {
"tags": ["Media"],
"summary": "Upload media file",
"requestBody": { "content": { "multipart/form-data": { "schema": { "type": "object", "properties": { "file": { "type": "string", "format": "binary" } } } } } },
"responses": { "200": { "description": "Upload result with temp path and MIME type" } }
}
},
"/v1/media/{id}": {
"get": {
"tags": ["Media"],
"summary": "Serve media by ID",
"parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string" } }],
"responses": { "200": { "description": "Media file" } }
}
},
"/v1/pending-messages": {
"get": {
"tags": ["Channels"],
"summary": "List pending message groups",
"responses": { "200": { "description": "Message group list" } }
},
"delete": {
"tags": ["Channels"],
"summary": "Clear pending message group",
"responses": { "200": { "description": "Group cleared" } }
}
}
},
"components": {
"securitySchemes": {
"bearerAuth": {
"type": "http",
"scheme": "bearer",
"description": "Gateway token or API key"
}
},
"schemas": {
"ApiKey": {
"type": "object",
"properties": {
"id": { "type": "string", "format": "uuid" },
"name": { "type": "string" },
"prefix": { "type": "string", "description": "First 8 chars for identification" },
"scopes": { "type": "array", "items": { "type": "string" } },
"expires_at": { "type": "string", "format": "date-time", "nullable": true },
"last_used_at": { "type": "string", "format": "date-time", "nullable": true },
"revoked": { "type": "boolean" },
"created_by": { "type": "string" },
"created_at": { "type": "string", "format": "date-time" },
"updated_at": { "type": "string", "format": "date-time" }
}
},
"AgentInput": {
"type": "object",
"properties": {
"name": { "type": "string", "description": "Unique agent slug" },
"display_name": { "type": "string" },
"agent_type": { "type": "string", "enum": ["open", "predefined"] },
"description": { "type": "string" },
"provider": { "type": "string", "description": "LLM provider name" },
"model": { "type": "string", "description": "Model ID" },
"system_prompt": { "type": "string" },
"other_config": {
"type": "object",
"description": "Optional per-agent JSON config.",
"properties": {
"chatgpt_oauth_routing": {
"type": "object",
"description": "Optional agent-side routing override for ChatGPT OAuth providers. The main provider field remains the preferred/default account, while provider settings may supply inherited defaults.",
"properties": {
"override_mode": { "type": "string", "enum": ["inherit", "custom"] },
"strategy": { "type": "string", "enum": ["manual", "primary_first", "round_robin", "priority_order"] },
"extra_provider_names": { "type": "array", "items": { "type": "string" } }
}
}
}
}
}
},
"ProviderInput": {
"type": "object",
"required": ["name", "provider_type"],
"properties": {
"name": { "type": "string", "description": "Unique provider slug" },
"display_name": { "type": "string" },
"provider_type": { "type": "string", "enum": ["anthropic_native", "openai_compat", "gemini_native", "openrouter", "groq", "deepseek", "mistral", "xai", "minimax_native", "cohere", "perplexity", "dashscope", "bailian", "chatgpt_oauth", "claude_cli", "suno", "yescale", "zai", "zai_coding", "ollama", "ollama_cloud", "acp"] },
"api_base": { "type": "string" },
"api_key": { "type": "string" },
"enabled": { "type": "boolean", "default": true }
}
},
"Error": {
"type": "object",
"properties": {
"error": { "type": "string" }
}
}
},
"responses": {
"Unauthorized": {
"description": "Authentication required or invalid token",
"content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
},
"BadRequest": {
"description": "Invalid request parameters",
"content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
},
"NotFound": {
"description": "Resource not found",
"content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
},
"Conflict": {
"description": "Resource state conflict",
"content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
}
}
}
}