Create LLM Provider
Endpoint
POST /apiops/projects/{projectName}/llm-providers/{providerName}/
Authentication
Requires a Personal API Access Token.
Header
Authorization: Bearer YOUR_TOKEN
Request
Headers
| Header | Value | Required |
|---|---|---|
| Authorization | Bearer {token} | Yes |
| Content-Type | application/json | Yes |
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| projectName | string | Yes | Project name |
| providerName | string | Yes | LLM provider name (must match the name field in the body) |
Query Parameters
None
Request Body
The body is a polymorphic ConnectionConfigLlm object. It must include "_class": "llm" — without this discriminator, deserialization fails.
Full JSON Body Example
{
"_class": "llm",
"name": "deepseek-primary",
"description": "DeepSeek production provider",
"enabled": true,
"providerType": "DEEPSEEK",
"endpoint": "https://api.deepseek.com/v1",
"apiVersion": "v1",
"authScheme": "BEARER",
"authHeaderName": "Authorization",
"apiKey": "sk-your-deepseek-api-key",
"providerRpmLimit": 500,
"providerTpmLimit": 100000,
"coldStartRetryEnabled": false,
"deploymentType": "CLOUD",
"allowedModelIds": ["deepseek-chat"],
"supportedModels": [
{
"modelId": "deepseek-chat",
"displayName": "DeepSeek Chat",
"contextWindow": 64000,
"maxOutputTokens": 8192,
"pricePerMillionInput": 0.27,
"pricePerMillionOutput": 1.10,
"capabilities": ["chat", "function_calling"],
"modality": "TEXT"
}
],
"metadata": [
{
"key": "team",
"value": "platform",
"secret": false
}
]
}
Request Body Fields
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| _class | string | Yes | - | Polymorphic discriminator — must be "llm" |
| name | string | Yes | - | Provider name; must match providerName in the path (case-insensitive) |
| description | string | No | - | Free-text description |
| enabled | boolean | No | true | Whether the provider is active |
| providerType | string | No | - | Provider type enum constant (OPENAI, ANTHROPIC, AZURE_OPENAI, BEDROCK, VERTEX, COHERE, MISTRAL, DEEPSEEK, GROQ, MOONSHOT, ZHIPU, QWEN_DASHSCOPE, VLLM, OLLAMA, CUSTOM_OPENAI_COMPAT, VOYAGE, OTHER) |
| endpoint | string | No | provider default | Base API URL; auto-filled from providerType when blank |
| apiVersion | string | No | provider default | Provider API version; auto-filled from providerType when blank |
| organizationId | string | No | - | Organization identifier (OpenAI org-...) |
| authScheme | string | No | provider default | Auth scheme enum constant (BEARER, API_KEY_HEADER, BASIC, AWS_SIGV4, OAUTH2, NONE, CUSTOM); auto-filled from providerType when null |
| authHeaderName | string | No | provider default | Credential header name; auto-filled from providerType when blank |
| apiKey | string | No | - | Primary auth secret (Bearer token, api-key). Encrypted at rest; never returned |
| apiSecret | string | No | - | Secondary auth secret (e.g. AWS SigV4 secretKey). Encrypted at rest; never returned |
| region | string | No | - | Region (e.g. Bedrock AWS region) |
| serviceAccountJson | string | No | - | GCP Vertex service-account JSON blob. Encrypted at rest; never returned |
| supportedModels | array | No | - | Per-provider model snapshots (see fields below) |
| providerRpmLimit | integer | No | - | Organization-level requests-per-minute limit |
| providerTpmLimit | integer | No | - | Organization-level tokens-per-minute limit |
| coldStartRetryEnabled | boolean | No | - | Retry on 503 for self-hosted providers (vLLM/Ollama) |
| deploymentType | string | No | auto | Deployment type enum constant (CLOUD, ON_PREM); auto-filled from providerType when null |
| providerDefinitionId | string | No | - | Optional catalog provider definition reference |
| allowedModelIds | array[string] | No | - | Integration-level model filter; empty/null = all models allowed |
| metadata | array | No | - | Custom key/value metadata entries (see fields below) |
endpoint and apiVersion runtime semanticsendpoint takes the base address only (e.g. https://api.deepseek.com/v1) — the request path
(/chat/completions, /embeddings, /audio/transcriptions, /audio/speech, /images/generations,
/responses) is appended automatically based on the request type. Putting a path in endpoint
produces a broken URL at request time; to set a custom path, use
LLM Provider Definitions instead. A query string embedded in
endpoint is not lost, but it is relocated to the end of the resolved address, after the appended path.
apiVersion only reaches the request URL for AZURE_OPENAI connections, where it is added as an
api-version query parameter (skipped if one is already present). For ANTHROPIC it is sent as the
anthropic-version header instead and never touches the URL. Bedrock and Vertex build their address
entirely in provider-specific code, so apiVersion has no effect on either.
See Query Strings and API Versioning in the Final URL for the full behavior.
wireProtocol and the six default*Path fields are copied from the selected provider definition
(providerDefinitionId) when the connection is saved; the gateway reads only that copy. They are
not writable through this endpoint — values sent in the body are ignored, and values omitted are
preserved from the stored record rather than cleared. To change a path, edit the provider definition
in the catalog, or clear providerDefinitionId and let the provider type's built-in defaults apply.
Paths support Apinizer variable resolution (${env.name}, #{contextVar}), resolved at request time
against the effective URL endpoint + path.
Supported Model (LlmModelDef) Fields
| Field | Type | Required | Description |
|---|---|---|---|
| modelId | string | Yes | Model identifier (e.g. deepseek-chat) |
| displayName | string | No | Human-readable model name |
| contextWindow | integer | No | Maximum context window in tokens |
| maxOutputTokens | integer | No | Maximum output tokens |
| pricePerMillionInput | number | No | USD per 1M input tokens |
| pricePerMillionOutput | number | No | USD per 1M output tokens |
| pricePerMillionCached | number | No | USD per 1M cached tokens |
| capabilities | array[string] | No | Model capabilities (e.g. chat, function_calling, vision) |
| modality | string | No | Modality enum constant (TEXT, VISION, AUDIO, EMBEDDING, RERANK, MULTIMODAL, IMAGE) |
Metadata Entry Fields
| Field | Type | Required | Description |
|---|---|---|---|
| key | string | Yes | Metadata key |
| value | string | No | Metadata value; encrypted at rest when secret is true |
| secret | boolean | No | Whether the value is a secret (nulled in read responses) |
Notes
_classmust be"llm"or the request fails to deserializenamemust matchproviderNamein the path (case-insensitive), otherwise a400 Bad Requestis returned- Fields left blank (
endpoint,apiVersion,authScheme,authHeaderName,deploymentType) are auto-filled from the selectedproviderType
Response
Success Response (200 OK)
{
"status": "SUCCESS",
"deploymentResult": {
"success": true
}
}
EnumStatus
SUCCESS- Operation successfulFAILURE- Operation failed
Error Response (400 Bad Request)
{
"status": "FAILURE",
"resultMessage": "LLM provider name in path (deepseek-primary) does not match name in body (deepseek-2)!"
}
or
{
"status": "FAILURE",
"resultMessage": "LLM provider body can not be empty!"
}
Error Response (401 Unauthorized)
{
"status": "FAILURE",
"resultMessage": "Token is not valid!"
}
cURL Example
curl -X POST \
"https://demo.apinizer.com/apiops/projects/MyProject/llm-providers/deepseek-primary/" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"_class": "llm",
"name": "deepseek-primary",
"description": "DeepSeek production provider",
"enabled": true,
"providerType": "DEEPSEEK",
"endpoint": "https://api.deepseek.com/v1",
"apiVersion": "v1",
"authScheme": "BEARER",
"authHeaderName": "Authorization",
"apiKey": "sk-your-deepseek-api-key",
"deploymentType": "CLOUD",
"allowedModelIds": ["deepseek-chat"],
"supportedModels": [
{
"modelId": "deepseek-chat",
"displayName": "DeepSeek Chat",
"contextWindow": 64000,
"maxOutputTokens": 8192,
"modality": "TEXT"
}
]
}'
Permissions
- User must have
AI_DEVELOPMENT+MANAGEpermission in the project
Notes and Warnings
- Upsert Semantics:
- If a provider with the same
namealready exists, it is updated (its internal ID is reused) - Otherwise a new provider is created
- If a provider with the same
- Polymorphic Discriminator:
"_class": "llm"is mandatory in the body
- Secret Fields (INV-06):
apiKey,apiSecretandserviceAccountJsonare encrypted before persistence and never returned in read responses
- Enum Serialization:
- Enum values (
providerType,authScheme,deploymentType, modelmodality) must be sent as the enum constant name (e.g.DEEPSEEK,BEARER,CLOUD,TEXT), not lowercase
- Enum values (
- Automatic Defaults:
- Blank endpoint/apiVersion/authScheme/authHeaderName/deploymentType are auto-filled from the
providerTypedefault
- Blank endpoint/apiVersion/authScheme/authHeaderName/deploymentType are auto-filled from the
- Deploy on Save:
- The provider is encrypted and pushed to the AI Gateway workers as part of the save
Related Documentation
- Update LLM Provider - Update an existing provider
- Get LLM Provider - Retrieve a provider by name
- List LLM Providers - List all providers in a project
- LLM Providers API - Resource overview and permissions