API Reference

Base URL: https://wocrm.ru/api/v1  ·  Версия: v1

Аутентификация #

Все запросы к API требуют заголовок Authorization с Bearer-токеном организации. Ключи создаются в настройках организации и привязаны к ней (не к пользователю).

Authorization: Bearer wocrm_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Полный токен показывается только при создании. WOCRM хранит только SHA-256-хеш — восстановить токен невозможно. При компрометации — создайте новый и отзовите старый.
ПолеЗначение
СхемаBearer
ЗаголовокAuthorization
Форматwocrm_live_ + 40 случайных символов
ХранениеSHA-256 хеш на сервере
ОтзывНемедленный — через настройки организации

Идемпотентность #

Передайте заголовок Idempotency-Key для защиты от дублей при повторных запросах (сетевой таймаут, retry в очереди).

Idempotency-Key: site-form-{{userId}}-{{timestamp}}
ПравилоЗначение
Максимальная длина255 символов
Область видимостиОрганизация — ключи уникальны в рамках одной организации
Время хранения72 часа с момента первого запроса
При повтореHTTP 200 + "idempotent_replay": true

Списки и пагинация #

Коллекции возвращаются постранично. Все GET-эндпоинты списков отдают единый конверт { ok, data, meta }.

GET-эндпоинты

МетодПутьОписание
GET/api/v1/leadsЛиды. Фильтры: status, assigned_to, search
GET/api/v1/leads/{id}Один лид
GET/api/v1/contactsКонтакты. Фильтр: search
GET/api/v1/contacts/{id}Один контакт
GET/api/v1/dealsСделки. Фильтры: status, assigned_to
GET/api/v1/deals/{id}Одна сделка
GET/api/v1/appointmentsОнлайн-записи. Фильтры: status, from, to
GET/api/v1/appointments/{id}Одна запись

Параметры пагинации

ПараметрТипПо умолчаниюОписание
per_pageinteger25Размер страницы, максимум 100
pageinteger1Номер страницы

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

{
  "ok": true,
  "data": [ { "id": 12, "name": "Иван", "status": "new" } ],
  "meta": { "total": 240, "per_page": 25, "current_page": 1, "last_page": 10 }
}
Персональные данные (имя, телефон, email) зашифрованы. Поиск по ним — точный, через параметр search (по слепому индексу), а не по подстроке.

POST /api/v1/leads #

Также доступны PATCH /api/v1/leads/{id} (изменение — поля как ниже, все необязательны) и DELETE /api/v1/leads/{id} (удаление).

Создаёт входящий лид в организации. Если указан Idempotency-Key и лид с таким ключом уже существует — возвращает его без создания дубля.

Заголовки

ЗаголовокОбяз.Описание
AuthorizationдаBearer {token}
Content-Typeдаapplication/json
Idempotency-KeyнетКлюч для защиты от дублей (≤ 255 символов)

Поля тела (JSON)

ПолеТипОбяз.Макс.Описание
namestringда255Имя лида
phonestringнет64Телефон
emailstringнет255Email
messagestringнет8192Сообщение / комментарий
sourcestringнет64Источник (landing, vk, site и т.д.)

Пример запроса

curl -X POST https://wocrm.ru/api/v1/leads \
  -H "Authorization: Bearer wocrm_live_xxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: my-form-1234567890" \
  -d '{
    "name": "Иван Петров",
    "phone": "+7 999 123-45-67",
    "email": "ivan@example.com",
    "source": "landing_page",
    "message": "Хочу записаться на консультацию"
  }'

Ответы

КодСитуацияТело ответа
201 Лид создан {"ok":true,"lead_id":1042}
200 Идемпотентный повтор {"ok":true,"lead_id":1042,"idempotent_replay":true}
422 Ошибка валидации {"ok":false,"error":"validation_failed","errors":{...}}
422 Квота лидов исчерпана {"ok":false,"error":"lead_quota_exceeded","message":"..."}
401 Неверный токен {"ok":false,"error":"unauthorized"}

Онлайн-записи (appointments) #

Создание и чтение записей на встречу/услугу — для внешних систем бронирования и виджетов.

GET /api/v1/appointments

Список записей. Фильтры: status, from (дата с), to (дата по), пагинация per_page.

curl "https://wocrm.ru/api/v1/appointments?from=2026-07-01&per_page=50" \
  -H "Authorization: Bearer <org_api_key>"

POST /api/v1/appointments

