◆ Sapport для разработчиков Справочник API Каталог ошибок OpenAPI
Разделы

#Быстрый старт за 5 минут

Статус: серверный API (чтение, кошелёк, вебхуки) — Доступно; песочница и тестовые ключи — Планируется; виджет и загрузчик — Доступно. Шаги 1–4 относятся к серверному API и описывают целевое поведение. Шаг 5 (виджет) работает уже сейчас.

Цель страницы: выпустить ключ, выбрать адрес своей ячейки, проверить доступ вызовом GET /me, сделать первый полезный запрос и встроить чат одной строкой.

#Что понадобится

#Шаг 1. Выпустите ключ

  1. Войдите в кабинет своей ячейки.
  2. Откройте Настройки → API.
  3. Создайте интеграцию (служебную учётную запись) и выберите области. Для первого знакомства достаточно analytics:read.
  4. Задайте имя ключа, режим (live или test) и при необходимости список разрешённых IP.
  5. Скопируйте ключ. Он показывается один раз. Потерянный ключ не восстановить — только выпустить новый.

Ключ выглядит так (пример заведомо ненастоящий):

sap_ru_live_EXAMPLE0KEYID_EXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEX

Положите ключ в переменную окружения или хранилище секретов вашего сервера:

export SAPPORT_API_KEY='sap_ru_live_EXAMPLE0KEYID_…'

Подробно — Аутентификация.

Тестовые ключи (sap_<ячейка>_test_…) работают на песочнице ячейки. Песочница — Планируется.

#Шаг 2. Выберите адрес своей ячейки

Ключ действует только в той ячейке, где выпущен.

ЯчейкаБазовый адрес
RUhttps://formula-cream.pro/api/public/v1
ENhttps://wfacademy.org/api/public/v1
IDhttps://wfacademy.id/api/public/v1
export SAPPORT_BASE_URL='https://formula-cream.pro/api/public/v1'

Ключ RU на адресе EN вернёт 401 wrong_cell с полем correct_base_url — правильным адресом. См. Ячейки и данные.

#Шаг 3. Проверьте ключ вызовом GET /me

GET /me не требует областей и не стоит денег. Он возвращает арендатора, ячейку, интеграцию, сведения о ключе (области, срок, список IP), пределы, состояние кошелька и режим CRM.

#curl

curl -sS "$SAPPORT_BASE_URL/me" \
  -H "Authorization: Bearer $SAPPORT_API_KEY"

#JavaScript (Node.js 18+, fetch)

const res = await fetch(`${process.env.SAPPORT_BASE_URL}/me`, {
  headers: { Authorization: `Bearer ${process.env.SAPPORT_API_KEY}` },
});

if (!res.ok) {
  const problem = await res.json(); // application/problem+json
  throw new Error(`${problem.code}: ${problem.detail} (request ${problem.request_id})`);
}

console.log(await res.json());

#Python (httpx)

import os
import httpx

resp = httpx.get(
    f"{os.environ['SAPPORT_BASE_URL']}/me",
    headers={"Authorization": f"Bearer {os.environ['SAPPORT_API_KEY']}"},
    timeout=10,
)
if resp.status_code != 200:
    problem = resp.json()
    raise RuntimeError(f"{problem['code']}: {problem['detail']} (request {problem['request_id']})")

print(resp.json())

#PHP (cURL)

<?php
$ch = curl_init(getenv('SAPPORT_BASE_URL') . '/me');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . getenv('SAPPORT_API_KEY')],
    CURLOPT_TIMEOUT        => 10,
]);
$body   = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

if ($status !== 200) {
    $problem = json_decode($body, true);
    throw new RuntimeException($problem['code'] . ': ' . $problem['detail']);
}
print_r(json_decode($body, true));

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

Значения иллюстративны, структура фиксирована.

