Ana içeriğe geç

Create LLM Provider

Endpoint​

POST /apiops/projects/{projectName}/llm-providers/{providerName}/

Authentication​

Requires a Personal API Access Token.

Authorization: Bearer YOUR_TOKEN

Request​

Headers​

HeaderValueRequired
AuthorizationBearer {token}Yes
Content-Typeapplication/jsonYes

Path Parameters​

ParameterTypeRequiredDescription
projectNamestringYesProject name
providerNamestringYesLLM provider name (must match the name field in the body)

Query Parameters​

None

Request Body​

The body is the LLM provider object. A "_class": "llm" field is not required; if you send it, it is ignored.

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",
"credentialSource": "GATEWAY",
"apiKeyLocation": "HEADER",
"apiKeyPrefix": null,
"allowClientOverride": false,
"apiKey": "sk-your-deepseek-api-key",
"onlyListedModels": false,
"deploymentType": "CLOUD",
"supportedModels": [
{
"modelId": "deepseek-chat",
"displayName": "DeepSeek Chat",
"contextWindow": 64000,
"maxOutputTokens": 8192,
"pricePerMillionInput": 0.27,
"pricePerMillionOutput": 1.10,
"capabilities": ["chat", "function_calling"],
"modality": "TEXT",
"enabled": true,
"aclEnabled": false,
"aclEntries": []
}
],
"metadata": [
{
"key": "team",
"value": "platform",
"secret": false
}
]
}

Request Body Fields​

FieldTypeRequiredDefaultDescription
_classstringNo-Not required. Ignored when sent
namestringYes-Provider name; must match providerName in the path (case-insensitive)
descriptionstringNo-Free-text description
enabledbooleanNotrueWhether the provider is active
providerTypestringNo-Provider type enum constant (OPENAI, ANTHROPIC, AZURE_OPENAI, BEDROCK, VERTEX, COHERE, MISTRAL, DEEPSEEK, GROQ, MOONSHOT, ZHIPU, QWEN_DASHSCOPE, XAI, GOOGLE_AI_STUDIO, TOGETHER, FIREWORKS, CEREBRAS, HUGGINGFACE, OPENROUTER, PERPLEXITY, NVIDIA_NIM, VLLM, OLLAMA, CUSTOM_OPENAI_COMPAT, VOYAGE, TYPESAFE, TEI, OTHER)
endpointstringNoprovider defaultBase API URL; auto-filled from providerType when blank. Required for TEI (no default endpoint); TYPESAFE defaults to https://api.typesafe.ai/v1
apiVersionstringNoprovider defaultProvider API version; auto-filled from providerType when blank
organizationIdstringNo-Organization identifier (OpenAI org-...)
authSchemestringNoprovider defaultAuth scheme enum constant (BEARER, API_KEY_HEADER, BASIC, AWS_SIGV4, OAUTH2, NONE, CUSTOM); auto-filled from providerType when null
authHeaderNamestringNoprovider defaultCredential header name; auto-filled from providerType when blank
apiKeystringNo-Primary auth secret (Bearer token, api-key). Encrypted at rest; never returned
apiSecretstringNo-Secondary auth secret (e.g. AWS SigV4 secretKey). Encrypted at rest; never returned
regionstringNo-Region (e.g. Bedrock AWS region)
serviceAccountJsonstringNo-GCP Vertex service-account JSON blob. Encrypted at rest; never returned
supportedModelsarrayNo-The models of the provider (see fields below)
coldStartRetryEnabledbooleanNo-Deprecated, has no effect. Still accepted in the request body for compatibility; the value is ignored
onlyListedModelsbooleanNofalseWhen true, the gateway refuses a model ID that is not in supportedModels (HTTP 403). true with an empty supportedModels list is rejected with 400.
deploymentTypestringNoautoDeployment type enum constant (CLOUD, ON_PREM, OTHER). A report-only label (Cloud / On-Premises / Other breakdown in AI usage reports); it never changes routing. When null it is auto-filled: OTHER for providerType OTHER (custom provider), ON_PREM for self-hosted types (VLLM, OLLAMA, CUSTOM_OPENAI_COMPAT, TEI), CLOUD otherwise. An explicit value is kept
metadataarrayNo-Custom key/value metadata entries (see fields below)
endpoint and apiVersion runtime semantics

endpoint 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 a providerType: OTHER connection with its own path fields. 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.

