Внешний API
Для клиентов, которым нужно читать и загружать данные в CRM извне — скриптом, ETL-процессом, другой системой, без браузера и без ручного логина. Ниже — реально работающий, проверенный функционал; известные ограничения перечислены в конце страницы.
Во всех примерах <slug> — адрес вашей CRM (https://<slug>.prohor.tech, либо ваш white-label домен).
1. Авторизация
API-ключ (рекомендуется для интеграций)
Ключи создаются в интерфейсе — Настройки CRM → API-ключи, кнопка «Создать ключ» (нужно право «Пользователи», manageUsers). Секрет вида pcrm_... показывается один раз, в момент создания — его нужно сразу сохранить на стороне интеграции.
Ключ передаётся заголовком в каждом запросе (оба варианта равнозначны):
bash
curl https://<slug>.prohor.tech/api/tenants/<slug> \
-H "Authorization: Bearer pcrm_...секрет..."bash
curl https://<slug>.prohor.tech/api/tenants/<slug> \
-H "X-Api-Key: pcrm_...секрет..."Запрос с ключом полностью эквивалентен запросу от залогиненного пользователя: те же права и ограничения группы доступа, к которой привязан ключ (включая ограничение видимых записей, если оно настроено для группы).
Логин + JWT (для браузерных сессий)
Это способ, которым авторизуется сам веб-интерфейс CRM; для серверных интеграций проще и надёжнее API-ключ выше — он не требует продлевать токен каждые 15 минут.
bash
curl -X POST https://<slug>.prohor.tech/api/auth/login \
-H "Content-Type: application/json" \
-c cookies.txt \
-d '{"email": "user@example.com", "password": "..."}'Сервер выставляет access_token (JWT, 15 минут) и refresh_token (30 дней) как httpOnly cookie; продлить access_token без повторного логина — POST /api/auth/refresh. JWT можно передавать и явным заголовком Authorization: Bearer <access_token> вместо cookie.
2. Получение данных
Список каталогов (таблиц) с их полями — GET /api/tenants/<slug>/catalogs. Понадобится, чтобы знать field.id и field.type для чтения/записи значений.
Список записей каталога, с пагинацией/поиском/фильтрами/сортировкой:
bash
curl "https://<slug>.prohor.tech/api/tenants/<slug>/catalogs/<catalogId>/records?page=1&page_size=50&sort_field=created_at&sort_dir=desc" \
-H "X-Api-Key: pcrm_..."| Параметр | Описание |
|---|---|
search | полнотекстовый поиск по записям |
sort_field, sort_dir | sort_dir — asc/desc |
page, page_size | пагинация |
filter_logic | AND или OR (заглавными) |
filter[0][field], filter[0][op], filter[0][value] | условие фильтра; индекс 0,1,2... для нескольких условий; op — eq, neq, contains, gt, lt и др. |
Также доступны: точечное чтение по id (.../records/by-ids?ids=...), список id, подпадающих под фильтр (.../records/ids?...), и агрегаты — группировка + сумма/среднее/количество (.../records/aggregate?groupBy=...&aggFunc=sum&aggField=...).
3. Создание, изменение, удаление записей
values — объект { "<fieldId>": <значение> }, где ключи — это id полей каталога, не их названия.
bash
curl -X POST https://<slug>.prohor.tech/api/tenants/<slug>/catalogs/<catalogId>/records \
-H "Content-Type: application/json" -H "X-Api-Key: pcrm_..." \
-d '{"values": {"<fieldId>": "Новая заявка №128"}}'bash
curl -X PATCH https://<slug>.prohor.tech/api/tenants/<slug>/catalogs/<catalogId>/records/<recordId> \
-H "Content-Type: application/json" -H "X-Api-Key: pcrm_..." \
-d '{"values": {"<fieldId_статус>": "В работе"}}'bash
curl -X DELETE https://<slug>.prohor.tech/api/tenants/<slug>/catalogs/<catalogId>/records/<recordId> \
-H "X-Api-Key: pcrm_..."Поля-связи и поля-пользователи
В values кладётся id целевой записи/пользователя (или JSON-массив id для мульти-значения), а не отображаемое название/имя — названия сервер сам подставляет только при чтении.
Массовые операции — для записей, уже существующих в CRM (не для создания пачки новых): массовое удаление (DELETE .../records с {"ids": [...]}) и массовое изменение одного поля (PATCH .../records/bulk-update с {"ids": [...], "field_id": "...", "value": "..."}).
4. Формат ошибок
| Статус | Когда |
|---|---|
| 200 / 204 | успех (204 — без тела, например отзыв ключа) |
| 400 | некорректный запрос |
| 401 | не авторизован (нет/невалиден токен, ключ отозван) |
| 403 | не хватает прав |
| 404 | не найдено (в т.ч. если запись недоступна по ограничению видимости группы — сервер не различает «не существует» и «нет доступа») |
json
{"error": {"message": "Unknown access group.", "details": null}}5. Известные ограничения
Это сознательно отложенный функционал, не баг:
- Нет bulk-эндпоинта для загрузки множества новых записей за один запрос — загрузка сегодня идёт по одной записи (
POST .../records) на цикл. - Нет upsert по внешнему ключу. Чтобы не создавать дубли, интеграция должна сама сопоставлять «внешний ID → id записи в CRM» (например, хранить его в отдельном поле и перед созданием проверять фильтром по этому полю).
- Один запрос — одна запись, без атомарного создания нескольких связанных записей за раз.
6. Полная спецификация (Swagger)
Интерактивная документация и актуальная OpenAPI-спецификация доступны по адресу /openapi.json (и /docs) на адресе вашей CRM.