Provider Keys API
Agentbase lets users securely store their own AI provider API keys (BYOK — Bring Your Own Key). Keys are encrypted at rest with AES-256-GCM and are never returned in plaintext by any endpoint.
All endpoints require a JWT bearer token — see Authentication.
Overview
| Method | Endpoint | Description |
|---|---|---|
GET | /api/provider-keys | List saved provider keys (hints only) |
PUT | /api/provider-keys/:provider | Save or replace a provider key |
DELETE | /api/provider-keys/:provider | Remove a saved provider key |
POST | /api/provider-keys/:provider/validate | Validate a key with a live test call |
Supported providers: openai · anthropic · gemini · huggingface
List Provider Keys
GET /api/provider-keys
Authorization: Bearer <token>Returns a list of providers for which the authenticated user has a saved key. The keyHint field contains only the last 4 characters of the original key — the plaintext key is never returned.
Response
[
{
"provider": "openai",
"keyHint": "ab12",
"isActive": true,
"lastUsedAt": "2026-03-19T10:00:00.000Z",
"lastValidatedAt": "2026-03-18T09:00:00.000Z"
},
{
"provider": "anthropic",
"keyHint": "cd34",
"isActive": true,
"lastUsedAt": null,
"lastValidatedAt": null
}
]Save or Replace a Key
PUT /api/provider-keys/:provider
Authorization: Bearer <token>
Content-Type: application/json
{
"apiKey": "sk-..."
}Saves or replaces the API key for the given provider. The key is validated for correct prefix format (sk- for OpenAI, sk-ant- for Anthropic, AIzaSy for Gemini, hf_ for HuggingFace) before being encrypted and stored.
Path Parameters
| Parameter | Description |
|---|---|
provider | openai · anthropic · gemini · huggingface |
Body
| Field | Type | Required | Description |
|---|---|---|---|
apiKey | string | Yes | The raw API key |
Response
{
"provider": "openai",
"keyHint": "ab12",
"isActive": true
}Errors
| Status | Reason |
|---|---|
400 | Invalid key prefix for the selected provider |
400 | Unsupported provider |
401 | Missing or invalid JWT |
Remove a Key
DELETE /api/provider-keys/:provider
Authorization: Bearer <token>Permanently deletes the stored key for the given provider. The next request made by this user using that provider will fall back to platform keys (if on a paid plan) or return a 402 (if on the Free plan with no BYOK key).
Response
204 No Content
Validate a Key
Makes a lightweight live API call to the provider to verify the stored key is still valid. On success, updates lastValidatedAt.
POST /api/provider-keys/:provider/validate
Authorization: Bearer <token>Response
{
"valid": true,
"provider": "openai",
"models": ["gpt-4", "gpt-4-turbo", "gpt-3.5-turbo"]
}Error Response
{
"valid": false,
"provider": "openai",
"error": "Incorrect API key provided"
}| Status | Reason |
|---|---|
404 | No saved key found for provider |
401 | Missing or invalid JWT |
How BYOK Affects Quota
When a user has a saved BYOK key for the active provider:
- Requests bypass the monthly token quota gate entirely — they are not counted against your plan allowance.
- Overage billing via Stripe is not triggered for BYOK calls.
- The decrypted key is passed only over the internal network between the core API and the AI microservice — it is never sent to browser clients.
Free-plan users without a saved key for a provider will receive a 402 Payment Required error when their quota is exhausted, along with a suggestion to add a BYOK key in Settings.
Security Notes
- Keys are encrypted using AES-256-GCM before being written to the database. The
ENCRYPTION_KEYenvironment variable (64 hex characters) must be set and kept stable. - The encryption includes an authentication tag — any tampering with the stored ciphertext causes decryption to throw and the request to be rejected.
- Only the last 4 characters (
keyHint) are ever returned by the API. - Ephemeral decrypted keys are held in memory only for the duration of a single request and are never cached.
Key rotation: If you need to rotate
ENCRYPTION_KEY, you must first decrypt and re-encrypt all rows inuser_provider_keysbefore deploying the new key. There is no automatic migration — plan accordingly.