is_valid: false; hard failures (provider rejects the credential) reject the request without storing anything.
Model-string format
A stored key is selected by the provider prefix of themodel string you pass to an agent, indexing job, or other consumer. Powabase routes models through LiteLLM, so these are LiteLLM model IDs.
| Provider | Format | Example |
|---|---|---|
openai | bare ID | gpt-4o |
anthropic | bare ID | claude-sonnet-4-6 |
google | gemini/<model> | gemini/gemini-2.5-pro |
openrouter | openrouter/<org>/<model> | openrouter/qwen/qwen3-235b-a22b-2507 |
openrouter/... cost-map keys, which can differ from OpenRouter’s own slugs. For a full walkthrough, including DeepSeek and the function-calling requirement for agents, see Bring your own LLM.
Common Patterns
Configure keys once after creating a project, then let agents and indexing jobs pick them up automatically. Use the batch PUT endpoint when wiring keys from a setup script. Use the/validate endpoint to test a key before storing it (e.g. in an admin UI).
GET /api/ai-provider-keys
List all configured provider keys. Each entry includesid, provider, masked_key (the only representation of the secret the API ever returns), is_valid, last_validated_at, created_at, and updated_at.
POST /api/ai-provider-keys
Upsert a single provider key. Returns 201 on insert, 200 on update.One of:
openai, anthropic, google, openrouter.The provider’s raw API key. Validated against the provider before storage.
PUT /api/ai-provider-keys
Batch upsert. Pass any subset of providers. Null or empty values are no-ops (won’t clear existing keys; use DELETE for that). On any hard-fail validation, the entire batch is rolled back.DELETE /api/ai-provider-keys/
Remove a stored key. Returns 204 with no body.One of:
openai, anthropic, google, openrouter.POST /api/ai-provider-keys/validate
Validate a key against the provider without storing it. Returns{ "is_valid": true } on success, or { "is_valid": false, "error": "..." } with the provider’s rejection reason.
One of:
openai, anthropic, google, openrouter.The key to test.
GET /api/ai-provider-keys/platform_supported
Returns which providers the platform itself has keys for at this pod: the “AI-on-us” providers, where the platform pays for inference and bills you in credits instead of requiring your own key. The Studio’s LLM Provider Keys settings page uses this to render “AI-on-us active” vs “BYOK required” badges per provider. It’s also a pre-flight check before pointing an agent at a model whose provider you haven’t BYOK’d yet: if the provider isplatform_supported, the model works; otherwise the agent run returns 402 provider_key_decrypt_failed until you upsert your own key.
The path uses an underscore (
platform_supported), not a hyphen. Hyphenating it 404s.["openai", "anthropic", "google", "openrouter"]: whichever ones the pod has a platform-side env-var key configured for.
Error Responses
Errors return{"error": "<message>"}; validation failures additionally include a fields map with the per-provider rejection reason.
| Status | Description |
|---|---|
| 400 | provider is not one of the four supported values |
| 400 | Provider rejected the key (hard fail). Response body: {"error": "Validation failed", "fields": {"<provider>": "<reason>"}} |
| 401 | Missing or invalid auth headers |