{
  "tenant": { "id": "3f0c9a52-0000-4000-8000-000000000001", "name": "Пример-студия" },
  "cell": "ru",
  "base_url": "https://formula-cream.pro/api/public/v1",
  "integration": { "id": "int_EXAMPLE01", "name": "Моя CRM" },
  "key": {
    "key_id": "EXAMPLE0KEYID",
    "mode": "live",
    "scopes": ["analytics:read"],
    "expires_at": "2027-10-11T00:00:00Z",
    "ip_allowlist": []
  },
  "limits": {
    "read_per_min": 600,
    "write_per_min": 120,
    "paid_per_min": 30,
    "paid_concurrency": 5
  },
  "wallet": {
    "balance": { "amount": "1500.00", "currency": "RUB" },
    "state": "ok",
    "exchange": "active",
    "topup_url": "https://formula-cream.pro/ru/promo/economics#wallet",
    "daily_spend": { "used": { "amount": "0.00", "currency": "RUB" }, "limit": { "amount": "500.00", "currency": "RUB" } }
  },
  "crm_mode": "internal",
  "channel_id": "00000000-0000-4000-8000-000000000000"
}

Поле wallet.exchange показывает, идёт ли обмен: при suspended (отрицательный баланс) остальные маршруты отвечают 402 wallet_suspended — см. Кошелёк и остановка обмена.

Поле channel_id — идентификатор канала api, созданного вместе с интеграцией; нужно, если вы ведёте собственный канал через ИИ-продажника.

Если вместо этого пришёл problem+json, найдите код в каталоге ошибок. Чаще всего это invalid_api_key (опечатка, ключ отозван или истёк), wrong_cell (не тот адрес) или ip_not_allowed (запрос с адреса вне списка).

#Шаг 4. Первый полезный вызов — источники трафика

Область analytics:read, не платно, ПДн нет.

curl -sS "$SAPPORT_BASE_URL/analytics/traffic-sources?from=2026-10-01&to=2026-10-07" \
  -H "Authorization: Bearer $SAPPORT_API_KEY"

Пример ответа (иллюстративный):

{
  "data": [
    { "source": "google", "kind": "search", "sessions": 1280, "visitors": 1104, "leads": 14 },
    { "source": "chatgpt", "kind": "ai_assistant", "sessions": 212, "visitors": 190, "leads": 5 },
    { "source": "social", "kind": "social", "sessions": 96, "visitors": 88, "leads": 1 }
  ],
  "data_as_of": { "tracker": "2026-10-07" }
}

Обратите внимание на data_as_of: данные внешних источников (например, поисковой консоли) приходят с задержкой, и платформа честно сообщает, на какой момент актуален каждый источник. Ряды по дням добавляются параметром include=series. Параметры и метрики — Чтение аналитики.

Другие запросы тем же ключом — README.

#Шаг 5. Подключите виджет чата одной строкой

Это уже работает. Секретный ключ для виджета не нужен — используется открытый идентификатор канала.

  1. В кабинете создайте канал «Веб-чат» и скопируйте его идентификатор (UUID).
  2. Вставьте перед </body> на странице вашего сайта:
<script src="https://formula-cream.pro/widget.js" data-channel="00000000-0000-4000-8000-000000000000"></script>

Замените домен на домен своей ячейки (wfacademy.org для EN, wfacademy.id для ID) и UUID на свой.

Необязательные параметры в теге: data-position (bottom-right или bottom-left), data-theme (light по умолчанию), data-bubble-text, data-delay (секунды).

Чтобы окно чата открылось, домен вашего сайта должен быть указан в настройках арендатора либо сайт должен быть привязан через модуль CMS: платформа разрешает встраивание только на такие домены. Без этого кнопка видна, а окно блокируется браузером.

Подробнее — Встраивание виджета. Если нужен и сбор аналитики одной строкой — загрузчик: Загрузчик.

#Что дальше

ХочуСтраница
Разобраться в ключах, областях и ротацииАутентификация
Знать формат ошибок, пагинацию, повторыСоглашения
Получать события в реальном времениВебхуки
Вести свой канал через ИИ-продажникаСвой канал
Подключить внешнюю CRMРежимы CRM