К основному содержимому
ClubBase

Публичный API · версия 1.0.0

Заявки с вашего сайта — сразу в CRM

Сервер вашего сайта создаёт заявку в нужной студии и читает её состояние. Ключ открывает только ту студию, которая его выдала.

Адресhttps://api.clubbase.fit

Где взять ключ

  1. Войдите в CRM как владелец или администраторДругие роли ключей не видят, и это намеренно: ключ открывает доступ к заявкам всей студии.
  2. Откройте Настройки → API и интеграции («Налаштування → API та інтеграції»)Это в левом меню CRM, в разделе с шестерёнкой.
  3. Нажмите Создать ключ («Створити ключ») и задайте название, срок и праваПрава отдельные: leads.read — читать заявки, leads.create — создавать. Берите только то, что действительно нужно вашей интеграции.
  4. Скопируйте секрет сразуClubBase показывает его ровно один раз. Потеряли — создайте новый, старый отзовите.
  5. Положите секрет в переменные окружения сервераНе в код страницы и не в запрос из браузера посетителя: ключ даёт доступ ко всем заявкам студии.

В студии может быть до 20 ключей, срок действия нового — до 366 дней. Замена сразу отключает предыдущий секрет; отзыв окончательный. Cookie входа в CRM ключ не заменяет.

Открыть свою CRM

Первый запрос

Ключ передаётся заголовком Authorization: Bearer …. Для создания заявки нужен ещё Idempotency-Key — любой UUID, который вы храните вместе с заявкой.

Создать заявку · curl
curl -X POST https://api.clubbase.fit/v1/integrations/leads \
  -H "Authorization: Bearer $CLUBBASE_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen | tr 'A-Z' 'a-z')" \
  -d '{
    "displayName": "Пример API",
    "contact": {
      "type": "email",
      "value": "[email protected]"
    },
    "sourceId": null,
    "note": "Контрольная заявка интеграции"
  }'
Создать заявку · Node.js
import { randomUUID } from 'node:crypto';

// Ключ берётся из переменных окружения, никогда из кода страницы.
const response = await fetch('https://api.clubbase.fit/v1/integrations/leads', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.CLUBBASE_API_KEY}`,
    'Content-Type': 'application/json',
    // Повтор с тем же ключом вернёт ту же заявку, а не вторую.
    'Idempotency-Key': randomUUID(),
  },
  body: JSON.stringify({
    "displayName": "Пример API",
    "contact": {
      "type": "email",
      "value": "[email protected]"
    },
    "sourceId": null,
    "note": "Контрольная заявка интеграции"
  }),
});

if (!response.ok) {
  const problem = await response.json();
  throw new Error(`${problem.status} ${problem.code}: ${problem.detail}`);
}

const lead = await response.json();
Создать заявку · PHP
<?php
// Ключ читается из окружения сервера, а не из кода страницы.
// Idempotency-Key должен быть именно UUID: 32 hex-символа без дефисов API отклонит.
$bytes = random_bytes(16);
$bytes[6] = chr(ord($bytes[6]) & 0x0f | 0x40);
$bytes[8] = chr(ord($bytes[8]) & 0x3f | 0x80);
$idempotencyKey = vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($bytes), 4));

$ch = curl_init('https://api.clubbase.fit/v1/integrations/leads');
curl_setopt_array($ch, [
  CURLOPT_POST => true,
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => [
    'Authorization: Bearer ' . getenv('CLUBBASE_API_KEY'),
    'Content-Type: application/json',
    'Idempotency-Key: ' . $idempotencyKey,
  ],
  CURLOPT_POSTFIELDS => json_encode([
    'displayName' => "Пример API",
    'contact' => [
      'type' => "email",
      'value' => "[email protected]",
    ],
    'note' => "Контрольная заявка интеграции",
  ], JSON_UNESCAPED_UNICODE),
]);
$response = curl_exec($ch);

Успех возвращает 201 и тело заявки с её идентификатором. Повтор того же Idempotency-Key вернёт ту же заявку, а не вторую.

Методы

POST/v1/integrations/leads

Создать заявку

Передаёт имя и контакт в текущую студию. Idempotency-Key защищает повтор после потерянного ответа.

Нужное право: leads.create

GET/v1/integrations/leads/{id}

Прочитать заявку

Возвращает разрешённые поля одной заявки. Чужой или неизвестный ID возвращает 404.

Нужное право: leads.read

GET/v1/integrations/leads

Список заявок

Читает заявки постранично. Значение nextCursor передайте в следующий запрос без изменений.

Нужное право: leads.read

Список заявок · curl
curl "https://api.clubbase.fit/v1/integrations/leads?limit=20" \
  -H "Authorization: Bearer $CLUBBASE_API_KEY"
Одна заявка · curl
curl https://api.clubbase.fit/v1/integrations/leads/$LEAD_ID \
  -H "Authorization: Bearer $CLUBBASE_API_KEY"

Список отдаётся страницами. limit — от 1 до 100, по умолчанию 25. Ответ содержит nextCursor: передайте его в следующий запрос параметром cursor без изменений. nextCursor: null значит, что страниц больше нет.

Повтор запроса

Сеть обрывает ответ чаще, чем кажется. Если вы не дождались ответа, повторите тот же запрос с тем же Idempotency-Key: ClubBase вернёт исходный результат и не создаст вторую заявку.

Тот же ключ с другим телом — это ошибка 409 integration_idempotency_conflict: так видно, что где-то потерялось состояние, и дубль не создаётся молча.

Если запустить пример дважды с новым Idempotency-Key и тем же контактом, ответ будет 409 integration_lead_already_open. Это не ошибка интеграции: в студии уже есть открытая заявка от этого человека, и ClubBase не заводит вторую. Чтобы проверить повтор, меняйте ключ вместе с контактом, а не по отдельности.

Ошибки

Ответ с ошибкой — application/problem+json с полями status, code, detail.

КодИдентификаторКогда возникает
400integration_invalid_requestНеизвестное поле, неверный контакт или cursor либо нет UUID в Idempotency-Key.
401integration_key_invalidКлюч не передан, отозван, заменён или срок его действия истёк.
402subscription_suspendedДоступ к студии приостановлен.
403integration_scope_forbiddenКлюч не разрешает эту операцию.
403integration_issuer_forbiddenТекущие права того, кто выдал ключ, больше не разрешают интеграцию.
404integration_lead_not_foundЗаявка недоступна в студии этого ключа.
409integration_idempotency_conflictТот же Idempotency-Key использован с другими данными.
409integration_lead_already_openУ контакта уже есть открытая заявка.
400integration_source_invalidИсточник заявки не принадлежит этой студии или отключён.
429integration_rate_limitedПодождите столько секунд, сколько указано в Retry-After.
503integration_rate_unavailableПроверка квоты временно недоступна; запись не выполнена.

429 приходит с заголовком Retry-After — это количество секунд до следующей попытки. Соблюдайте его: иначе следующий ответ будет таким же.

Нужен другой метод?

Опишите, что должно передаваться в ClubBase и в какую сторону, — разберём ваш сценарий.

Написать команде