Management API v8
Базовый путь: http://localhost:8317/v8/management
Это API конфигурации и операций для макета v8. Пути конфигурации повторяют дерево YAML v8, описанное в опциях конфигурации. Успешная запись конфигурации сохраняет файл, и сервис применяет его через hot reload.
/v0/management остается доступным для существующих клиентов, но близок к устареванию. Не создавайте новую функциональность на основе этого API.
Аутентификация
- Каждый запрос, кроме callback OAuth, должен содержать действительный ключ управления, включая запросы с localhost.
- Удаленный доступ требует
management.allow-remote: true. Пока запись v8 не мигрировала файл, старое имяremote-management.allow-remoteпродолжает работать. - Отправьте открытый ключ одним из заголовков:
Authorization: Bearer <plaintext-key>X-Management-Key: <plaintext-key>
Дополнительно:
MANAGEMENT_PASSWORDрегистрирует дополнительный секрет управления только в памяти и сохраняет удаленное управление включенным, даже еслиallow-remoteравен false. Значение никогда не записывается на диск.cliproxy run --password <pwd>и SDKWithLocalManagementPasswordпринимают этот пароль только с localhost (127.0.0.1или::1). Он остается в памяти.- Маршруты возвращают 404, когда
management.secret-keyпуст,MANAGEMENT_PASSWORDне задан и локальный пароль управления не был настроен. Тот же 404 применяется к/v0/management. - Режим Home не предоставляет этот API и также возвращает 404.
- Пять последовательных ошибок аутентификации с одного IP клиента, включая localhost, создают временную блокировку примерно на 30 минут.
- Открытый
management.secret-keyхешируется bcrypt при загрузке или сохранении конфигурации.
Соглашения запросов и ответов
- Аутентифицированные тела конфигурации и операций используют
Content-Type: application/json, если endpoint не указывает иное. - Тело конфигурации v8 является самим значением. Не оборачивайте его в
{ "value": ... },{ "items": ... }или старое имя поля. GET /configиGET /config/<path>возвращают узел YAML как JSON. Отсутствующий путь возвращает404с{ "error": "not_found" }.PUTзаменяет выбранный узел.PATCHглубоко объединяет объекты и заменяет любой другой вид.nullсохраняется и не удаляет поле. Для удаления поля используйтеDELETE.- Сегменты пути являются ключами отображения YAML. Это не индексы массива. Списки заменяются целиком.
- Успешное изменение конфигурации возвращает
{ "status": "ok", "config-version": 8 }и выполняет hot reload сохраненного файла. GETвозвращает представление v8, но не переписывает файл. Первый успешныйPUT,PATCHилиDELETEмигрирует старый файл вconfig-version: 8, удаляет старые написания и сохраняет комментарии. Отклоненная запись файл не мигрирует.- Записи v8 отклоняют старые имена полей и неизвестные корневые разделы. Карта старых полей находится в опциях конфигурации.
Эти поля принадлежат Home. Их изменение возвращает 400 с { "error": "read_only_field", "field": "<path>" }:
credentials/concurrency/lifecycle-config-revisioncredentials/concurrency/observation-barrier-revisionplugins/auth-revision
Конфигурация
Имена полей, значения по умолчанию и правила провайдеров определены в опциях конфигурации. Примеры ниже показывают только транспорт.
Чтение конфигурации
GET /config— полный документ v8.GET /config/<section>/<key>/...— один вложенный узел.GET /config.yaml— то же представление v8 в YAML.
curl -H 'Authorization: Bearer <MANAGEMENT_KEY>' \
http://localhost:8317/v8/management/configcurl -H 'Authorization: Bearer <MANAGEMENT_KEY>' \
http://localhost:8317/v8/management/config/routing/strategy"round-robin"curl -H 'Authorization: Bearer <MANAGEMENT_KEY>' \
-H 'Accept: application/yaml' \
http://localhost:8317/v8/management/config.yamlПримечания:
- Ответы отправляют
Cache-Control: no-store. - YAML использует
Content-Type: application/yaml; charset=utf-8. - Чтение JSON опускает
usernameиcredentialвoauth.providers.codex.live-media-relay.ice-servers. Чтение YAML по-прежнему их содержит. - Если пригодную конфигурацию прочитать нельзя, обработчик возвращает
500с{ "error": "read_failed" }или{ "error": "invalid_config" }.
Замена или объединение конфигурации
PUT /configзаменяет весь документ. Тело должно быть объектом JSON.PATCH /configглубоко объединяет объект JSON с документом.PUT /config/<path>заменяет этот узел. Тело является исходным значением JSON: объект, массив, строка, число, логическое значение илиnull.PATCH /config/<path>объединяет, когда и текущий узел, и тело являются объектами; иначе заменяет узел.PUT /config.yamlзаменяет файл документом YAML v8.Content-Typeможет бытьapplication/yaml. Для/config.yamlнетPATCH.
curl -X PATCH -H 'Authorization: Bearer <MANAGEMENT_KEY>' \
-H 'Content-Type: application/json' \
-d '{"routing":{"retry":{"request-retry":0}},"oauth":{"providers":{"aistudio":{"ws-auth":false}}}}' \
http://localhost:8317/v8/management/configcurl -X PUT -H 'Authorization: Bearer <MANAGEMENT_KEY>' \
-H 'Content-Type: application/json' \
-d '"direct"' \
http://localhost:8317/v8/management/config/requests/proxy-urlcurl -X PUT -H 'Authorization: Bearer <MANAGEMENT_KEY>' \
-H 'Content-Type: application/json' \
-d '["client-key-1","client-key-2"]' \
http://localhost:8317/v8/management/config/access/api-keyscurl -X PATCH -H 'Authorization: Bearer <MANAGEMENT_KEY>' \
-H 'Content-Type: application/json' \
-d '{"enabled":true,"priority":10}' \
http://localhost:8317/v8/management/config/plugins/configs/example-plugincurl -X PUT -H 'Authorization: Bearer <MANAGEMENT_KEY>' \
-H 'Content-Type: application/yaml' \
--data-binary @config.yaml \
http://localhost:8317/v8/management/config.yamlОтвет:
{ "status": "ok", "config-version": 8 }API-ключи upstream являются списками групп. Заменяйте список провайдера; путь не может выбрать api-keys/codex/0.
curl -X PUT -H 'Authorization: Bearer <MANAGEMENT_KEY>' \
-H 'Content-Type: application/json' \
-d '[{"name":"codex-1","base-url":"https://example.invalid","keys":[{"api-key":"sk-example","weight":1}]}]' \
http://localhost:8317/v8/management/config/api-keys/codexПримечания:
- Старая оболочка, например
{ "value": 0 }, не является значением v8, и проверка завершается ошибкой. - Неизвестные разделы, старые имена и значения, не прошедшие разбор конфигурации, отклоняются. Прежний файл остается на месте.
- Повторная запись отредактированного списка ICE-серверов JSON сохраняет TURN
usernameиcredentialдля записи с теми жеurls. Явная пустая строка илиnullочищает секрет. Замена YAML не сохраняет пропущенные секреты. - Запись обновляет существующий файл конфигурации на месте, поэтому файловое монтирование Docker сохраняет тот же inode.
- Изменение
management.secret-keyилиmanagement.allow-remoteвозможно. Пустой секрет без запасного пароля заставляет последующие вызовы управления возвращать 404.
Удаление поля конфигурации
DELETE /config/<path>удаляет поле и убирает ставших пустыми предков-отображений.DELETE /configотклоняется.
curl -X DELETE -H 'Authorization: Bearer <MANAGEMENT_KEY>' \
http://localhost:8317/v8/management/config/requests/proxy-urlСервер
Последняя версия
GET /server/latest-version— последний тег релиза GitHub. Ресурсы релиза не загружаются.
curl -H 'Authorization: Bearer <MANAGEMENT_KEY>' \
http://localhost:8317/v8/management/server/latest-version{ "latest-version": "v1.2.3" }Запрос использует https://api.github.com/repos/router-for-me/CLIProxyAPI/releases/latest с User-Agent: CLIProxyAPI. Настроенный requests.proxy-url учитывается.
Запросы
Аутентифицированный вызов upstream
POST /requests/api-call— отправить один исходящий HTTP-запрос, при необходимости с сохраненными учетными данными.
curl -X POST -H 'Authorization: Bearer <MANAGEMENT_KEY>' \
-H 'Content-Type: application/json' \
-d '{"auth_index":"a1b2","method":"GET","url":"https://api.example.com/v1/ping","header":{"Authorization":"Bearer $TOKEN$"}}' \
http://localhost:8317/v8/management/requests/api-call{ "status_code": 200, "header": { "Content-Type": ["application/json"] }, "body": "{\"ok\":true}" }Примечания:
- Обязательны
methodи абсолютныйurl. Необязательны строковое отображениеheader, исходная строкаdataиproxy_url. auth_indexтакже принимается какauthIndexилиAuthIndex.$TOKEN$в заголовке заменяется access token или API-ключом выбранных учетных данных.- Прокси учетных данных имеет приоритет над
proxy_urlзапроса и глобальным прокси. Ответ сохраняет статус upstream вstatus_code. - Так можно вызвать произвольные URL с сохраненными учетными данными. Защитите ключ управления.
Маршрутизация
Сброс cooldown
POST /routing/cooldown/reset— очистить состояние квоты и cooldown для одних учетных данных.
curl -X POST -H 'Authorization: Bearer <MANAGEMENT_KEY>' \
-H 'Content-Type: application/json' \
-d '{"auth_index":"a1b2"}' \
http://localhost:8317/v8/management/routing/cooldown/reset{ "status": "ok", "auth_index": "a1b2", "models": ["gpt-5.4"] }Неизвестный auth_index возвращает 404 с { "error": "auth not found" }.
Статические определения моделей
GET /routing/model-definitions/:channel— статические метаданные каталога одного канала.
curl -H 'Authorization: Bearer <MANAGEMENT_KEY>' \
http://localhost:8317/v8/management/routing/model-definitions/codexОтвет имеет вид { "channel": "codex", "models": [ ... ] }.
Неизвестный канал возвращает 400 с { "error": "unknown channel", "channel": "..." }.
Наблюдаемость
Логи приложения
GET /observability/logs— прочитать строки журнала.DELETE /observability/logs— удалить ротированные журналы и обрезать активный журнал.
Параметры запроса для GET:
after: метка Unix. Возвращаются только более новые строки.limit: максимум строк. Приlimitбезafterвозвращаются новейшие строки.cursor: непрозрачный курсор из предыдущегоnext-cursor.
curl -H 'Authorization: Bearer <MANAGEMENT_KEY>' \
'http://localhost:8317/v8/management/observability/logs?limit=2'{
"lines": ["2026-05-05 12:00:00 info request accepted"],
"line-count": 1,
"latest-timestamp": 1777982400,
"next-cursor": "<OPAQUE_CURSOR>"
}Примечания:
- Запись журнала в файл должна быть включена через
observability.logs.logging-to-file. Иначе ответ —400с{ "error": "logging to file disabled" }. - Отсутствующий файл журнала возвращает пустые
linesиline-count: 0. - Верните
next-cursorкакcursor. При сбросе ответ содержит"cursor-reset": true. DELETEвозвращает{ "success": true, "message": "Logs cleared successfully", "removed": 3 }.
Журналы ошибок запросов
GET /observability/logs/errors— список файловerror-*.log.GET /observability/logs/errors/:name— загрузить один журнал ошибок.GET /observability/logs/requests/:id— загрузить журнал запроса, имя файла которого заканчивается на-<id>.log.
curl -H 'Authorization: Bearer <MANAGEMENT_KEY>' \
http://localhost:8317/v8/management/observability/logs/errors{ "files": [{ "name": "error-2026-05-05.log", "size": 12345, "modified": 1777982400 }] }Примечания:
- Когда логирование запросов включено, список журналов ошибок пуст.
:nameдолжен быть существующим именемerror-*.logбез разделителей пути.:idне должен содержать разделители пути.
Использование
GET /observability/usage/queue?count=10— извлечь доcountзаписей использования.countпо умолчанию равен1и должен быть положительным целым. Записи удаляются из очереди в памяти. Пустая очередь возвращает[].GET /observability/usage/api-keys— корзины успехов и ошибок в памяти для учетных данных API-ключа, сгруппированные по провайдеру и адресуемые ключомbase_url|api_key.
curl -H 'Authorization: Bearer <MANAGEMENT_KEY>' \
'http://localhost:8317/v8/management/observability/usage/queue?count=10'Локальный вывод использования Redis RESP отключен. Перед ожиданием записей включите observability.usage.usage-statistics-enabled.
Учетные данные
Эти маршруты управляют файлами и состоянием среды выполнения в oauth.auth-dir. Они не изменяют группы api-keys; для них используйте маршруты конфигурации.
Список, загрузка и удаление
GET /credentials— список файлов учетных данных и записей среды выполнения.POST /credentials— загрузить одни учетные данные.jsonполем multipartfileили исходным телом JSON с?name=<file.json>.DELETE /credentials?name=<file.json>— удалить одни учетные данные на диске и отключить их в среде выполнения.DELETE /credentials?all=true— удалить все учетные данные.jsonна диске. Ответ:{ "status": "ok", "deleted": 3 }.GET /credentials/download?name=<file.json>— загрузить одни учетные данные с диска.GET /credentials/models?name=<file-or-id>— определения моделей одних учетных данных:{ "models": [ ... ] }.
curl -H 'Authorization: Bearer <MANAGEMENT_KEY>' \
http://localhost:8317/v8/management/credentials{
"files": [
{
"id": "[email protected]",
"auth_index": "a1b2c3d4e5f67890",
"name": "[email protected]",
"provider": "claude",
"status": "ready",
"disabled": false,
"unavailable": false,
"runtime_only": false,
"source": "file"
}
]
}Примечания:
- Записи сортируются по
name.runtime_only: trueозначает, что учетные данные существуют только в памяти; такие записи нельзя загрузить или удалить здесь. - Для загрузки требуется основной auth manager. Если он недоступен, ответ —
503с{ "error": "core auth manager unavailable" }. - Имена загружаемых файлов должны заканчиваться на
.json. Успешная загрузка регистрируется немедленно и возвращает{ "status": "ok" }.
Статус, поля и обновление
PATCH /credentials/status—{ "name": "<file-or-id>", "disabled": true }. Записи API-ключа отключаются через конфигурацию исключенных моделей. Виртуальный дочерний элемент плагина нельзя изменить отдельно.PATCH /credentials/fields—{ "name": "<file-or-id>", ...fields }. Точечные пути обновляют вложенные метаданные, напримерheaders.X-Team. Объектheadersобъединяется с существующими заголовками; пустое значение удаляет заголовок.POST /credentials/refresh— обновить файловые учетные данные OAuth.
curl -X PATCH -H 'Authorization: Bearer <MANAGEMENT_KEY>' \
-H 'Content-Type: application/json' \
-d '{"name":"codex-user.json","disabled":true}' \
http://localhost:8317/v8/management/credentials/statusOAuth
Начало входа
GET /oauth/auth-url?provider=<provider>— начать вход провайдера и вернуть URL браузера.
Провайдеры: claude, codex, antigravity, kimi, kimi-ai, xai, devin, meta и провайдер OAuth, зарегистрированный плагином.
curl -H 'Authorization: Bearer <MANAGEMENT_KEY>' \
'http://localhost:8317/v8/management/oauth/auth-url?provider=claude&is_webui=true'{ "status": "ok", "url": "https://...", "state": "anth-1716206400" }Примечания:
- Отсутствие
providerвозвращает400с{ "error": "provider is required" }. Неизвестный провайдер возвращает404с{ "error": "provider_not_found" }, если плагин его не обрабатывает. is_webui=trueповторно использует переадресатор callback интерфейса управления для поддерживающих его провайдеров.- Провайдеры кода устройства также могут вернуть
flow,user_codeиexpires_in.
Опрос и отмена
GET /oauth/status?state=<state>—waitво время ожидания,okпосле успеха илиerrorсо строкойerror. Завершенные состояния ненадолго сохраняются, чтобы клиент мог увидетьok.DELETE /oauth/session?state=<state>— отменить ожидающий сеанс. Ответ:{ "status": "ok", "cancelled": true }. Отмененный процесс не сохраняет учетные данные.
Импорт
POST /oauth/import?provider=vertex— импортировать JSON-файл сервисного аккаунта Google. Поддерживаемый провайдер —vertex.
curl -X POST -H 'Authorization: Bearer <MANAGEMENT_KEY>' \
-F 'file=@/path/to/service-account.json' \
-F 'location=us-central1' \
'http://localhost:8317/v8/management/oauth/import?provider=vertex'{
"status": "ok",
"auth-file": "/abs/path/auths/vertex-my-project.json",
"project_id": "my-project",
"email": "[email protected]",
"location": "us-central1"
}Загрузка выполняется как multipart/form-data в поле file. location необязателен и по умолчанию равен us-central1.
Callback
GET /oauth/callback и POST /oauth/callback находятся вне middleware ключа управления. Они принимают callback только для ожидающего состояния, провайдер которого совпадает с сеансом.
GETчитаетprovider,state,code, а такжеerrorилиerror_description.POSTпринимает{ "provider", "redirect_url", "code", "state", "error" }.redirect_urlможет содержать query callback.
curl 'http://localhost:8317/v8/management/oauth/callback?provider=codex&state=codex-...&code=AUTHORIZATION_CODE'{ "status": "ok" }Плагины
Включение плагина и принадлежащие ему параметры являются конфигурацией, а не отдельными маршрутами:
GET /config/pluginsчитает раздел плагинов.PUTилиPATCH /config/plugins/configs/<plugin-id>заменяет или объединяет один объект плагина.PUT /config/plugins/configs/<plugin-id>/enabledсtrueилиfalseменяет только этот флаг. Это не меняетplugins.enabled.
Обнаружение и магазин
GET /plugins— обнаруженные, настроенные и зарегистрированные плагины, включаяplugins_enabled,plugins_dir, а также id, путь, состояние включения, метаданные, поля конфигурации и меню каждого плагина.DELETE /plugins/:id— удалить локальный файл плагина и его сохраненную конфигурацию. Плагин, который нельзя выгрузить, возвращает409и может установитьrestart_required: true.GET /plugins/store— каталог магазина, ошибки источников, состояние установки и доступность обновления.POST /plugins/store/:id/install— загрузить или обновить один плагин и включить его. Используйте?source=<source-id>при совпадении ID.versionможет быть параметром запроса или{ "version": "1.2.3" }.
curl -X POST -H 'Authorization: Bearer <MANAGEMENT_KEY>' \
-H 'Content-Type: application/json' \
-d '{"version":"1.2.3"}' \
'http://localhost:8317/v8/management/plugins/store/example-plugin/install?source=official'{
"status": "installed",
"source_id": "official",
"id": "example-plugin",
"version": "1.2.3",
"path": "/abs/path/plugins/example-plugin.so",
"restart_required": false
}Установка из магазина может загружать исполняемые артефакты. Доверяйте источникам магазина перед их включением.
Квота плагина
GET /plugins/:id/quota?auth_index=<auth-index>POST /plugins/:id/quotaс{ "auth_index": "<auth-index>" }DELETE /plugins/:id/quota?auth_index=<auth-index>
authIndex принимается как псевдоним. Отсутствующий провайдер квоты возвращает 404. Ошибки провайдера возвращают 502. v8 не регистрирует устаревший псевдоним /quota/reset.
Ответы об ошибках
Обработчики конфигурации и операций используют собственные строки ошибок. Распространенные результаты:
400:{ "error": "invalid_json" },{ "error": "invalid_body" },{ "error": "invalid_path" },{ "error": "config_must_be_object" },{ "error": "cannot_delete_config" }или{ "error": "invalid_config", "message": "..." }400:{ "error": "read_only_field", "field": "plugins/auth-revision" }401:{ "error": "missing management key" }или{ "error": "invalid management key" }403:{ "error": "remote management disabled" }404:{ "error": "not_found" },{ "error": "provider_not_found" }или{ "error": "auth not found" }409: плагин нельзя выгрузить или требуется перезапуск422:{ "error": "invalid_config", "message": "..." }, когда документ разбирается, но не проходит проверку конфигурации500:{ "error": "write_failed", "message": "..." }или{ "error": "read_failed" }502: ошибка провайдера квоты503:{ "error": "core auth manager unavailable" }
Пустой секрет управления без запасного пароля возвращает 404 до выполнения этих обработчиков.
Примечания
- Новые клиенты должны отправлять только пути v8. После миграции файла устаревшее обновление
/v0/managementвсе еще изменяет действующее значение, но это не контракт для новой разработки. - У
quota-exceeded.switch-projectиquota-exceeded.switch-preview-modelнет имен v8. Не добавляйте функции, которые от них зависят. - Параметры провайдера OAuth в
oauth.providersне применяются к группамapi-keys. Храните эти учетные данные в полях группы и ключа, описанных для API-ключей upstream.