Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.powabase.ai/llms.txt

Use this file to discover all available pages before exploring further.

Each project stores its own set of model-provider API keys (OpenAI, Anthropic, Google, OpenRouter). Keys are encrypted at rest and decrypted only when an agent, workflow, or indexing job needs them. Stored keys are returned masked — the full secret is never echoed back. When you set a key, the platform calls the provider to validate it. Soft failures (provider down, transient network issue) still store the key with is_valid: false; hard failures (provider rejects the credential) reject the request without storing anything.

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 includes id, provider, masked_key (the only representation of the secret ever returned by the API), is_valid, last_validated_at, created_at, and updated_at.
response = requests.get(f"{BASE_URL}/api/ai-provider-keys", headers=headers)

POST /api/ai-provider-keys

Upsert a single provider key. Returns 201 on insert, 200 on update.
provider
string
required
One of: openai, anthropic, google, openrouter.
api_key
string
required
The provider’s raw API key. Validated against the provider before storage.
{ "provider": "openai", "api_key": "sk-..." }
requests.post(f"{BASE_URL}/api/ai-provider-keys", headers=headers, json={"provider": "openai", "api_key": "sk-..."})

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.
{
  "openai": "sk-...",
  "anthropic": "sk-ant-...",
  "google": null,
  "openrouter": ""
}
requests.put(f"{BASE_URL}/api/ai-provider-keys", headers=headers, json={"openai": "sk-...", "anthropic": "sk-ant-..."})

DELETE /api/ai-provider-keys/

Remove a stored key. Returns 204 with no body.
provider
string
required
One of: openai, anthropic, google, openrouter.
requests.delete(f"{BASE_URL}/api/ai-provider-keys/openai", headers=headers)

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.
provider
string
required
One of: openai, anthropic, google, openrouter.
api_key
string
required
The key to test.
{ "provider": "openai", "api_key": "sk-..." }
result = requests.post(f"{BASE_URL}/api/ai-provider-keys/validate", headers=headers, json={"provider": "openai", "api_key": "sk-..."}).json()
if not result["is_valid"]:
    print("Rejected:", result.get("error"))

Error Responses

Errors return {"error": "<message>"}; validation failures additionally include a fields map with the per-provider rejection reason.
StatusDescription
400provider is not one of the four supported values
400Provider rejected the key (hard fail). Response body: {"error": "Validation failed", "fields": {"<provider>": "<reason>"}}
401Missing or invalid auth headers