Providers & BYOK

Connect your own provider account once, then call its models through the AI Gateway as provider/model.

Overview

A provider is one set of credentials for one AI vendor, stored for your organization. With Bring Your Own Key (BYOK), requests that name a provider's model go to your account at that vendor, and the vendor bills you for them.

  • Console: open Providers in the sidebar, under Build.
  • API: the /v1/providers endpoints below.
  • CLI: backbone providers, see CLI.

API keys you store are encrypted at rest and never returned: no response on this page contains apiKey.

Tier Availability

BYOK is part of the Team, Business and Enterprise plans. On these plans the console shows Providers in the sidebar, and a request that routes to your own provider is billed by that provider, and its model charge does not count against your plan's usage. On Starter, or without a plan, the sidebar item is hidden; use the platform models instead.

Calling Your Models

Name a BYOK model as <prefix>/<model>. The prefix picks the provider type; everything after the first / is passed to the provider unchanged.

openai/gpt-5.1
azure-openai/my-gpt-deployment
anthropic/claude-sonnet-4-5-20250929
xai/grok-4
mistral/mistral-large-latest
ollama/llama3

A name without a / is a platform model and never touches your providers. The same naming works everywhere a model is accepted: chat completions, the Responses API, extraction, transcription and agents.

What goes wrong, and how the gateway answers:

SituationResponse
Unknown prefix, e.g. nope/gpt-5.1400, the message lists the valid prefixes
Known prefix, but no provider of that type configured404 Provider not configured. Please check your provider settings.
Platform model name that does not exist404, the message lists the available platform models

Supported Provider Types

Providerprovider valuePrefixconfig keys
OpenAIOPENAIopenaibaseUrl (optional), organizationId (optional, your OpenAI organization), useResponsesApi (optional, true or false)
Azure OpenAIAZURE_OPENAIazure-openaiendpoint (required, https://), apiVersion (optional), extendedPromptCacheRetention (optional, true or false)
AnthropicANTHROPICanthropicbaseUrl (optional), version (optional, default 2023-06-01)
xAIXAIxaibaseUrl (optional)
MistralMISTRALmistralbaseUrl (optional)
OllamaOLLAMAollamabaseUrl (required, your server, e.g. http://ollama.internal:11434)
  • Every baseUrl must start with http:// or https://. Leave it out to use the vendor's default endpoint; set it for a proxy.
  • For Azure OpenAI, the part after the prefix is your deployment name, not the model name.
  • For Ollama, the server must be reachable from 2kw.ai, and the models are the ones pulled on it. Ollama needs no key: leave apiKey out.
  • useResponsesApi: true makes 2kw.ai talk to OpenAI through the Responses API instead of chat completions.
  • extendedPromptCacheRetention: true asks Azure to keep this row's prompt cache for 24 hours instead of the few minutes it defaults to, for every deployment on this row named exactly gpt-4.1, gpt-5.1 or gpt-5.4 — other deployments on the same row are untouched. Azure stores key/value tensors of the prompt prefix on GPU-local storage on your own Azure account for up to 24 hours after last use — inside the data zone for Data Zone deployments, inside the region for Regional deployments; Microsoft makes no such statement for Global deployments. gpt-5.5 deployments use extended retention by default whatever this setting says. The deployment name must match the model it serves, or Azure refuses the call.
  • Blank config values are dropped before the provider is saved.

Test a Connection

POST /v1/providers/test

Checks credentials before you save them, or re-checks a saved provider. Nothing is stored. Whether the credentials work or not, the answer is 200: read success. A providerId that does not exist answers 404, and a provider type that is not supported answers 400.

curl -X POST https://api.2kw.ai/v1/providers/test \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer sk_your_api_key" \
  -d '{
    "provider": "AZURE_OPENAI",
    "apiKey": "your-azure-key",
    "config": { "endpoint": "https://my-resource.openai.azure.com" }
  }'
FieldTypeRequiredDescription
providerstringYesProvider type, e.g. OPENAI
configobjectYesThe same config you would save
apiKeystringNoKey to test. Leave it out and send providerId to test a saved provider's stored key
providerIdstringNoA saved provider whose stored key is used when apiKey is empty

Success

{
  "success": true,
  "models": ["my-gpt-deployment", "my-embedding-deployment"]
}

Failure

{
  "success": false,
  "message": "Authentication failed: 401"
}

On success, models lists what the credentials can reach; for Azure OpenAI these are your deployment names. On failure, message says why: a missing key, the HTTP status the vendor answered, or the connection error.

Create a Provider

POST /v1/providers

curl -X POST https://api.2kw.ai/v1/providers \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer sk_your_api_key" \
  -d '{
    "name": "Production OpenAI",
    "provider": "OPENAI",
    "apiKey": "sk-proj-...",
    "config": {}
  }'