Wire protocol and paths

wireProtocol and the six default*Path fields are the provider type's own, unless you set them on the connection. You can write them through this endpoint. A body that omits them, or sends a blank path, keeps the stored values. If the body changes providerType, the stored values are not kept and the new type's own apply. For a vendor outside the provider type list, use providerType: OTHER and set the protocol and paths on the connection.

Paths support Apinizer variable resolution (${env.name}, #{contextVar}), resolved at request time against the effective URL endpoint + path.

Supported Model Fields​

Each supportedModels row is one model of the provider.

FieldTypeRequiredDescription
modelIdstringYesModel identifier (e.g. deepseek-chat)
displayNamestringNoHuman-readable model name
contextWindowintegerNoMaximum context window in tokens
maxOutputTokensintegerNoMaximum output tokens
pricePerMillionInputnumberNoUSD per 1M input tokens
pricePerMillionOutputnumberNoUSD per 1M output tokens
pricePerMillionCachednumberNoUSD per 1M cached input tokens
pricePerMillionCacheWritenumberNoUSD per 1M cache-write tokens (flat rate). A matching row in cacheWritePricesByTtl overrides this for its TTL
cacheWritePricesByTtlarrayNoCache-write price per TTL — see Cache-Write Price Fields
contextTierPricesarrayNoLong-context price tiers — see Context-Tier Price Fields
serviceTierPricesarrayNoProvider service-tier price multipliers — see Service-Tier Price Fields
pricePerImagenumberNoUSD per generated image
pricePerAudioMinutenumberNoUSD per minute of audio (STT)
pricePerCharacterTtsnumberNoUSD per input character (TTS)
capabilitiesarray[string]NoCapability tags, normalized on save — see Capabilities Normalization
modalitystringNoModality enum constant (TEXT, VISION, AUDIO, EMBEDDING, RERANK, MULTIMODAL, IMAGE)
enabledbooleanNofalse makes the gateway refuse the model with 403 and leave it out of GET /v1/models
aclEnabledbooleanNotrue limits the callers of the model to the subjects in aclEntries
aclEntriesarrayNoConsumers, applications and organizations allowed to call the model — see Model Access Control Fields

Cache-Write Price (cacheWritePricesByTtl) Fields​

One row per cache TTL the provider bills separately for (e.g. Anthropic prices a 5-minute cache write at 1.25× input and a 1-hour cache write at 2× input). A row overrides pricePerMillionCacheWrite for usage that reports that TTL.

FieldTypeRequiredDescription
ttlstringYesShort TTL label as the provider reports it — typically "5m" or "1h"
pricePerMillionnumberYesUSD per 1M cache-write tokens at this TTL
"cacheWritePricesByTtl": [
{ "ttl": "5m", "pricePerMillion": 3.75 },
{ "ttl": "1h", "pricePerMillion": 6.00 }
]

Context-Tier Price (contextTierPrices) Fields​

Long-context pricing: above aboveTokens prompt tokens, the whole request is priced at inputFactor × the input price and outputFactor × the output price. When several tiers match, the one with the highest aboveTokens threshold wins.

FieldTypeRequiredDescription
aboveTokensintegerYesPrompt-token threshold (input + cached + cache-write). The tier applies strictly above this value
inputFactornumberYesMultiplier applied to the input price for the whole request
outputFactornumberYesMultiplier applied to the output price for the whole request
"contextTierPrices": [
{ "aboveTokens": 200000, "inputFactor": 2.0, "outputFactor": 1.5 }
]

Service-Tier Price (serviceTierPrices) Fields​

The gateway applies the row whose tier matches the service_tier value the provider echoed in the response usage (e.g. OpenAI's flex / priority, or a request routed through a Batch API).

FieldTypeRequiredDescription
tierstringYesService tier enum constant: BATCH, PRIORITY, FLEX or CUSTOM
namestringNoProvider-reported tier value to match, used only when tier is CUSTOM (e.g. "scale"); ignored for the fixed tiers
inputFactornumberYesMultiplier applied to the input price when the provider echoes this tier
outputFactornumberYesMultiplier applied to the output price when the provider echoes this tier
"serviceTierPrices": [
{ "tier": "BATCH", "name": null, "inputFactor": 0.5, "outputFactor": 0.5 },
{ "tier": "PRIORITY", "name": null, "inputFactor": 2.0, "outputFactor": 2.0 }
]

Model Access Control (aclEntries) Fields​

One row per consumer, application or organization that may call the model. The rows apply only when aclEnabled is true. Whoever may edit the provider may edit the access control of its models.

FieldTypeRequiredDescription
subjectTypestringYesKind of the subject: consumer, application or organization
subjectIdstringNo*Identifier of the subject. If sent, it wins over subjectName
subjectNamestringNo*Name of the subject: consumer username, application name or organization name. Used when subjectId is not sent
organizationIdstringNoIdentifier of the organization of the subject
organizationNamestringNoName of the organization of the subject
"aclEnabled": true,
"aclEntries": [
{ "subjectType": "ORGANIZATION", "subjectId": "64f0c0ffee", "subjectName": "Payments", "organizationId": null, "organizationName": null }
]

* Send subjectId or subjectName. A name is looked up in the project of the provider, then in the admin project. A name that finds nobody returns 400 Bad Request. A name that matches more than one subject returns 400 Bad Request too, and the message asks you to send the subject id. One match in the project of the provider wins over matches in the admin project. Two matches in the project of the provider are ambiguous. When the project of the provider has no match, several matches in the admin project are ambiguous. Send subjectId in these cases.

Capabilities Normalization​

capabilities is normalized on every save. The stored value never contains a legacy spelling.

Known keys (the values capabilities normalizes to): function_calling, vision, prompt_caching, reasoning, structured_output, streaming, web_search.

Aliases collapsed to a known key: tools, tool_use, tool_calling, function-calling → function_calling; image_input, multimodal_input → vision; caching → prompt_caching; json_mode, json_schema, response_schema → structured_output; search → web_search.

Dropped as modality noise (already implied by the modality field, so it carries no extra information): chat, completion, text, embedding, embeddings, code.

Unknown values are lower-cased, converted to snake_case, and kept as a custom tag.

For example, a request body sending "capabilities": ["chat", "tool_use", "json_mode"] is stored as ["function_calling", "structured_output"] — chat is dropped and both remaining values collapse to their canonical key.

Prices are optional

A model without a price counts as 0 in cost reports. A USD limit does not meter such a model.

Metadata Entry Fields​

FieldTypeRequiredDescription
keystringYesMetadata key
valuestringNoMetadata value; encrypted at rest when secret is true
secretbooleanNoWhether the value is a secret (nulled in read responses)

Notes​

  • name must match providerName in the path (case-insensitive), otherwise a 400 Bad Request is returned
  • Fields left blank (endpoint, apiVersion, authScheme, authHeaderName, deploymentType) are auto-filled from the selected providerType

Response​

Success Response (200 OK)​

{
"status": "SUCCESS",
"deploymentResult": {
"success": true
}
}

EnumStatus​

  • SUCCESS - Operation successful
  • FAILURE - 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",
"supportedModels": [
{
"modelId": "deepseek-chat",
"displayName": "DeepSeek Chat",
"contextWindow": 64000,
"maxOutputTokens": 8192,
"modality": "TEXT"
}
]
}'

Permissions​

  • User must have AI_DEVELOPMENT + MANAGE permission in the project

Notes and Warnings​

  • Health Fields Are Read-Only: healthStatus, lastHealthCheckAt and lastLatencyMs are not accepted on create. The health check writes them.

  • Upsert Semantics:

    • If a provider with the same name already exists, it is updated (its internal ID is reused)
    • Otherwise a new provider is created
  • Model List Checks:

    • Every model needs a modelId, and a modelId can appear only once in supportedModels
    • A model that is removed from the list cannot still be used: an AI proxy, policy or knowledge base that names it makes the request 400, and the message names where the model is used
    • An aclEntries row must name an existing consumer, application or organization, otherwise the request is 400
  • Secret Fields (INV-06):

    • apiKey, apiSecret and serviceAccountJson are encrypted before persistence and never returned in read responses
  • Enum Serialization:

    • Enum values (providerType, authScheme, deploymentType, model modality) must be sent as the enum constant name (e.g. DEEPSEEK, BEARER, CLOUD, TEXT), not lowercase
  • Automatic Defaults:

    • Blank endpoint/apiVersion/authScheme/authHeaderName/deploymentType are auto-filled from the providerType default
  • Deploy on Save:

    • The provider is encrypted and pushed to the AI Gateway workers as part of the save