AI Provider Keys
Manage API keys for third-party AI providers (OpenAI, Anthropic, Google, etc.). Provider keys are stored encrypted and used by the AI Gateway to authenticate requests to upstream providers. The raw API key value is never returned after creation.
ProviderKey Object
Reads return these fields only. The key value is never returned, in full or masked.
{
"_id": "65c1f0a2b3c4d5e6f7a8b9c0",
"name": "OpenAI Production Key",
"provider": "openai",
"providerOrganization": "org-abc123",
"owner": "user_abc123",
"organizationId": "org_abc123",
"isActive": true,
"lastUsedAt": null,
"lastTestedAt": "2025-02-06T12:00:00.000Z",
"testResult": {
"success": true,
"message": "Successfully connected to openai",
"status": 200,
"response": "..."
},
"createdAt": "2025-01-10T08:00:00.000Z",
"updatedAt": "2025-02-06T12:00:00.000Z"
}
GET /api/v1/ai-gateway/provider-keys
List provider keys
Returns a paginated list of provider keys for the current user's organization. API key values are never included.
Scope: ai-gateway:read
Parameters:
| Name | In | Type | Required | Description |
|---|---|---|---|---|
provider | query | string | No | Filter by provider: openai, anthropic, google, huggingface, etc. |
status | query | string | No | Filter by status: active, inactive |
q | query | string | No | Search by key name |
limit | query | integer | No | Max results (default: 50, max: 200) |
cursor | query | string | No | meta.nextCursor of the previous page; omit for the first page |
sort | query | string | No | Sort field (default: -createdAt) |
Response: 200 OK (paginated)
{
"data": [
{
"_id": "65c1f0a2b3c4d5e6f7a8b9c0",
"name": "OpenAI Production Key",
"provider": "openai",
"providerOrganization": "org-abc123",
"owner": "user_abc123",
"organizationId": "org_abc123",
"isActive": true,
"lastUsedAt": null,
"lastTestedAt": "2025-02-06T12:00:00.000Z",
"testResult": {
"success": true,
"message": "Successfully connected to openai",
"status": 200,
"response": "..."
},
"createdAt": "2025-01-10T08:00:00.000Z",
"updatedAt": "2025-02-06T12:00:00.000Z"
}
],
"meta": { "total": 4, "limit": 50, "nextCursor": null, "requestId": "req_abc123" }
}
POST /api/v1/ai-gateway/provider-keys
Create a provider key
Registers a new provider API key. The key is encrypted at rest and can only be used by the AI Gateway for upstream requests.
Scope: ai-gateway:write
Request Body:
{
"name": "OpenAI Production Key",
"provider": "openai",
"apiKey": "sk-proj-abc123def456ghi789",
"description": "Production API key for OpenAI models",
"organization": "org-abc123"
}
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Human-readable key name |
provider | string | Yes | Provider name, for example openai or anthropic (any string is accepted) |
apiKey | string | Yes | The raw API key value |
description | string | No | Key description (an empty string is not stored) |
organization | string | No | Provider-specific organization ID (for example an OpenAI org ID), sent when the key is tested. An empty string is not stored |
additionalHeaders | object | No | Extra HTTP headers sent to the provider when the key is tested |
No other fields are accepted: an unknown field (including providerOrganization) returns 400 validation-error, as does a missing name, provider or apiKey (listed in details). A new key is active (is_active: true) and has never been tested.
Response: 201 Created
data is the new key's id, as an object holding the 24-character hex id:
{
"data": { "_str": "65c1f0a2b3c4d5e6f7a8b9c0" },
"meta": { "requestId": "req_abc123" }
}
Use that hex id as :id in the other endpoints.
The raw apiKey value is stored encrypted and is never returned in any API response.
GET /api/v1/ai-gateway/provider-keys/:id
Get a provider key
Returns a single provider key with safe fields only. The raw API key value is never included.
Scope: ai-gateway:read
Parameters:
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes | Provider key ID |
Response: 200 OK
{
"data": {
"_id": "65c1f0a2b3c4d5e6f7a8b9c0",
"name": "OpenAI Production Key",
"provider": "openai",
"providerOrganization": "org-abc123",
"owner": "user_abc123",
"organizationId": "org_abc123",
"isActive": true,
"lastUsedAt": null,
"lastTestedAt": "2025-02-06T12:00:00.000Z",
"testResult": {
"success": true,
"message": "Successfully connected to openai",
"status": 200,
"response": "..."
},
"createdAt": "2025-01-10T08:00:00.000Z",
"updatedAt": "2025-02-06T12:00:00.000Z"
},
"meta": { "requestId": "req_abc123" }
}
PATCH /api/v1/ai-gateway/provider-keys/:id
Update a provider key
Updates provider key properties. If apiKey is provided, the stored key is replaced. Only provided fields are changed.
Scope: ai-gateway:write
Parameters:
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes | Provider key ID |
Request Body:
{
"name": "OpenAI Production Key (Rotated)",
"apiKey": "sk-proj-new-key-value",
"description": "Rotated key as of Feb 2025"
}
| Field | Type | Required | Description |
|---|---|---|---|
name | string | No | Updated key name |
apiKey | string | No | New raw API key value (replaces existing) |
description | string | No | Updated description |
providerOrganization | string | No | Updated provider organization ID |
Response: 200 OK
{
"data": { "success": true },
"meta": { "requestId": "req_abc123" }
}
Read the key back with GET /api/v1/ai-gateway/provider-keys/:id to see the stored values.
DELETE /api/v1/ai-gateway/provider-keys/:id
Delete a provider key
Permanently removes a provider key. Models using this key will lose access to the upstream provider.
Scope: ai-gateway:write
Parameters:
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes | Provider key ID |
Response: 204 No Content
Deleting a provider key will immediately prevent any AI models using this key from making inference requests. Ensure no active models depend on this key before deleting.
POST /api/v1/ai-gateway/provider-keys/:id/test
Test a provider key
Validates the provider key by making a lightweight API call to the upstream provider. This does not consume tokens or incur costs.
Scope: ai-gateway:read
Parameters:
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes | Provider key ID |
Response: 200 OK
{
"data": {
"success": true,
"message": "Successfully connected to openai",
"status": 200,
"response": "..."
},
"meta": { "requestId": "req_abc123" }
}
A successful test is saved on the key as testResult, with lastTestedAt. A key that fails the test returns an error with the provider's reason in the message:
{
"type": "urn:strongly:problem:internal-error",
"title": "Internal error",
"status": 500,
"detail": "Failed to connect to openai: 401 - ...",
"code": "internal-error",
"requestId": "req_abc123"
}