FieldTypeRequiredDescription
namestringYesDisplay name, 1–255 characters, unique within the organization
providerstringYesProvider type from the table above
apiKeystringYes, except for OLLAMAThe vendor API key. Stored encrypted, never returned
configobjectYesType-specific settings; {} when you need none

Answers 201 with the provider:

{
  "id": "0b8e6f3c-...",
  "name": "Production OpenAI",
  "provider": "OPENAI",
  "config": {},
  "organizationId": "org_...",
  "createdAt": "2026-09-27T10:15:00Z",
  "lastModifiedAt": "2026-09-27T10:15:00Z"
}

The response also carries version and aliases; treat them as informational.

A config that breaks the rules for its type (an Azure provider without endpoint, a baseUrl without http:// or https://, a useResponsesApi or extendedPromptCacheRetention that is not true or false) is refused with 400 and the message says what to fix. A name the organization already uses answers 409, as does a second provider of the same type. A 4xx will not succeed on retry: fix the request.

Update a Provider

PATCH /v1/providers/{id}

Send only what changes:

  • name renames the provider; a name another provider of the organization already uses answers 409.
  • apiKey replaces the stored key; leave it out to keep the current one.
  • config replaces the whole stored config, it is not merged. Send every key you want to keep.
  • provider cannot be changed. To move to another type, create a new provider and delete the old one.
curl -X PATCH https://api.2kw.ai/v1/providers/0b8e6f3c-... \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer sk_your_api_key" \
  -d '{ "apiKey": "sk-proj-new-key" }'

Read Providers

GET /v1/providers

A page of providers. Query parameters: search (matches the name, case-insensitive), page, size and sort.

GET /v1/providers/all

Every provider of the organization as a plain array, without paging.

GET /v1/providers/{id}

One provider. An id that does not exist answers 404.

List Available Models

GET /v1/providers/models

The platform models first, then your providers' models under their provider/model names, fetched live from each vendor.

{
  "object": "list",
  "data": [
    { "id": "gpt-5.1", "object": "model", "owned_by": "system" },
    { "id": "openai/gpt-5.1", "object": "model", "owned_by": "openai" },
    { "id": "anthropic/claude-sonnet-4-5-20250929", "object": "model", "owned_by": "anthropic" }
  ]
}

owned_by is system for platform models and the prefix for yours. Use the id as the model of a request.

The list is a convenience, not the full set of names you can call:

  • Azure OpenAI deployments are not listed. Call them by deployment name; POST /v1/providers/test shows the names.
  • OpenAI is filtered to chat models (gpt-, o1-, o3-, o4-, chatgpt-); fine-tunes and other models are left out.
  • A vendor that cannot be reached, or refuses the key, contributes no models instead of failing the call.

A model missing from this list can still work. For embedding models of one provider, see Which embedding models fit. A knowledge base no longer needs a provider of yours at all: it can embed through the platform's built-in embedding models.

Delete a Provider

DELETE /v1/providers/{id}

Answers 204. From then on, every request that names this provider's prefix answers 404 until you configure a provider of that type again, so move agents, prompts and schemas that use it to another model first.

Permissions

OperationRole needed
List, get, list modelsViewer, Member, Admin or Owner
Create, update, testMember, Admin or Owner
DeleteAdmin or Owner

An API key acts with the role it was created with.

Was this page helpful?