ПолеТипОбяз.Описание
client_namestringдаИмя клиента
scheduled_atdatetimeдаДата и время (ISO 8601)
client_phonestringнетТелефон
client_emailstringнетEmail
duration_minutesintegerнетДлительность, мин (по умолчанию 30)
typestringнетТип записи
statusstringнетСтатус (по умолчанию scheduled)
notesstringнетЗаметки
deal_idintegerнетПривязка к сделке (в вашей организации)
curl -X POST https://wocrm.ru/api/v1/appointments \
  -H "Authorization: Bearer <org_api_key>" \
  -H "Content-Type: application/json" \
  -d '{"client_name":"Иван","scheduled_at":"2026-07-15T14:00:00","duration_minutes":60}'

Ответ 201: { "ok": true, "data": { "id": 88, ... } }

Contacts — создание, изменение, удаление #

POST /api/v1/contacts   PATCH /api/v1/contacts/{id}   DELETE /api/v1/contacts/{id}

ПолеТипОбяз. (POST)Описание
namestringдаИмя (до 255)
phonestringнетТелефон (до 64)
emailstringнетEmail
companystringнетКомпания
positionstringнетДолжность
citystringнетГород
notesstringнетЗаметки

При PATCH любое поле необязательно (обновляются только переданные). DELETE удаляет контакт организации.

curl -X POST https://wocrm.ru/api/v1/contacts \
  -H "Authorization: Bearer <org_api_key>" -H "Content-Type: application/json" \
  -d '{"name":"Иван Петров","phone":"+79990001122","email":"ivan@mail.ru"}'

Deals — создание и изменение #

POST /api/v1/deals   PATCH /api/v1/deals/{id}

ПолеТипОбяз. (POST)Описание
titlestringдаНазвание сделки
amountnumberнетСумма (≥ 0)
statusstringнетОдно из: open, won, lost
prioritystringнетОдно из: low, medium, high
lead_idintegerнетПривязка к лиду (только POST)
notesstringнетЗаметки

При PATCH все поля необязательны. Удаление сделок через API не предусмотрено.

GET /api/v1/openapi.yaml #

Возвращает машиночитаемую спецификацию OpenAPI 3.0 (YAML) по всем эндпоинтам v1: leads, contacts, deals, appointments — со схемами, параметрами и кодами ответов. Не требует авторизации.

curl https://wocrm.ru/api/v1/openapi.yaml
Импортируйте файл в Postman, Insomnia или генератор клиентов (openapi-generator) — получите готовый SDK и коллекцию запросов.

Импорт в Postman / генерация SDK #

Postman — популярный бесплатный инструмент для работы с API. По нашей OpenAPI-спеке он за минуту создаёт готовую коллекцию всех запросов.

Импорт коллекции в Postman

  1. Откройте Postman → Import → вкладка Link.
  2. Вставьте ссылку на спеку и нажмите Continue → Import:
https://wocrm.ru/api/v1/openapi.yaml
  1. В настройках коллекции → Authorization → тип Bearer Token → вставьте ключ организации из настроек API.
  2. Готово — можно отправлять запросы к leads, contacts, deals, appointments.
Ту же ссылку понимают Insomnia, Hoppscotch и Swagger UI. Для генерации готового клиента (PHP, Python, JS, Go и др.) используйте openapi-generator или swagger-codegen с этим же файлом.

Быстрый старт через curl

# список лидов
curl "https://wocrm.ru/api/v1/leads?per_page=10" \
  -H "Authorization: Bearer <ваш_ключ>"

Коды ошибок #

HTTPerrorПричина
400invalid_jsonТело запроса не является валидным JSON
401unauthorizedТокен отсутствует, неверен или отозван
403forbiddenНет прав для данной операции
404not_foundРесурс не существует
422validation_failedНе переданы обязательные поля или нарушены ограничения
422lead_quota_exceededДостигнут лимит лидов по тарифу
422invalid_idempotency_keyIdempotency-Key длиннее 255 символов
429too_many_requestsПревышен rate limit — ожидайте Retry-After секунд
500server_errorВнутренняя ошибка — обратитесь в поддержку

Rate limits #

600
запросов / минуту
HTTP 429
при превышении
Retry-After
заголовок с задержкой
По токену
лимит на организацию

Формат webhook-запроса #

WOCRM отправляет POST на ваш URL с JSON-телом:

{
  "event": "lead.created",
  "sent_at": "2026-01-01T12:00:00+00:00",
  "organization_id": 7,
  "data": { ... }         // зависит от события
}
Ваш эндпоинт должен вернуть HTTP 2xx в течение 30 секунд. Иначе доставка будет повторена по расписанию.

Заголовки webhook #

ЗаголовокПримерОписание
Content-Typeapplication/jsonТело всегда JSON
X-Wocrm-Eventlead.createdТип события
X-Wocrm-Signaturesha256=abc123…HMAC-SHA256 тела запроса
X-Wocrm-Deliveryuuid-v4Уникальный ID доставки
User-AgentWOCRM-Webhook/1.0Идентификатор отправителя

