Skip to main content

Upsert AI Provider

Creates or updates an AI provider's configuration and the AI features it serves. The saved configuration is used by the next AI call; nothing needs activating.

api_key is nullable on purpose. You cannot read the key back, so a save that leaves it out keeps the stored one:

  • omitted or null keeps the stored key (the first save of a provider must carry one);
  • a non-empty string replaces it;
  • an empty string is refused: a provider cannot be saved without a key.

A stored key is only sent to the endpoint it was saved for. Changing base_url to another origin while keeping the stored key is refused with 10015 naming api_key: send the key again. An empty base_url counts as the vendor's own endpoint.

Defaults. An empty base_url is saved as the vendor's endpoint (https://api.anthropic.com for claude, https://api.openai.com for openai), a timeout of 0 as 60 seconds and a max_tokens of 0 as 1024. The response shows the saved values.

Features. features is the full list and replaces the stored one; omitting it clears it. Turning is_enabled off keeps the features, so turning it back on restores the same scope. Note that is_enabled is written as sent: omitting it disables the provider.

Platform owner only. The caller's node must be the platform root node; any other caller is refused with 403 / 10005.

Required permission: ai-provider:update

Request​

PUT /v2/admin/ai-providers/{provider}

Parameters​

NameTypeInDescription
providerstringpathRequired. Provider key: claude or openai

Headers​

NameDescription
AuthorizationRequired. Bearer <access_token>
Content-TypeRequired. application/json

Body​

FieldTypeRequiredDescription
api_keystring | nullConditionalVendor API key. Required on the first save; null keeps the stored key afterwards
base_urlstringNoAPI base URL. Empty means the vendor's own endpoint
modelstringYesModel used for text features (e.g. claude-sonnet-4-5, gpt-4o)
image_modelstringConditionalModel used for tokenization_image (e.g. gpt-image-1). Required when features contains tokenization_image; may be stored ahead of that
timeoutintegerNoRequest timeout in seconds, 0 or greater. 0 means 60
max_tokensintegerNoMaximum reply length in tokens, 0 or greater. 0 means 1024
is_enabledbooleanNoMaster switch. Omitted means false
featuresarray of stringNoAI features this provider serves: tokenization_suggestion, support_assistant, tokenization_image. Each at most once. tokenization_image only on openai

Example​

curl --request PUT \
--url '{{baseUrl}}/v2/admin/ai-providers/openai' \
--header 'Authorization: Bearer <access_token>' \
--header 'Content-Type: application/json' \
--data '{
"api_key": "<openai_api_key>",
"base_url": "",
"model": "gpt-4o",
"image_model": "gpt-image-1",
"timeout": 0,
"max_tokens": 0,
"is_enabled": true,
"features": ["tokenization_suggestion", "tokenization_image"]
}'

Response​

200 OK with the saved provider, masked as on List AI Providers.

{
"provider": "openai",
"base_url": "https://api.openai.com",
"model": "gpt-4o",
"image_model": "gpt-image-1",
"timeout": 60,
"max_tokens": 1024,
"is_enabled": true,
"features": ["tokenization_suggestion", "tokenization_image"],
"api_key_set": true,
"api_key_last4": "Zk8w",
"configured": true,
"created_at": "2026-11-09T11:31:56.218Z",
"updated_at": "2026-11-09T11:31:56.218Z"
}

Errors​

StatusCodeDescription
40010015Validation failed (model missing, negative timeout or max_tokens) — see details. Also (with details naming api_key) a stored key that would move to a new endpoint
40079001Unsupported provider key (domain 79)
40079002Unknown feature, or a feature listed twice (domain 79)
40079004No API key: the first save carries none, or api_key is an empty string (domain 79)
40079008The provider cannot serve a listed feature (tokenization_image on claude) (domain 79)
40079009tokenization_image listed without an image_model (domain 79)
40310005The caller is not the platform owner (domain 2)

See Errors for the error format and common codes.