# Provider Endpoints

Endpoints for provider catalogs, logins, credentials, quota and model lists.

| Method | Path | Description |
|---|---|---|
| `GET` | `/v1/providers` | **local** — list providers and their available auth methods. Each row also carries `logged_in`, true only for the OAuth providers (`codex`, `copilot`, `grok-oauth`) that currently hold a token and for `claude-code` while it is enabled, `hidden` (v1.1.0; true for `claude-code` unless the daemon was started with `agen --enable-claude-code`, which needs a stopped daemon — `agen stop` first), and (since v1.0.22) `console`, the sorted page names that `/v1/provider/:provider/console` serves for it (`key` / `billing` for API-key providers, `plan` for subscriptions, empty for `compat`) |
| `GET` | `/v1/providers/quota` | **local** — remaining quota for `codex`, `grok-oauth`, `copilot`, `claude-code` (since v1.1.0), `openrouter` and `deepseek`, returned under `quota` keyed by provider. `ollama-cloud` was removed from quota tracking; check its usage on ollama.com (Removed in v1.2.0). Since v1.1.3 each entry carries `remaining`, holding only the fields that provider reports: `five_hour`, `week` and `total` (percent left in each window) or `balance` (credit in USD); before v1.1.3 it was a single `kind` (`percent` / `balance`) plus `value`. Fetched in parallel with a 10 s ceiling. Renamed from `/v1/providers/usage` in v0.35.3. Successful reads are cached in ToriiDB for 3 minutes and come back flagged `cached:true`; `?refresh=1` drops the cache and re-reads, and saving a key or finishing an OAuth login drops that provider's entry on its own. Providers without a credential come back with `error` instead of `remaining` and are never cached |
| `POST` | `/v1/provider/:provider/key` | **local** — `{api_key, account_id?, gateway_id?}`. Stores `<PROVIDER>_API_KEY` in the keychain; `account_id` is required for `cloudflare`, and a provider without an API-key method returns 400. `compat` takes `{name, url, api_key?}` instead and adds or updates a custom compatible instance (key stored as `COMPAT_<NAME>_API_KEY`) |
| `GET` | `/v1/provider/:provider/oauth` | **local** — SSE login flow. Only `copilot` is a device-code flow (`{url, user_code}`); `codex` and `grok-oauth` emit `{url}` for a browser login; `claude-code` only checks that the `claude` CLI is installed. The stream ends with `{done, ok, error?}`; a provider without OAuth returns 400. An existing token is left in place while the login runs, so an abandoned or failed re-login no longer logs the provider out |
| `DELETE` | `/v1/provider/:provider/oauth` | **local** — clear a stored provider login (`codex`, `copilot`, `grok-oauth`). The token keys belong to the OAuth libraries, so this goes through their own `ClearToken` rather than `DELETE /v1/key` |
| `GET` | `/v1/provider/:provider/models` | **local** — `{models, windows}`: the text models this provider's own API lists for the stored credential; a custom compatible instance is probed at its `/models` endpoint. 400 when the provider has no model listing, 502 when the fetch fails. Since v1.0.15 the response also carries `windows`, a `{model: {in, out}}` map of context-window sizes for the models the window table knows; a model with no entry is simply absent from the map. Since v1.0.18 the list is cached in ToriiDB for 15 minutes per provider and dropped as soon as that provider's key is set, its OAuth completes, or its login is cleared |
| `GET` | `/v1/provider/:provider/console` | **local** — added in v1.0.22. `302` redirect to the provider's console page; `?page=` is `key`, `billing` or `plan`, defaulting to `plan` for subscription providers and `key` otherwise. 404 when the provider has no such page. The TUI (`o` in `/model add`) and the dashboard's Console / Plans links go through it, so the URLs live in one table (`providerConsole` in `handler/providers.go`) |