Проверка подписи #

Заголовок X-Wocrm-Signature: sha256=<hex> содержит HMAC-SHA256 от сырого тела запроса, подписанный секретом webhook-эндпоинта.

Всегда проверяйте подпись перед обработкой. Используйте сравнение в постоянное время (hash_equals).

PHP (Laravel)

$secret  = config('services.wocrm_webhook_secret');
$payload = $request->getContent();   // raw body — до json_decode
$sig     = 'sha256=' . hash_hmac('sha256', $payload, $secret);

if (! hash_equals($sig, $request->header('X-Wocrm-Signature', ''))) {
    abort(401, 'Invalid signature');
}

Node.js (Express)

const crypto = require('crypto');

app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
    const sig = 'sha256=' + crypto
        .createHmac('sha256', process.env.WOCRM_SECRET)
        .update(req.body)   // Buffer — raw body
        .digest('hex');

    if (!crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(req.headers['x-wocrm-signature'] || ''))) {
        return res.sendStatus(401);
    }
    // ...
});

Python (Flask)

import hmac, hashlib

@app.route('/webhook', methods=['POST'])
def webhook():
    secret = os.environ['WOCRM_SECRET'].encode()
    sig = 'sha256=' + hmac.new(secret, request.data, hashlib.sha256).hexdigest()
    if not hmac.compare_digest(sig, request.headers.get('X-Wocrm-Signature', '')):
        abort(401)
    # ...

Retry-политика #

При неуспешной доставке (не 2xx, или таймаут 30 сек) WOCRM повторяет по расписанию:

ПопыткаЗадержка
1-я (первичная)немедленно
2-я+10 сек
3-я+60 сек
4-я+5 мин
5-я (последняя)+30 мин
4xx (кроме 408, 425, 429) считаются финальными — повторов не будет. 5xx и сетевые ошибки всегда ретраятся.

События: lead.* #

Это события webhooks — CRM сама отправляет их POST-запросом на ваш URL при изменениях. Не путать с REST-эндпоинтами (раздел «Endpoints»), которые вызываете вы. Подключаются в настройках API.

lead.created — новый лид

// data:
{
  "lead_id": 1042,
  "lead": {
    "id": 1042, "name": "Иван Петров", "email": "ivan@example.com",
    "phone": "+7 999 123-45-67", "status": "new", "priority": null,
    "assigned_to": null, "source_id": null,
    "last_channel": "api", "created_at": "2026-01-01T12:00:00+00:00"
  }
}

lead.status_changed

// data:
{
  "lead_id": 1042,
  "old_status": "new",
  "new_status": "in_progress",
  "lead": { /* объект лида */ }
}

Статусы: new · in_progress · converted · lost · closed

lead.assigned

// data:
{
  "lead_id": 1042,
  "assigned_to": 5,   // ID пользователя или null
  "lead": { /* объект лида */ }
}

lead.idle — лид не обрабатывается 30+ дней

// data:
{
  "lead_id": 1042
}
// Срабатывает 1 раз в сутки по расписанию (cron)

События: deal.* #

deal.created

// data:
{
  "deal_id": 10,
  "deal": {
    "id": 10, "title": "Проект X", "amount": 150000.00,
    "status": "open", "funnel_id": 1, "funnel_stage_id": 3,
    "contact_id": 7, "lead_id": 1042, "assigned_to": 5,
    "created_at": "2026-01-01T12:00:00+00:00"
  }
}

deal.stage_changed

// data:
{
  "deal_id": 10,
  "lead_id": 1042,
  "funnel_stage_id": 4,
  "previous_funnel_stage_id": 3
}

deal.won

// data:
{ "deal_id": 10, "lead_id": 1042, "contact_id": 7, "amount": 150000.00 }

deal.lost

// data:
{ "deal_id": 10, "lead_id": 1042, "contact_id": 7 }

События: message.* #

message.received / message.sent

// data (поля зависят от канала):
{
  "lead_id": 1042,
  "channel": "telegram",   // telegram | vk | whatsapp | api | ...
  "direction": "in",        // in | out
  "text": "Здравствуйте!",
  "message_id": "tg_123456789"
}

События: contact.* #

contact.created

// data:
{ "contact_id": 7, "lead_id": 1042 }

contact.churn_risk — риск оттока

// data:
{
  "contact_id": 7,
  "health_score": 28   // <= 35 — риск оттока
}
// Срабатывает не чаще 1 раза в 7 дней на контакт

События: invoice.* #

invoice.status_changed

// data:
{
  "invoice_id": 55,
  "lead_id": 1042,
  "old_status": "pending",
  "new_status": "paid"
}
WOCRM API v1 · Управление ключами Задать вопрос в поддержку