For AI agents: markdown of this page — /docs-content-en/ai/credentials/create.md documentation index — /llms.txt

Connect a provider key

POST /v1/ai/credentials

Connects a new provider key to the current user (USER scope). The key is automatically verified with the provider before saving: a key that fails the check is not saved. One user can connect only one key per provider.

Request fields (body)

Field Type Required Default Description
FieldproviderId Typestring Requiredyes Default— DescriptionProvider ID. List: GET /v1/ai/providers
Fieldname Typestring Requiredyes Default— DescriptionArbitrary key name shown in the list
Fieldcredentials.apiKey Typestring Requiredyes Default— DescriptionProvider key (e.g. sk-... for OpenAI)
Fieldcredentials.baseUrl Typestring Requiredconditional Default— DescriptionRequired for custom-openai-compat and not allowed for other providers. Format: https://api.example.com/v1. Only http/https schemes are allowed; private networks are forbidden
FieldisDefault Typeboolean Requiredno Defaultfalse DescriptionUse this key as the default for the provider

Examples

curl — personal key

Terminal
curl -X POST https://vibecode.bitrix24.com/v1/ai/credentials \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "providerId": "openai",
    "name": "My personal OpenAI",
    "credentials": {
      "apiKey": "sk-proj-..."
    },
    "isDefault": true
  }'

curl — OAuth application

Terminal
curl -X POST https://vibecode.bitrix24.com/v1/ai/credentials \
  -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "providerId": "openai",
    "name": "My personal OpenAI",
    "credentials": {
      "apiKey": "sk-proj-..."
    },
    "isDefault": true
  }'

JavaScript — personal key

javascript
const res = await fetch('https://vibecode.bitrix24.com/v1/ai/credentials', {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_API_KEY',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    providerId: 'openai',
    name: 'My personal OpenAI',
    credentials: { apiKey: 'sk-proj-...' },
    isDefault: true,
  }),
})

const { success, data } = await res.json()
if (success) console.log('Key connected, ID:', data.id)

JavaScript — OAuth application

javascript
const res = await fetch('https://vibecode.bitrix24.com/v1/ai/credentials', {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_APP_KEY',
    'Authorization': 'Bearer USER_SESSION_TOKEN',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    providerId: 'openai',
    name: 'My personal OpenAI',
    credentials: { apiKey: 'sk-proj-...' },
    isDefault: true,
  }),
})

const { data } = await res.json()
console.log('ID:', data.id)

Connecting a Custom OpenAI-Compatible service

For an arbitrary OpenAI-compatible service (Minimax, Cerebras, Cohere, an enterprise vLLM/Ollama deployment, etc.) use providerId: cprv_custom_seed and be sure to specify baseUrl:

Terminal
curl -X POST https://vibecode.bitrix24.com/v1/ai/credentials \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "providerId": "cprv_custom_seed",
    "name": "Corporate service",
    "credentials": {
      "apiKey": "sk-corp-...",
      "baseUrl": "https://llm.example.com/v1"
    }
  }'

Response fields

Field Type Description
Fieldsuccess Typeboolean DescriptionAlways true on success
Fielddata.id Typestring DescriptionUnique ID of the created key
Fielddata.providerId Typestring DescriptionProvider ID
Fielddata.provider.slug Typestring DescriptionProvider system name
Fielddata.provider.name Typestring DescriptionProvider name
Fielddata.name Typestring DescriptionKey name from the request
Fielddata.isDefault Typeboolean DescriptionDefault-key flag
Fielddata.createdAt Typestring DescriptionCreation time in ISO 8601
Fielddata.updatedAt Typestring DescriptionLast update time in ISO 8601

Response example

HTTP status 201 Created:

JSON
{
  "success": true,
  "data": {
    "id": "cred_abc123def456",
    "providerId": "openai",
    "provider": {
      "slug": "openai",
      "name": "OpenAI"
    },
    "name": "My personal OpenAI",
    "isDefault": true,
    "createdAt": "2026-04-27T11:30:00.000Z",
    "updatedAt": "2026-04-27T11:30:00.000Z"
  }
}

Error response example

422 credential_invalid — the key failed verification with the provider:

JSON
{
  "success": false,
  "error": {
    "code": "credential_invalid",
    "message": "OpenAI API 401: Incorrect API key provided"
  }
}

Errors

HTTP Code Description
HTTP400 Codeinvalid_request DescriptionThe body schema is violated (missing required fields)
HTTP400 Codeno_key Descriptioncredentials has no apiKey field
HTTP400 Codebase_url_not_supported Descriptioncredentials.baseUrl was sent for a provider that has no endpoint of its own. Only custom-openai-compat accepts the field
HTTP400 Codebase_url_invalid DescriptionbaseUrl uses a scheme other than http/https, or is malformed
HTTP400 Codebase_url_private DescriptionbaseUrl points at a private network or does not resolve to an IP address via DNS
HTTP404 Codeprovider_not_found DescriptionA provider with this providerId does not exist or is disabled
HTTP409 Codealready_exists DescriptionA key for this provider is already connected — use PATCH /v1/ai/credentials/:id
HTTP422 Codecredential_invalid DescriptionThe key failed verification with the provider. The message contains details from the provider
HTTP422 Codeprovider_geoblocked DescriptionThe provider rejected the key check based on our server's region. Connect your own proxy or switch to OpenRouter. The response carries a suggestions field
HTTP403 Codescope_missing DescriptionThe API key lacks the vibe:ai scope

For the full list of common API errors, see Errors.

Key creation limit: 10 requests per minute (one bucket per Bitrix24 account — all the account's keys share it). The current limit is returned in the x-ratelimit-limit header.

Known specifics

Verification before saving. The key is verified with the provider via verify() — an HTTP request to GET /v1/models or (if the provider does not support models) to POST /v1/chat/completions with a minimal body. The verification timeout is 10 seconds. If the key is invalid, nothing is saved to the database.

SSRF protection for the Custom provider. The baseUrl for custom-openai-compat must pass a check: private networks are forbidden (127.0.0.0/8, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 169.254.0.0/16), IPv6 link-local and ULA, IPv4-mapped IPv6. Only http:///https:// schemes are accepted.

Error message sanitized. The error text from the provider is truncated to 200 characters, and URLs are replaced with the placeholder [URL] — this protects against accidental leakage of internal addresses into the client's logs.

See also