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 your 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
providerId string yes Provider ID. List: GET /v1/ai/providers
name string yes Arbitrary key name shown in the list
credentials.apiKey string yes Provider key (e.g. sk-... for OpenAI)
credentials.baseUrl string conditional Required for custom-openai-compat. Format: https://api.example.com/v1. Only http/https, private networks forbidden
isDefault boolean no false Use 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-...' },
  }),
})

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, a corporate vLLM/Ollama, 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
success boolean Always true on success
data.id string Unique ID of the created key
data.providerId string Provider ID
data.provider.slug string Provider system name
data.provider.name string Provider name
data.name string Key name from the request
data.isDefault boolean Default-key flag
data.createdAt string Creation time in ISO 8601
data.updatedAt string Last 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
400 invalid_request The body schema is violated (missing required fields)
400 no_key credentials has no apiKey field
400 base_url_invalid baseUrl uses a scheme other than http/https, or is malformed
400 base_url_private baseUrl points at a private network or does not resolve to an IP address via DNS
404 provider_not_found A provider with this providerId does not exist or is disabled
409 already_exists A key for this provider is already connected — use PATCH /v1/ai/credentials/:id
422 credential_invalid The key failed verification with the provider. The message contains details from the provider
422 provider_geoblocked The 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
403 scope_missing The API key lacks the vibe:ai scope

Full list of common API errors — Errors.

Key creation limit: 10 requests per minute (one bucket per portal — all the portal's keys share it).

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. For an invalid key, 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