All endpoints below are under the path where agent_gateway_admin is mounted. The Admin API does not implement login or sessions; protect this mount with Caddy basic_auth, mTLS, a reverse proxy authenticator, or the standalone daemon's --admin-basic-auth-hash wrapper.
GET /admin/health
GET /admin/llm/provider_typesGET /admin/llm/api_handler_typesGET /admin/llm/providersPOST /admin/llm/providersGET /admin/llm/providers/{id}PUT /admin/llm/providers/{id}POST /admin/llm/providers/{id}/enablePOST /admin/llm/providers/{id}/disableDELETE /admin/llm/providers/{id}
Create a provider:
curl -u admin:your-password -X POST http://localhost:8019/admin/llm/providers \
-H 'Content-Type: application/json' \
-d '{
"id": "openrouter-main",
"provider_type": "openrouter",
"api_key": "sk-or-...",
"base_url": "https://openrouter.ai/api/v1",
"default_model": "openai/gpt-4o-mini",
"network": {
"request_timeout_seconds": 120,
"max_retries": 3,
"max_idle_connections": 100,
"max_idle_connections_per_host": 20,
"idle_keep_alive_timeout_seconds": 90
}
}'Provider notes:
idandprovider_typeare requiredcreated_atandupdated_atare server-managed fields
GET /admin/llm/routesPOST /admin/llm/routesGET /admin/llm/routes/{id}PUT /admin/llm/routes/{id}POST /admin/llm/routes/{id}/enablePOST /admin/llm/routes/{id}/disableDELETE /admin/llm/routes/{id}
Create a route:
curl -u admin:your-password -X POST http://localhost:8019/admin/llm/routes \
-H 'Content-Type: application/json' \
-d '{
"id": "chat-prod",
"protocol": "openai",
"match": {
"path_prefix": "/",
"methods": ["POST"]
},
"target_policy": {
"provider_target": {
"provider_id": "openrouter-main"
}
},
"auth_policy": {
"require_virtual_key": true
}
}'Route notes:
protocolandtarget_policyare requiredcreated_atandupdated_atare server-managed fields- when
target_policy.provider_target.provider_idis present, the route runs in direct-provider mode - logical-model routes using
target_policy.model_targetsremain supported through dynamic route management and bundle workflows, but not in Caddyfile routes oragwd --static-config
GET /admin/virtual_keysPOST /admin/virtual_keysGET /admin/virtual_keys/{id}PUT /admin/virtual_keys/{id}POST /admin/virtual_keys/{id}/enablePOST /admin/virtual_keys/{id}/disableDELETE /admin/virtual_keys/{id}
Create a VirtualKey:
curl -X POST http://localhost:8019/admin/virtual_keys \
-H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
-d '{
"id": "demo-key",
"tag": "demo-user",
"allowed_route_ids": ["chat-prod"]
}'Example response:
{
"id": "demo-key",
"key": "vk-...",
"tag": "demo-user",
"allowed_route_ids": ["chat-prod"],
"created_at": "2026-05-13T03:00:00Z",
"updated_at": "2026-05-13T03:00:00Z",
"source": "store",
"read_only": false
}VirtualKey notes:
idis the stable management identifierkeyis the bearer credential value clients must send on requestscreated_atandupdated_atare server-managed fields
GET /admin/credentialsPOST /admin/credentialsGET /admin/credentials/{credential_id}PUT /admin/credentials/{credential_id}DELETE /admin/credentials/{credential_id}
Create an API-key credential:
curl -X POST http://localhost:8019/admin/credentials \
-H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
-d '{
"provider_id": "openai-main",
"label": "primary",
"attributes": {
"api_key": "sk-...",
"base_url": "https://api.openai.com/v1",
"priority": "10"
}
}'Credential notes:
created_atandupdated_atare server-managed response fields- do not send them in
POSTorPUTbodies
GET /admin/llm/models/providers/{provider_id}/discoveredPOST /admin/llm/models/providers/{provider_id}/refreshGET /admin/llm/models/managedPUT /admin/llm/models/managed/{provider_id}/{upstream_model}
GET /admin/cliauth/authenticatorsGET /admin/cliauth/authenticators/{authenticator_name}PUT /admin/cliauth/authenticators/{authenticator_name}POST /admin/cliauth/authenticators/{authenticator_name}/loginGET /admin/cliauth/logins/{login_id}
CLI auth behavior:
- login runs asynchronously and returns
202 Accepted - poll the login status endpoint for completion
- the login request body must include
provider_id - authenticator config set through the admin API is runtime-only
- disabling an authenticator or restarting the server resets it to factory defaults
Examples:
curl -X PUT http://localhost:8019/admin/cliauth/authenticators/codex \ -H 'Content-Type: application/json' \
--data '{"enabled":true,"config":{}}'curl -X PUT http://localhost:8019/admin/cliauth/authenticators/codex \ -H 'Content-Type: application/json' \
--data '{"enabled":true,"config":{"callback_port":9002,"no_browser":true,"device_flow":true}}'curl -X POST http://localhost:8019/admin/cliauth/authenticators/codex/login \ -H 'Content-Type: application/json' \
--data '{"provider_id":"openai-main","scope":"type:openai"}'Implemented MCP admin families include:
- MCP services
- MCP routes
- MCP discovery and execution endpoints
- MCP dispatcher runtime inspection endpoints
Implemented ACP admin families include:
GET /admin/acp/servicesPOST /admin/acp/servicesGET /admin/acp/services/{id}PUT /admin/acp/services/{id}DELETE /admin/acp/services/{id}GET /admin/acp/services/{id}/sessionsGET /admin/acp/services/{id}/sessions/{session_id}/transcriptGET /admin/acp/routesPOST /admin/acp/routesGET /admin/acp/routes/{id}PUT /admin/acp/routes/{id}DELETE /admin/acp/routes/{id}GET /admin/acp/runtimeGET /admin/acp/runtime/inflightDELETE /admin/acp/runtime/threads/{service_id}/{thread_id}POST /admin/acp/runtime/permissions/{request_id}
The dispatcher also exposes consumer-facing route-scoped ACP session endpoints
under /<acp-route>/sessions and
/<acp-route>/sessions/{session_id}/transcript; those are not Admin API
families because they resolve the service from the matched route and use the
route's VirtualKey policy.
See acp-api.md for request and response shapes.
GET /admin/metricsGET /admin/metrics/prometheusGET /admin/metrics/llm/eventsGET /admin/metrics/llm/timeseriesGET /admin/metrics/llm/breakdownGET /admin/metrics/mcp/eventsGET /admin/metrics/mcp/timeseriesGET /admin/metrics/mcp/breakdownGET /admin/metrics/mcp/tools/summaryGET /admin/metrics/acp/eventsGET /admin/metrics/acp/timeseriesGET /admin/metrics/acp/breakdownGET /admin/metrics/acp/summaryGET /admin/metrics/interactionsGET /admin/metrics/interactions/summary
Metrics are backed by SQLite usage event tables when the sqlite config store
backend is active. GET /admin/metrics returns per-kind summaries plus a
pipeline object with dropped_events and write_failures counters.
GET /admin/metrics/prometheus renders an O(1) in-process counter snapshot in
Prometheus text exposition format (request/failure/token totals by kind plus the
pipeline health counters); point an external Prometheus scrape at it (behind the
admin auth boundary) for trends, aggregation, and alerting. Event listing
endpoints support from, to, limit, success, and family-specific filters
such as route, provider/service, model, method, tool, operation, thread,
session, and trace identifiers. Aggregate endpoints support from, to,
limit, group_by, and endpoint-specific filters. The LLM, MCP, and ACP
timeseries and breakdown endpoints share the same shape; each accepts its
protocol's group_by dimensions and filter keys (LLM:
route_id/provider_id/virtual_key_id/upstream_model/llm_api; MCP:
route_id/service_id/virtual_key_id/method/tool_name/result_status;
ACP: route_id/route_protocol/service_id/virtual_key_id/agent_type/operation).
The ACP route_protocol filter separates data-plane turns (route_protocol=acp)
from the admin-plane audit spans the manager records when polling /admin/acp
(route_protocol=admin).
Timeseries supports bucket=minute|hour|day (plural and short forms such as
minutes/min/m are also accepted, as are Grafana-style durations such as
3h/5m/30s/1d; empty defaults to hour). mcp/tools/summary and
acp/summary remain as fixed-grouping convenience views. Usage-event retention is configured through the Caddyfile
metrics block or the agwd --metrics-retention-days flag and is enforced at
startup and by a periodic background janitor.
GET /admin/agentsPOST /admin/agentsGET /admin/agents/{id}PUT /admin/agents/{id}DELETE /admin/agents/{id}GET /admin/agents/{id}/workspaceGET /admin/agents/{id}/activityGET /admin/agents/{id}/usageGET /admin/agents/{id}/interactionsGET /admin/agents/{id}/resourcesPUT /admin/agents/{id}/resourcesGET /admin/agents/{id}/health
Agents are first-class management objects that bind an operator-facing identity
to one runtime backend, currently an ACP service for managed local agents.
P0/P1 agents are management-plane groupings: data-plane requests still
authenticate through VirtualKeys and route policy. Agent usage and activity
views prefer durable agent_id attribution and fall back to the agent's owned
routes and ACP runtime service for older or untagged events.
These families still contain 501 Not Implemented endpoints:
- memory
The gateway admin handler does not expose Caddy server management endpoints.
- if you need
/admin/caddy/*operations for a Caddy-managed deployment, run the standalonecaddymgrservice and point the Web UI at that service agwctl caddy ...talks to the Caddy admin API directly and does not use the gateway Admin API route table