До основного вмісту
ClubBase

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

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

Сервер вашого сайту створює заявку в потрібній студії та читає її стан. Ключ відкриває лише ту студію, яка його видала.

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

Де взяти ключ

  1. Увійдіть у CRM як власник або адміністраторІнші ролі ключів не бачать — це навмисно: ключ відкриває доступ до заявок усієї студії.
  2. Відкрийте «Налаштування → 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 і в який бік — розберемо ваш сценарій.

Написати команді