#Подключить ключ провайдера

POST /v1/ai/credentials

Подключает новый ключ провайдера к вашему пользователю (USER scope). Ключ автоматически проверяется у провайдера до сохранения — если ключ некорректен, операция возвращает 422 credential_invalid с сообщением от провайдера, и ничего не сохраняется. Один пользователь может подключить только один ключ на каждого провайдера.

#Поля запроса (body)

Поле Тип Обяз. По умолч. Описание
providerId string да ID провайдера. Список: `GET /v1/ai/providers`
name string да Произвольное имя ключа для отображения в списке
credentials.apiKey string да Ключ от провайдера (например, sk-... для OpenAI)
credentials.baseUrl string условно Обязательно для custom-openai-compat. Формат: https://api.example.com/v1. Только http/https, приватные сети запрещены
isDefault boolean нет false Использовать этот ключ по умолчанию для провайдера

#Примеры

#curl — личный ключ

Terminal
curl -X POST https://vibecode.bitrix24.tech/v1/ai/credentials \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "providerId": "openai",
    "name": "Мой личный OpenAI",
    "credentials": {
      "apiKey": "sk-proj-..."
    },
    "isDefault": true
  }'

#curl — OAuth-приложение

Terminal
curl -X POST https://vibecode.bitrix24.tech/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": "Мой личный OpenAI",
    "credentials": {
      "apiKey": "sk-proj-..."
    },
    "isDefault": true
  }'

#JavaScript — личный ключ

javascript
const res = await fetch('https://vibecode.bitrix24.tech/v1/ai/credentials', {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_API_KEY',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    providerId: 'openai',
    name: 'Мой личный OpenAI',
    credentials: { apiKey: 'sk-proj-...' },
    isDefault: true,
  }),
})

const { success, data } = await res.json()
if (success) console.log('Ключ подключён, ID:', data.id)

#JavaScript — OAuth-приложение

javascript
const res = await fetch('https://vibecode.bitrix24.tech/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: 'Мой личный OpenAI',
    credentials: { apiKey: 'sk-proj-...' },
  }),
})

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

#Подключение Custom OpenAI-Compatible сервиса

Для произвольного OpenAI-совместимого сервиса (Minimax, Cerebras, Cohere, корпоративный vLLM/Ollama и т. п.) используйте providerId: cprv_custom_seed и обязательно укажите baseUrl:

Terminal
curl -X POST https://vibecode.bitrix24.tech/v1/ai/credentials \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "providerId": "cprv_custom_seed",
    "name": "Корпоративный сервис",
    "credentials": {
      "apiKey": "sk-corp-...",
      "baseUrl": "https://llm.example.com/v1"
    }
  }'

#Поля ответа

Поле Тип Описание
success boolean Всегда true при успехе
data.id string Уникальный ID созданного ключа
data.providerId string ID провайдера
data.provider.slug string Системное имя провайдера
data.provider.name string Название провайдера
data.name string Имя ключа из запроса
data.isDefault boolean Флаг ключа по умолчанию
data.createdAt string Время создания в ISO 8601
data.updatedAt string Время последнего обновления в ISO 8601

#Пример ответа

HTTP-статус 201 Created:

JSON
{
  "success": true,
  "data": {
    "id": "cred_abc123def456",
    "providerId": "openai",
    "provider": {
      "slug": "openai",
      "name": "OpenAI"
    },
    "name": "Мой личный OpenAI",
    "isDefault": true,
    "createdAt": "2026-04-27T11:30:00.000Z",
    "updatedAt": "2026-04-27T11:30:00.000Z"
  }
}

#Пример ответа при ошибке

422 credential_invalid — ключ не прошёл верификацию у провайдера:

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

409 already_exists — ключ для этого провайдера уже подключён:

JSON
{
  "success": false,
  "error": {
    "code": "already_exists",
    "message": "A credential for this provider already exists. Update the existing one instead."
  }
}

400 base_url_privatebaseUrl указывает на приватную сеть (защита от SSRF — Server-Side Request Forgery):

JSON
{
  "success": false,
  "error": {
    "code": "base_url_private",
    "message": "baseUrl points at a private network or fails DNS resolution"
  }
}

#Ошибки

HTTP Код Описание
400 invalid_request Нарушена схема body (нет обязательных полей)
400 no_key В credentials нет поля apiKey
400 base_url_invalid baseUrl использует не http/https или некорректен
400 base_url_private baseUrl указывает на приватную сеть или не разрешается в IP-адрес через DNS
404 provider_not_found Провайдер с таким providerId не существует или отключён
409 already_exists Ключ для этого провайдера уже подключён — используйте `PATCH /v1/ai/credentials/:id`
422 credential_invalid Ключ не прошёл верификацию у провайдера. Сообщение содержит детали от провайдера
403 scope_missing API-ключу не хватает скоупа vibe:ai

Полный список общих ошибок API — Ошибки.

Лимит создания ключей: 10 запросов в минуту.

#Известные особенности

Верификация перед сохранением. Ключ проверяется у провайдера через verify() — это HTTP-запрос к GET /v1/models или (если провайдер не поддерживает models) к POST /v1/chat/completions с минимальным телом. Тайм-аут проверки — 10 секунд. При некорректном ключе ничего не сохраняется в базе.

SSRF-защита для Custom-провайдера. baseUrl для custom-openai-compat обязательно проходит проверку: запрещены приватные сети (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 и ULA, IPv4-mapped IPv6. Принимаются только http:///https:// схемы.

Один ключ на провайдера. Эндпоинт не позволяет подключить второй ключ того же провайдера — вернёт 409. Для замены ключа используйте PATCH с тем же id.

Сообщение об ошибке очищено. Текст ошибки от провайдера обрезается до 200 символов, URL заменяются на плейсхолдер [URL] — это защищает от случайной утечки внутренних адресов в логах клиента.

#Смотрите также