Management API
Base path: http://localhost:8317/v0/management
This API manages the CLI Proxy API’s runtime configuration and authentication files. All changes are persisted to the YAML config file and hot‑reloaded by the service.
Note: The following options cannot be modified via API and must be set in the config file (restart if needed):
allow-remote-managementremote-management-key(if plaintext is detected at startup, it is automatically bcrypt‑hashed and written back to the config)
Authentication
- All requests (including localhost) must provide a valid management key.
- Remote access requires enabling remote management in the config:
allow-remote-management: true. - Provide the management key (in plaintext) via either:
Authorization: Bearer <plaintext-key>X-Management-Key: <plaintext-key>
Additional notes:
- If
remote-management.secret-keyis empty, the entire Management API is disabled (all/v0/managementroutes return 404). - For remote IPs, 5 consecutive authentication failures trigger a temporary ban (~30 minutes) before further attempts are allowed.
If a plaintext key is detected in the config at startup, it will be bcrypt‑hashed and written back to the config file automatically.
Request/Response Conventions
- Content-Type:
application/json(unless otherwise noted). - Boolean/int/string updates: request body is
{ "value": <type> }. - Array PUT: either a raw array (e.g.
["a","b"]) or{ "items": [ ... ] }. - Array PATCH: supports
{ "old": "k1", "new": "k2" }or{ "index": 0, "value": "k2" }. - Object-array PATCH: supports matching by index or by key field (specified per endpoint).
Endpoints
Usage Statistics
- GET
/usage— Retrieve aggregated in-memory request metrics- Response:json
{ "usage": { "total_requests": 24, "success_count": 22, "failure_count": 2, "total_tokens": 13890, "requests_by_day": { "2024-05-20": 12 }, "requests_by_hour": { "09": 4, "18": 8 }, "tokens_by_day": { "2024-05-20": 9876 }, "tokens_by_hour": { "09": 1234, "18": 865 }, "apis": { "POST /v1/chat/completions": { "total_requests": 12, "total_tokens": 9021, "models": { "gpt-4o-mini": { "total_requests": 8, "total_tokens": 7123, "details": [ { "timestamp": "2024-05-20T09:15:04.123456Z", "tokens": { "input_tokens": 523, "output_tokens": 308, "reasoning_tokens": 0, "cached_tokens": 0, "total_tokens": 831 } } ] } } } } }, "failed_requests": 2 } - Notes:
- Statistics are recalculated for every request that reports token usage; data resets when the server restarts.
- Hourly counters fold all days into the same hour bucket (
00–23). - The top-level
failed_requestsrepeatsusage.failure_countfor convenience when polling.
- Response:
Config
- GET
/config— Get the full config- Request:bash
curl -H 'Authorization: Bearer <MANAGEMENT_KEY>' http://localhost:8317/v0/management/config - Response:json
{"debug":true,"proxy-url":"","api-keys":["1...5","JS...W"],"quota-exceeded":{"switch-project":true,"switch-preview-model":true},"gemini-api-key":[{"api-key":"AI...01","base-url":"https://generativelanguage.googleapis.com","headers":{"X-Custom-Header":"custom-value"},"proxy-url":""},{"api-key":"AI...02","proxy-url":"socks5://proxy.example.com:1080"}],"generative-language-api-key":["AI...01","AI...02"],"request-log":true,"request-retry":3,"claude-api-key":[{"api-key":"cr...56","base-url":"https://example.com/api","proxy-url":"socks5://proxy.example.com:1080","models":[{"name":"claude-3-5-sonnet-20241022","alias":"claude-sonnet-latest"}]},{"api-key":"cr...e3","base-url":"http://example.com:3000/api","proxy-url":""},{"api-key":"sk-...q2","base-url":"https://example.com","proxy-url":""}],"codex-api-key":[{"api-key":"sk...01","base-url":"https://example/v1","proxy-url":""}],"openai-compatibility":[{"name":"openrouter","base-url":"https://openrouter.ai/api/v1","api-key-entries":[{"api-key":"sk...01","proxy-url":""}],"models":[{"name":"moonshotai/kimi-k2:free","alias":"kimi-k2"}]},{"name":"iflow","base-url":"https://apis.iflow.cn/v1","api-key-entries":[{"api-key":"sk...7e","proxy-url":"socks5://proxy.example.com:1080"}],"models":[{"name":"deepseek-v3.1","alias":"deepseek-v3.1"},{"name":"glm-4.5","alias":"glm-4.5"},{"name":"kimi-k2","alias":"kimi-k2"}]}]} - Notes:
- The response includes a sanitized
gl-api-keylist derived from the detailedgemini-api-keyentries. - When no configuration is loaded yet the handler returns
{}.
- The response includes a sanitized
- Request:
Debug
- GET
/debug— Get the current debug state- Request:bash
curl -H 'Authorization: Bearer <MANAGEMENT_KEY>' http://localhost:8317/v0/management/debug - Response:json
{ "debug": false }
- Request:
- PUT/PATCH
/debug— Set debug (boolean)- Request:bash
curl -X PUT -H 'Content-Type: application/json' \ -H 'Authorization: Bearer <MANAGEMENT_KEY>' \ -d '{"value":true}' \ http://localhost:8317/v0/management/debug - Response:json
{ "status": "ok" }
- Request:
Config YAML
- GET
/config.yaml— Download the persisted YAML file as-is- Response headers:
Content-Type: application/yaml; charset=utf-8Cache-Control: no-store
- Response body: raw YAML stream preserving comments/formatting.
- Response headers:
- PUT
/config.yaml— Replace the config with a YAML document- Request:bash
curl -X PUT -H 'Content-Type: application/yaml' \ -H 'Authorization: Bearer <MANAGEMENT_KEY>' \ --data-binary @config.yaml \ http://localhost:8317/v0/management/config.yaml - Response:json
{ "ok": true, "changed": ["config"] } - Notes:
- The server validates the YAML by loading it before persisting; invalid configs return
422with{ "error": "invalid_config", "message": "..." }. - Write failures return
500with{ "error": "write_failed", "message": "..." }.
- The server validates the YAML by loading it before persisting; invalid configs return
- Request:
Logging to File
- GET
/logging-to-file— Check whether file logging is enabled- Response:json
{ "logging-to-file": true }
- Response:
- PUT/PATCH
/logging-to-file— Enable or disable file logging- Request:bash
curl -X PATCH -H 'Content-Type: application/json' \ -H 'Authorization: Bearer <MANAGEMENT_KEY>' \ -d '{"value":false}' \ http://localhost:8317/v0/management/logging-to-file - Response:json
{ "status": "ok" }
- Request:
Log Files
- GET
/logs— Stream recent log lines- Query params:
after(optional): Unix timestamp; only lines newer than this are returned.
- Response:json
{ "lines": ["2024-05-20 12:00:00 info request accepted"], "line-count": 125, "latest-timestamp": 1716206400 } - Notes:
- Requires file logging to be enabled; otherwise returns
{ "error": "logging to file disabled" }with400. - When no log file exists yet the response contains empty
linesandline-count: 0.
- Requires file logging to be enabled; otherwise returns
- Query params:
- DELETE
/logs— Remove rotated log files and truncate the active log- Response:json
{ "success": true, "message": "Logs cleared successfully", "removed": 3 }
- Response:
Usage Statistics Toggle
- GET
/usage-statistics-enabled— Check whether telemetry collection is active- Response:json
{ "usage-statistics-enabled": true }
- Response:
- PUT/PATCH
/usage-statistics-enabled— Enable or disable collection- Request:bash
curl -X PUT -H 'Content-Type: application/json' \ -H 'Authorization: Bearer <MANAGEMENT_KEY>' \ -d '{"value":true}' \ http://localhost:8317/v0/management/usage-statistics-enabled - Response:json
{ "status": "ok" }
- Request:
Proxy Server URL
- GET
/proxy-url— Get the proxy URL string- Request:bash
curl -H 'Authorization: Bearer <MANAGEMENT_KEY>' http://localhost:8317/v0/management/proxy-url - Response:json
{ "proxy-url": "socks5://user:[email protected]:1080/" }
- Request:
- PUT/PATCH
/proxy-url— Set the proxy URL string- Request (PUT):bash
curl -X PUT -H 'Content-Type: application/json' \ -H 'Authorization: Bearer <MANAGEMENT_KEY>' \ -d '{"value":"socks5://user:[email protected]:1080/"}' \ http://localhost:8317/v0/management/proxy-url - Request (PATCH):bash
curl -X PATCH -H 'Content-Type: application/json' \ -H 'Authorization: Bearer <MANAGEMENT_KEY>' \ -d '{"value":"http://127.0.0.1:8080"}' \ http://localhost:8317/v0/management/proxy-url - Response:json
{ "status": "ok" }
- Request (PUT):
- DELETE
/proxy-url— Clear the proxy URL- Request:bash
curl -H 'Authorization: Bearer <MANAGEMENT_KEY>' -X DELETE http://localhost:8317/v0/management/proxy-url - Response:json
{ "status": "ok" }
- Request:
Quota Exceeded Behavior
- GET
/quota-exceeded/switch-project- Request:bash
curl -H 'Authorization: Bearer <MANAGEMENT_KEY>' http://localhost:8317/v0/management/quota-exceeded/switch-project - Response:json
{ "switch-project": true }
- Request:
- PUT/PATCH
/quota-exceeded/switch-project— Boolean- Request:bash
curl -X PUT -H 'Content-Type: application/json' \ -H 'Authorization: Bearer <MANAGEMENT_KEY>' \ -d '{"value":false}' \ http://localhost:8317/v0/management/quota-exceeded/switch-project - Response:json
{ "status": "ok" }
- Request:
- GET
/quota-exceeded/switch-preview-model- Request:bash
curl -H 'Authorization: Bearer <MANAGEMENT_KEY>' http://localhost:8317/v0/management/quota-exceeded/switch-preview-model - Response:json
{ "switch-preview-model": true }
- Request:
- PUT/PATCH
/quota-exceeded/switch-preview-model— Boolean- Request:bash
curl -X PATCH -H 'Content-Type: application/json' \ -H 'Authorization: Bearer <MANAGEMENT_KEY>' \ -d '{"value":true}' \ http://localhost:8317/v0/management/quota-exceeded/switch-preview-model - Response:json
{ "status": "ok" }
- Request:
API Keys (proxy service auth)
These endpoints update the inline config-api-key provider inside the auth.providers section of the configuration. Legacy top-level api-keys remain in sync automatically.
- GET
/api-keys— Return the full list- Request:bash
curl -H 'Authorization: Bearer <MANAGEMENT_KEY>' http://localhost:8317/v0/management/api-keys - Response:json
{ "api-keys": ["k1","k2","k3"] }
- Request:
- PUT
/api-keys— Replace the full list- Request:bash
curl -X PUT -H 'Content-Type: application/json' \ -H 'Authorization: Bearer <MANAGEMENT_KEY>' \ -d '["k1","k2","k3"]' \ http://localhost:8317/v0/management/api-keys - Response:json
{ "status": "ok" }
- Request:
- PATCH
/api-keys— Modify one item (old/neworindex/value)- Request (by old/new):bash
curl -X PATCH -H 'Content-Type: application/json' \ -H 'Authorization: Bearer <MANAGEMENT_KEY>' \ -d '{"old":"k2","new":"k2b"}' \ http://localhost:8317/v0/management/api-keys - Request (by index/value):bash
curl -X PATCH -H 'Content-Type: application/json' \ -H 'Authorization: Bearer <MANAGEMENT_KEY>' \ -d '{"index":0,"value":"k1b"}' \ http://localhost:8317/v0/management/api-keys - Response:json
{ "status": "ok" }
- Request (by old/new):
- DELETE
/api-keys— Delete one (?value=or?index=)- Request (by value):bash
curl -H 'Authorization: Bearer <MANAGEMENT_KEY>' -X DELETE 'http://localhost:8317/v0/management/api-keys?value=k1' - Request (by index):bash
curl -H 'Authorization: Bearer <MANAGEMENT_KEY>' -X DELETE 'http://localhost:8317/v0/management/api-keys?index=0' - Response:json
{ "status": "ok" }
- Request (by value):
Gemini API Key
- GET
/gemini-api-key- Request:bash
curl -H 'Authorization: Bearer <MANAGEMENT_KEY>' http://localhost:8317/v0/management/gemini-api-key - Response:json
{ "gemini-api-key": [ {"api-key":"AIzaSy...01","base-url":"https://generativelanguage.googleapis.com","headers":{"X-Custom-Header":"custom-value"},"proxy-url":""}, {"api-key":"AIzaSy...02","proxy-url":"socks5://proxy.example.com:1080"} ] }
- Request:
- PUT
/gemini-api-key- Request (array form):bash
curl -X PUT -H 'Content-Type: application/json' \ -H 'Authorization: Bearer <MANAGEMENT_KEY>' \ -d '[{"api-key":"AIzaSy-1","headers":{"X-Custom-Header":"vendor-value"}},{"api-key":"AIzaSy-2","base-url":"https://custom.example.com"}]' \ http://localhost:8317/v0/management/gemini-api-key - Response:json
{ "status": "ok" }
- Request (array form):
- PATCH
/gemini-api-key- Request (update by index):bash
curl -X PATCH -H 'Content-Type: application/json' \ -H 'Authorization: Bearer <MANAGEMENT_KEY>' \ -d '{"index":0,"value":{"api-key":"AIzaSy-1","base-url":"https://custom.example.com","headers":{"X-Custom-Header":"custom-value"},"proxy-url":""}}' \ http://localhost:8317/v0/management/gemini-api-key - Request (update by api-key match):bash
curl -X PATCH -H 'Content-Type: application/json' \ -H 'Authorization: Bearer <MANAGEMENT_KEY>' \ -d '{"match":"AIzaSy-1","value":{"api-key":"AIzaSy-1","headers":{"X-Custom-Header":"custom-value"},"proxy-url":"socks5://proxy.example.com:1080"}}' \ http://localhost:8317/v0/management/gemini-api-key - Response:json
{ "status": "ok" }
- Request (update by index):
- DELETE
/gemini-api-key- Request (by api-key):bash
curl -H 'Authorization: Bearer <MANAGEMENT_KEY>' -X DELETE \ 'http://localhost:8317/v0/management/gemini-api-key?api-key=AIzaSy-1' - Request (by index):bash
curl -H 'Authorization: Bearer <MANAGEMENT_KEY>' -X DELETE \ 'http://localhost:8317/v0/management/gemini-api-key?index=0' - Response:json
{ "status": "ok" }
- Request (by api-key):
Generative Language API Key (Legacy Alias)
- GET
/generative-language-api-key- Request:bash
curl -H 'Authorization: Bearer <MANAGEMENT_KEY>' http://localhost:8317/v0/management/generative-language-api-key - Response:json
{ "generative-language-api-key": ["AIzaSy...01","AIzaSy...02"] }
- Request:
- PUT
/generative-language-api-key- Request:bash
curl -X PUT -H 'Content-Type: application/json' \ -H 'Authorization: Bearer <MANAGEMENT_KEY>' \ -d '["AIzaSy-1","AIzaSy-2"]' \ http://localhost:8317/v0/management/generative-language-api-key - Response:json
{ "status": "ok" }
- Request:
- PATCH
/generative-language-api-key- Request:bash
curl -X PATCH -H 'Content-Type: application/json' \ -H 'Authorization: Bearer <MANAGEMENT_KEY>' \ -d '{"old":"AIzaSy-1","new":"AIzaSy-1b"}' \ http://localhost:8317/v0/management/generative-language-api-key - Response:json
{ "status": "ok" }
- Request:
- DELETE
/generative-language-api-key- Request:bash
curl -H 'Authorization: Bearer <MANAGEMENT_KEY>' -X DELETE 'http://localhost:8317/v0/management/generative-language-api-key?value=AIzaSy-2' - Response:json
{ "status": "ok" }
- Request:
- Notes:
- This endpoint mirrors the key-only view of
gemini-api-key.
- This endpoint mirrors the key-only view of
Codex API KEY (object array)
- GET
/codex-api-key— List all- Request:bash
curl -H 'Authorization: Bearer <MANAGEMENT_KEY>' http://localhost:8317/v0/management/codex-api-key - Response:json
{ "codex-api-key": [ { "api-key": "sk-a", "base-url": "", "proxy-url": "" } ] }
- Request:
- PUT
/codex-api-key— Replace the list- Request:bash
curl -X PUT -H 'Content-Type: application/json' \ -H 'Authorization: Bearer <MANAGEMENT_KEY>' \ -d '[{"api-key":"sk-a","proxy-url":"socks5://proxy.example.com:1080"},{"api-key":"sk-b","base-url":"https://c.example.com","proxy-url":""}]' \ http://localhost:8317/v0/management/codex-api-key - Response:json
{ "status": "ok" }
- Request:
- PATCH
/codex-api-key— Modify one (byindexormatch)- Request (by index):bash
curl -X PATCH -H 'Content-Type: application/json' \ -H 'Authorization: Bearer <MANAGEMENT_KEY>' \ -d '{"index":1,"value":{"api-key":"sk-b2","base-url":"https://c.example.com","proxy-url":""}}' \ http://localhost:8317/v0/management/codex-api-key - Request (by match):bash
curl -X PATCH -H 'Content-Type: application/json' \ -H 'Authorization: Bearer <MANAGEMENT_KEY>' \ -d '{"match":"sk-a","value":{"api-key":"sk-a","base-url":"","proxy-url":"socks5://proxy.example.com:1080"}}' \ http://localhost:8317/v0/management/codex-api-key - Response:json
{ "status": "ok" }
- Request (by index):
- DELETE
/codex-api-key— Delete one (?api-key=or?index=)- Request (by api-key):bash
curl -H 'Authorization: Bearer <MANAGEMENT_KEY>' -X DELETE 'http://localhost:8317/v0/management/codex-api-key?api-key=sk-b2' - Request (by index):bash
curl -H 'Authorization: Bearer <MANAGEMENT_KEY>' -X DELETE 'http://localhost:8317/v0/management/codex-api-key?index=0' - Response:json
{ "status": "ok" }
- Request (by api-key):
Request Retry Count
- GET
/request-retry— Get integer- Request:bash
curl -H 'Authorization: Bearer <MANAGEMENT_KEY>' http://localhost:8317/v0/management/request-retry - Response:json
{ "request-retry": 3 }
- Request:
- PUT/PATCH
/request-retry— Set integer- Request:bash
curl -X PATCH -H 'Content-Type: application/json' \ -H 'Authorization: Bearer <MANAGEMENT_KEY>' \ -d '{"value":5}' \ http://localhost:8317/v0/management/request-retry - Response:json
{ "status": "ok" }
- Request:
Request Log
- GET
/request-log— Get boolean- Request:bash
curl -H 'Authorization: Bearer <MANAGEMENT_KEY>' http://localhost:8317/v0/management/request-log - Response:json
{ "request-log": false }
- Request:
- PUT/PATCH
/request-log— Set boolean- Request:bash
curl -X PATCH -H 'Content-Type: application/json' \ -H 'Authorization: Bearer <MANAGEMENT_KEY>' \ -d '{"value":true}' \ http://localhost:8317/v0/management/request-log - Response:json
{ "status": "ok" }
- Request:
Claude API KEY (object array)
- GET
/claude-api-key— List all- Request:bash
curl -H 'Authorization: Bearer <MANAGEMENT_KEY>' http://localhost:8317/v0/management/claude-api-key - Response:json
{ "claude-api-key": [ { "api-key": "sk-a", "base-url": "", "proxy-url": "" } ] }
- Request:
- PUT
/claude-api-key— Replace the list- Request:bash
curl -X PUT -H 'Content-Type: application/json' \ -H 'Authorization: Bearer <MANAGEMENT_KEY>' \ -d '[{"api-key":"sk-a","proxy-url":"socks5://proxy.example.com:1080"},{"api-key":"sk-b","base-url":"https://c.example.com","proxy-url":""}]' \ http://localhost:8317/v0/management/claude-api-key - Response:json
{ "status": "ok" }
- Request:
- PATCH
/claude-api-key— Modify one (byindexormatch)- Request (by index):bash
curl -X PATCH -H 'Content-Type: application/json' \ -H 'Authorization: Bearer <MANAGEMENT_KEY>' \ -d '{"index":1,"value":{"api-key":"sk-b2","base-url":"https://c.example.com","proxy-url":""}}' \ http://localhost:8317/v0/management/claude-api-key - Request (by match):bash
curl -X PATCH -H 'Content-Type: application/json' \ -H 'Authorization: Bearer <MANAGEMENT_KEY>' \ -d '{"match":"sk-a","value":{"api-key":"sk-a","base-url":"","proxy-url":"socks5://proxy.example.com:1080"}}' \ http://localhost:8317/v0/management/claude-api-key - Response:json
{ "status": "ok" }
- Request (by index):
- DELETE
/claude-api-key— Delete one (?api-key=or?index=)- Request (by api-key):bash
curl -H 'Authorization: Bearer <MANAGEMENT_KEY>' -X DELETE 'http://localhost:8317/v0/management/claude-api-key?api-key=sk-b2' - Request (by index):bash
curl -H 'Authorization: Bearer <MANAGEMENT_KEY>' -X DELETE 'http://localhost:8317/v0/management/claude-api-key?index=0' - Response:json
{ "status": "ok" }
- Request (by api-key):
OpenAI Compatibility Providers (object array)
- GET
/openai-compatibility— List all- Request:bash
curl -H 'Authorization: Bearer <MANAGEMENT_KEY>' http://localhost:8317/v0/management/openai-compatibility - Response:json
{ "openai-compatibility": [ { "name": "openrouter", "base-url": "https://openrouter.ai/api/v1", "api-key-entries": [ { "api-key": "sk", "proxy-url": "" } ], "models": [] } ] }
- Request:
- PUT
/openai-compatibility— Replace the list- Request:bash
curl -X PUT -H 'Content-Type: application/json' \ -H 'Authorization: Bearer <MANAGEMENT_KEY>' \ -d '[{"name":"openrouter","base-url":"https://openrouter.ai/api/v1","api-key-entries":[{"api-key":"sk","proxy-url":""}],"models":[{"name":"m","alias":"a"}]}]' \ http://localhost:8317/v0/management/openai-compatibility - Response:json
{ "status": "ok" }
- Request:
- PATCH
/openai-compatibility— Modify one (byindexorname)Request (by name):
bashcurl -X PATCH -H 'Content-Type: application/json' \ -H 'Authorization: Bearer <MANAGEMENT_KEY>' \ -d '{"name":"openrouter","value":{"name":"openrouter","base-url":"https://openrouter.ai/api/v1","api-key-entries":[{"api-key":"sk","proxy-url":""}],"models":[]}}' \ http://localhost:8317/v0/management/openai-compatibilityRequest (by index):
bashcurl -X PATCH -H 'Content-Type: application/json' \ -H 'Authorization: Bearer <MANAGEMENT_KEY>' \ -d '{"index":0,"value":{"name":"openrouter","base-url":"https://openrouter.ai/api/v1","api-key-entries":[{"api-key":"sk","proxy-url":""}],"models":[]}}' \ http://localhost:8317/v0/management/openai-compatibilityResponse:
json{ "status": "ok" }Notes:
- Legacy
api-keysinput remains accepted; keys are migrated intoapi-key-entriesautomatically so the legacy field will eventually remain empty in responses.
- Legacy
- DELETE
/openai-compatibility— Delete (?name=or?index=)- Request (by name):bash
curl -H 'Authorization: Bearer <MANAGEMENT_KEY>' -X DELETE 'http://localhost:8317/v0/management/openai-compatibility?name=openrouter' - Request (by index):bash
curl -H 'Authorization: Bearer <MANAGEMENT_KEY>' -X DELETE 'http://localhost:8317/v0/management/openai-compatibility?index=0' - Response:json
{ "status": "ok" }
- Request (by name):
Auth File Management
Manage JSON token files under auth-dir: list, download, upload, delete.
GET
/auth-files— List- Request:bash
curl -H 'Authorization: Bearer <MANAGEMENT_KEY>' http://localhost:8317/v0/management/auth-files - Response:json
{ "files": [ { "name": "acc1.json", "size": 1234, "modtime": "2025-08-30T12:34:56Z", "type": "google", "email": "[email protected]" } ] } - Notes:
modtimeis returned in RFC3339 format; when metadata includes an email it is surfaced.
- Request:
GET
/auth-files/download?name=<file.json>— Download a single file- Request:bash
curl -H 'Authorization: Bearer <MANAGEMENT_KEY>' -OJ 'http://localhost:8317/v0/management/auth-files/download?name=acc1.json'
- Request:
POST
/auth-files— Upload- Request (multipart):bash
curl -X POST -F 'file=@/path/to/acc1.json' \ -H 'Authorization: Bearer <MANAGEMENT_KEY>' \ http://localhost:8317/v0/management/auth-files - Request (raw JSON):bash
curl -X POST -H 'Content-Type: application/json' \ -H 'Authorization: Bearer <MANAGEMENT_KEY>' \ -d @/path/to/acc1.json \ 'http://localhost:8317/v0/management/auth-files?name=acc1.json' - Response:json
{ "status": "ok" } - Notes:
- The core auth manager must be active; otherwise the API returns
503with{ "error": "core auth manager unavailable" }. - Uploaded filenames must end with
.json.
- The core auth manager must be active; otherwise the API returns
- Request (multipart):
DELETE
/auth-files?name=<file.json>— Delete a single file- Request:bash
curl -H 'Authorization: Bearer <MANAGEMENT_KEY>' -X DELETE 'http://localhost:8317/v0/management/auth-files?name=acc1.json' - Response:json
{ "status": "ok" }
- Request:
DELETE
/auth-files?all=true— Delete all.jsonfiles underauth-dir- Request:bash
curl -H 'Authorization: Bearer <MANAGEMENT_KEY>' -X DELETE 'http://localhost:8317/v0/management/auth-files?all=true' - Response:json
{ "status": "ok", "deleted": 3 }
- Request:
Login/OAuth URLs
These endpoints initiate provider login flows and return a URL to open in a browser. Tokens are saved under auths/ once the flow completes.
For Anthropic, Codex, Gemini CLI, and iFlow you can append ?is_webui=true to reuse the embedded callback forwarder when launching from the management UI.
GET
/anthropic-auth-url— Start Anthropic (Claude) login- Request:bash
curl -H 'Authorization: Bearer <MANAGEMENT_KEY>' \ http://localhost:8317/v0/management/anthropic-auth-url - Response:json
{ "status": "ok", "url": "https://...", "state": "anth-1716206400" } - Notes:
- Add
?is_webui=truewhen triggering from the built-in UI to reuse the local callback service.
- Add
- Request:
GET
/codex-auth-url— Start Codex login- Request:bash
curl -H 'Authorization: Bearer <MANAGEMENT_KEY>' \ http://localhost:8317/v0/management/codex-auth-url - Response:json
{ "status": "ok", "url": "https://...", "state": "codex-1716206400" }
- Request:
GET
/gemini-cli-auth-url— Start Google (Gemini CLI) login- Query params:
project_id(optional): Google Cloud project ID.
- Request:bash
curl -H 'Authorization: Bearer <MANAGEMENT_KEY>' \ 'http://localhost:8317/v0/management/gemini-cli-auth-url?project_id=<PROJECT_ID>' - Response:json
{ "status": "ok", "url": "https://...", "state": "gem-1716206400" }
- Query params:
GET
/qwen-auth-url— Start Qwen login (device flow)- Request:bash
curl -H 'Authorization: Bearer <MANAGEMENT_KEY>' \ http://localhost:8317/v0/management/qwen-auth-url - Response:json
{ "status": "ok", "url": "https://...", "state": "gem-1716206400" }
- Request:
GET
/iflow-auth-url— Start iFlow login- Request:bash
curl -H 'Authorization: Bearer <MANAGEMENT_KEY>' \ http://localhost:8317/v0/management/iflow-auth-url - Response:json
{ "status": "ok", "url": "https://...", "state": "ifl-1716206400" }
- Request:
GET
/get-auth-status?state=<state>— Poll OAuth flow status- Request:bash
curl -H 'Authorization: Bearer <MANAGEMENT_KEY>' \ 'http://localhost:8317/v0/management/get-auth-status?state=<STATE_FROM_AUTH_URL>' - Response examples:json
{ "status": "wait" }json{ "status": "ok" }json{ "status": "error", "error": "Authentication failed" }
- Request:
Error Responses
Generic error format:
- 400 Bad Request:
{ "error": "invalid body" } - 401 Unauthorized:
{ "error": "missing management key" }or{ "error": "invalid management key" } - 403 Forbidden:
{ "error": "remote management disabled" } - 404 Not Found:
{ "error": "item not found" }or{ "error": "file not found" } - 422 Unprocessable Entity:
{ "error": "invalid_config", "message": "..." } - 500 Internal Server Error:
{ "error": "failed to save config: ..." } - 503 Service Unavailable:
{ "error": "core auth manager unavailable" }
Notes
- Changes are written back to the YAML config file and hot‑reloaded by the file watcher and clients.
allow-remote-managementandremote-management-keycannot be changed via the API; configure them in the config file.