Create LLM Provider Definition
Endpoint
POST /apiops/projects/{projectName}/llm-provider-definitions/{definitionName}/
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 |
| definitionName | string | Yes | Provider catalog definition name (must match the effective name in the body) |
Query Parameters
None
Request Body
The body is an LlmProviderDefinition object — unlike Create LLM Provider, this is a plain entity, not a polymorphic type, so no _class discriminator is required or accepted.
Full JSON Body Example
{
"name": "internal-llm-gateway",
"code": "internal-llm-gateway",
"displayName": "Internal LLM Gateway",
"defaultEndpoint": "https://llm-gateway.internal.example.com/v1",
"defaultApiVersion": "v1",
"defaultAuthScheme": "API_KEY_HEADER",
"defaultAuthHeaderName": "x-api-key",
"iconUrl": "https://cdn.example.com/icons/internal-llm.svg",
"docsUrl": "https://wiki.internal.example.com/llm-gateway"
}
Request Body Fields
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| name | string | No | code value, then path value | Definition name; if blank, falls back to code, then to definitionName. Must match definitionName in the path (case-insensitive) once resolved |
| code | string | No | - | Provider type code (e.g. internal-llm-gateway); used as the name fallback when name is blank |
| displayName | string | No | - | UI label |
| defaultEndpoint | string | No | - | Default base API URL |
| defaultApiVersion | string | No | - | Default API version |
| defaultAuthScheme | string | No | - | Default auth scheme enum constant (BEARER, API_KEY_HEADER, BASIC, AWS_SIGV4, OAUTH2, NONE, CUSTOM) |
| defaultAuthHeaderName | string | No | - | Default credential header name |
| iconUrl | string | No | - | Provider icon URL |
| docsUrl | string | No | - | Vendor documentation deep link |
| builtIn | boolean | No | forced false | Ignored on write and always persisted as false. Sending "builtIn": true is rejected outright (see below) |
| id, projectId, lastUpdatedAt | — | No | server-assigned | Any value sent for these fields is ignored — id/projectId are resolved server-side (upsert lookup / path project), lastUpdatedAt is always set to the current time |
Notes
namemust matchdefinitionNamein the path (case-insensitive) once resolved (name→code→ path fallback), otherwise a400 Bad Requestis returned- Sending
"builtIn": truein the body is rejected with a400 Bad Request("Built-in provider definitions are read-only."), regardless of whether a definition with that name already exists - No
_classdiscriminator — this is a plain entity body, not a polymorphicConnectionConfigsubtype
Response
Success Response (200 OK)
{
"status": "SUCCESS",
"deploymentResult": {
"success": true
}
}
EnumStatus
SUCCESS- Operation successfulFAILURE- Operation failed
Error Response (400 Bad Request)
{
"status": "FAILURE",
"resultMessage": "Built-in provider definitions are read-only."
}
or
{
"status": "FAILURE",
"resultMessage": "Provider definition name in path (internal-llm-gateway) does not match name in body (other-name)!"
}
or
{
"status": "FAILURE",
"resultMessage": "Provider definition 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-provider-definitions/internal-llm-gateway/" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "internal-llm-gateway",
"code": "internal-llm-gateway",
"displayName": "Internal LLM Gateway",
"defaultEndpoint": "https://llm-gateway.internal.example.com/v1",
"defaultApiVersion": "v1",
"defaultAuthScheme": "API_KEY_HEADER",
"defaultAuthHeaderName": "x-api-key"
}'
Permissions
- User must have
AI_DEVELOPMENT+MANAGEpermission in the project
Notes and Warnings
- Upsert Semantics:
- If a definition with the same
namealready exists in the caller's visible scope (built-in ∪ this project's custom entries) and is not built-in, it is updated (its internal ID is reused) - Otherwise a new definition is created, owned by the calling project
- If a definition with the same
- Built-in Is Read-Only:
- Both the target of an update (an already-built-in row) and the incoming body (
"builtIn": true) are checked — either one is rejected with the same stable message
- Both the target of an update (an already-built-in row) and the incoming body (
- No
_classDiscriminator:- Unlike
ConnectionConfigLlm(LLM Provider) bodies, this entity is not polymorphic
- Unlike
- No Secrets, No Deploy:
- The entity carries no credential fields, and creating a definition never triggers an AI Gateway worker deploy —
deploymentResultreflects the database write only
- The entity carries no credential fields, and creating a definition never triggers an AI Gateway worker deploy —
Related Documentation
- Update LLM Provider Definition - Update an existing custom definition
- Get LLM Provider Definition - Retrieve a definition by name
- List LLM Provider Definitions - List all definitions visible to a project
- LLM Provider Definitions API - Resource overview, permissions and the LlmProviderDefinition vs. LLM Provider distinction