Use the API
Manage providers, apps, users and usage from scripts and CI with a management key.
The console uses the API to manage your apps and providers. Some account and access actions require a human console session; management credentials cannot perform those actions. For a terminal or coding agent, start with the CLI, which handles protected state, browser handoffs and creation retries. Direct integrations can use the same API from a deployment script or CI job.
Use https://api.appaigateway.com as the API origin and
console.appaigateway.com to manage access.
Self-hosting
Use your gateway's API origin. If your console and API share an address, use that address. Routes and request bodies are the same.
Management keys
A management key authenticates API calls to the /v1/admin/* routes. Open
the user menu in the console, choose Access, and click New
key. The key is shown once in a dialog titled Copy your new key now. The
same page lists the MCP clients connected with OAuth, whose access tokens the
/v1/admin/* routes accept too; see MCP server.
A management key acts within its owning identity's current account membership and role. It does not expire. Store it in a secret manager and read it from the environment. Revoke key stops it immediately.
Each key also has a grant, chosen when you create it. Manage, the default,
lets the key do everything its owner's role allows. Read only lets it list,
inspect and validate your apps, providers and usage, but not change them. A
change the owner's role would otherwise allow is refused with
403 grant_insufficient; one the role or the kind of credential rules out is
refused for that reason instead. A read-only key can still revoke itself
(DELETE /v1/cli/credential). Give one to a dashboard or an agent that only
needs to look.
Keys are listed and revoked on that page, and created there or by a CLI login
you approve in the browser (agw account login). A key the CLI received is
listed with a CLI tag and the label the CLI sent, such as CLI on mac-studio. A management key cannot create or list keys, and the only key it
can revoke is itself (DELETE /v1/cli/credential, which is what
agw account logout sends). So a key you hand to another system cannot issue
itself a second key, and revoking the one you handed out ends that access for
good.
The console's Access page calls Create a management key, List management keys and Revoke a management key. They accept a console session only.
Management keys manage; they never call providers. An app's own API key is what calls providers, and a management key is refused on those routes.
Making a call
Send the management credential as an Authorization: Bearer header from your
HTTP client's protected credential store. Do not put it in shell arguments or
logs. The CLI reads it from the AGW_MANAGEMENT_KEY environment variable,
which takes precedence over any saved login without saving that environment
key to disk. A CI job can supply it from its secret store:
AGW_MANAGEMENT_KEY="$MANAGEMENT_KEY" agw app list --jsonTo save the key on a machine instead, pipe it once through stdin:
agw deployment connect --url https://api.appaigateway.com --key-stdin < /private/path/management-key
agw app list --jsonThe full reference with every request and response shape is under API reference, and the OpenAPI document is at /openapi.json.
What you can do
| Area | Routes |
|---|---|
| Providers | GET, POST /v1/admin/providers, POST /v1/admin/providers/test, PUT, DELETE /v1/admin/providers/{id} |
| Gateways | GET, POST /v1/admin/provider-gateways, POST …/test, PATCH, DELETE …/{id}, POST …/{id}/rotate |
| Apps | GET, POST /v1/admin/apps, GET, PUT, DELETE /v1/admin/apps/{app}, POST …/validate, POST /v1/admin/app-drafts/validate |
| App checks | GET /v1/admin/apps/{app}/check, GET …/snippet (no inference) |
| App keys | GET, POST /v1/admin/apps/{app}/keys, POST …/keys/{key}/revoke |
| Users | GET /v1/admin/apps/{app}/users, GET …/users/{user}, POST …/block, POST …/unblock |
| Usage | GET /v1/admin/apps/{app}/usage, …/usage/timeseries, …/usage/breakdown, …/events, POST …/usage/reprice |
| Auth events | GET /v1/admin/apps/{app}/auth-events, …/auth-events/summary, …/rejection-events |
| Prices | GET /v1/admin/prices |
Account status and totals are also available through GET /v1/cli/account
and GET /v1/cli/usage?month=YYYY-MM. The latter retains usage from deleted apps.
Validate before you write
POST /v1/admin/apps/{app}/validate checks an application body without
saving it and returns the same errors an update of that app would. Run it
before PUT in any automated flow, so a bad configuration is caught before it
replaces a good one. For an app you have not created yet, use
POST /v1/admin/app-drafts/validate, which returns the errors a creation
would.
Rules worth knowing
- Never send
idwhen creating an app. The gateway assigns it and returns it asapp.id. A body withidis refused with400. PUT /v1/admin/apps/{app}replaces the whole app: sendname, the fullconfig,status, and therevisionfrom your latest read. Omittedstatusdefaults toactive, so preserve it to avoid enabling a paused app.- App deletion requires
DELETE /v1/admin/apps/{app}?confirm={app}, repeating the app ID in the query. - An app's API key is returned once, as
api_key.keyon create orkeyonPOST …/keys. Ordinary reads never return it; retry-safe operations have the limited recovery window described below. - A provider key is never returned. Responses carry only
secretHint, the last characters. - App and provider changes take up to a minute to affect live traffic. Management credential revocation is immediate; user blocks stop new token exchanges immediately and existing gateway tokens within ten seconds.
Example: create a server app and its first key
Send this JSON body to POST https://api.appaigateway.com/v1/admin/apps
from your authenticated HTTP client, with Content-Type: application/json.
First add a provider with slug openai and validate the same body at
POST /v1/admin/app-drafts/validate.
{
"name": "Search service",
"config": {
"authentication": { "type": "api_key", "end_user": { "source": "none" } },
"routing": {
"providers": {
"mode": "selected",
"selected": { "openai": { "allowed_paths": ["v1/responses"], "allowed_models": ["gpt-5.6-sol"] } }
},
"model_rewrites": {}
},
"limits": {
"per_user": { "requests": { "per_minute": null, "per_day": null }, "spending": { "monthly_usd": null } },
"per_app": { "requests": { "per_minute": 300, "per_day": 10000 }, "spending": { "monthly_usd": 100 } }
}
}
}The response carries app.id, which clients compile into their URLs, and
api_key.key, which goes straight into the calling service's secret manager.
Handle the response privately: do not print it to a terminal or CI log. For a
retryable script, submit the body as an operation as described below. The CLI
handles both retry proofs and private key storage automatically.
Revisions and retry proofs
Read an app, provider or provider gateway before updating it and send back the
revision it answered with. Apps require it on full PUT; providers require it
on PUT; gateways require it when renaming or rotating a token. A missing
revision returns 400 and a stale one 409; reread and merge before retrying. The
revision travels only in the body — no ETag is published, because anything
that compresses a response rewrites that header and a browser cannot read it
cross-origin.
To make the creation of an app, app key, provider or provider gateway safe to
retry, send it to POST /v1/cli/operations with a random token you persist
before sending. Retrying with the same token and payload recovers the existing
resource instead of creating another. A new key is returned for 15 minutes;
after that the result identifies the resource and never creates another key
automatically.