#Оценка лидов
Статус: чтение оценки в объекте лида (
GET /leads) — Доступно; вызов и запись оценки через API — Планируется; оценка внутри платформы — работает. Лид уже оценивается внутри платформы; вызвать оценку или записать свою через API нельзя. Классgradeи сохранениеreasonв текущей реализации отсутствуют: они появятся вместе с публичным API (см. «Заметки»). Сроки не обещаются.
Оценка отвечает на вопрос «насколько этот лид похож на покупателя». Модель читает недавнюю переписку и ставит число от 0 до 100; параллельно отдельный разбор выставляет флаги (хочет купить, пишет в поддержку, это поставщик). Оценка помогает менеджеру расставить приоритеты и позволяет автоматике отсеять нецелевые обращения.
Доступ: leads:read — прочитать оценку в составе лида; leads:score — запросить оценку нашей моделью; leads:write — записать оценку внешней CRM. Платно: POST /leads/{id}/score — да, списание с кошелька арендатора; PUT /leads/{id}/score — нет. ПДн: нет в самом ответе; оценка строится по переписке с маскировкой ПДн.
#Что получается на выходе
| Поле | Тип | Описание |
|---|---|---|
score | integer | Балл 0–100 |
grade | string | Класс лида, вычисляется из score: A — 75 и выше, B — 50–74, C — 25–49, D — ниже 25 |
reason | string | Краткое обоснование, до 500 знаков. Сохраняется вместе с оценкой |
flags | object | Флаги buy_intent, support, supplier |
model | string | Модель, поставившая оценку |
scored_at | string (ISO 8601) | Когда поставлена |
source | string | Источник оценки: ai — наша модель, external — внешняя CRM, manual — ручная оценка в кабинете |
#Флаги
Каждый флаг принимает одно из трёх значений: true, false, null.
| Флаг | Смысл |
|---|---|
buy_intent | Человек хочет купить |
support | Это обращение в поддержку, а не новый клиент |
supplier | Это поставщик или рассылка, не клиент |
null означает «не уверены». Разбор даёт вероятность, а флаг ставится, только когда она не меньше 0,8 (true) или не больше 0,2 (false); между этими значениями флага нет. Эта полоса выбрана потому, что именно в ней точность разбора была измерена.
#Как оценка влияет на лид
- Если модель уверенно определила
supplier = true, балл ограничивается значением 10, а лид уходит в архив с причинойai_not_client. Лид не удаляется: архивные лиды можно просмотреть и вернуть. - Статус лида оценка автоматически не меняет. Исключение — кнопка «Оценить» в кабинете, которая двигает статус только вперёд: до 20 баллов
new, до 50qualified, до 70proposal, вышеnegotiation. Будет ли так же вести себяPOST /leads/{id}/score, в проекте не определено (см. «Открытые вопросы»). - В режиме
externalпосле принятия лида наши агенты статус не меняют вообще; изменение предлагается запросом действия (см. Действия агентов).
#Что видит модель
Модель получает последние 10 сообщений диалога, без внутренних заметок персонала. Перед отправкой в модель из текста удаляются персональные данные: телефон, почта, номер карты, аккаунты мессенджеров, паспорт, СНИЛС, ИНН, имена, адреса заменяются заглушками. Если у лида нет диалога или в нём нет сообщений, оценка невозможна.
Поставщики моделей получают обработанный текст. Подробнее — Передача ПДн.
#Когда лид оценивается сам
Автоматическая оценка запускается в таких случаях:
- сработало правило автоматизации «оценить лид»;
- лид пришёл с сайта или из бота и ИИ ответил в диалоге (на сегодня — только площадка Формула ИИ);
- менеджер нажал «Оценить» в кабинете;
- агент-связыватель CRM после очередного ответа перепроверил лид.
Для лидов, созданных через POST /leads без диалога, автоматическая оценка недоступна; такие лиды можно оценить только внешней оценкой (PUT).
#POST /leads/{id}/score
Запускает оценку нашей моделью.
Заголовки: Authorization, Idempotency-Key (обязателен: платная операция). Параметры: тело не требуется.
Операция выполняется синхронно, за секунды (у модели таймаут 20 секунд), и в конверт operation не оборачивается (Соглашения). Повторный запрос с тем же Idempotency-Key деньги второй раз не списывает.
Ответ 200 OK:
{
"lead_id": "5d1b2c7e-3f0a-4a8e-9a3b-1c2d3e4f5a6b",
"score": 72,
"grade": "B",
"reason": "Клиент уточнил сроки старта и спросил о рассрочке.",
"flags": { "buy_intent": true, "support": false, "supplier": false },
"model": "model-EXAMPLE",
"scored_at": "2026-10-11T09:45:12Z",
"source": "ai",
"usage": {
"cost": { "amount": "0.12", "currency": "RUB" },
"model": "model-EXAMPLE"
}
}
Поле usage соответствует принципу «деньги видимы»: стоимость операции возвращается в ответе строкой в валюте кошелька арендатора. Тестовые ключи деньги не списывают. Размер стоимости в проекте не зафиксирован.
Возможные отказы. Внутренние причины сегодняшней оценки сопоставлены кодам каталога; соответствие предварительное.
| Причина | Код | HTTP |
|---|---|---|
lead_not_found | not_found | 404 |
conversation_not_found, no_messages | invalid_state | 409 |
no_key | insufficient_funds | 402 |
model_failed, output_rejected, parse_failed | upstream_unavailable | 503 |
write_failed | service_unavailable | 503 |
Превышение предела трат, предела одновременных платных операций (5 на арендатора) или максимума стоимости одной операции (эквивалент 100 ₽) — 402 spend_limit_reached. Ошибки 503 повторяйте с тем же Idempotency-Key.
#Примеры
curl -X POST https://formula-cream.pro/api/public/v1/leads/$LEAD_ID/score \
-H "Authorization: Bearer $API_KEY" \
-H "Idempotency-Key: 9b2d7a54-1f3c-4e8a-b6d0-5c7a2e9f1b30"
# API_KEY=sap_ru_test_EXAMPLE0KEYID_… (пример, не настоящий ключ)
const res = await fetch(
`https://formula-cream.pro/api/public/v1/leads/${leadId}/score`,
{
method: "POST",
headers: {
Authorization: `Bearer ${process.env.API_KEY}`,
"Idempotency-Key": crypto.randomUUID(),
},
},
);
if (res.status === 402) throw new Error("Пополните кошелёк");
const result = await res.json();
r = httpx.post(
f"https://formula-cream.pro/api/public/v1/leads/{lead_id}/score",
headers={"Authorization": f"Bearer {os.environ['API_KEY']}",
"Idempotency-Key": str(uuid.uuid4())},
timeout=30,
)
result = r.json()
$ch = curl_init("https://formula-cream.pro/api/public/v1/leads/$leadId/score");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer " . getenv("API_KEY"),
"Idempotency-Key: " . bin2hex(random_bytes(16)),
],
]);
$result = json_decode(curl_exec($ch), true);
После успешной оценки подписчикам уходит событие lead.scored.
#PUT /leads/{id}/score
Записывает вашу оценку (внешняя CRM). Она хранится рядом с нашей и не заменяет её: в таблице владения полями (см. режимы) внешняя оценка называется external_score. Область — leads:write (не leads:score): запись не списывает средства. PUT идемпотентен по природе, заголовок Idempotency-Key принимается и игнорируется.
| Параметр | Тип | Обязательно | Ограничения | Пример |
|---|---|---|---|---|
score | integer | да | 0–100 | 85 |
reason | string | нет | До 500 знаков | "Повторный клиент" |
model | string | нет | Подпись источника оценки | "crm-scoring-v3" |
Требует If-Match, как любое изменение лида (428 precondition_required без заголовка, 412 precondition_failed при устаревшей версии). Ответ 200 OK — объект оценки с source: "external" и вычисленным grade. Значение вне 0–100 — 422 validation_failed (errors[].field = /score).
curl -X PUT https://formula-cream.pro/api/public/v1/leads/$LEAD_ID/score \
-H "Authorization: Bearer $API_KEY" -H "If-Match: 3" \
-H "Content-Type: application/json" \
-d '{"score":85,"reason":"Повторный клиент"}'
#События
| Событие | Когда |
|---|---|
lead.scored | Лид оценён (нашей моделью или внешней оценкой) |
Нагрузка тонкая: идентификатор лида, версия, тип. Саму оценку забирайте запросом GET /leads/{id}; подписка с include_pii: true присылает содержимое в событии. Вебхуки — раздел о вебхуках.
#Заметки
- Настройки оценки (модель, включение флагов) хранятся на арендатора (
settings.crm.scoring); значение ячейки служит умолчанием. Выбрать произвольную модель вы не можете. - Обоснование
reasonи время оценки сохраняются вместе с источником (ai,external,manual) — это изменение кода, которое выполняется при выделении сервиса оценки. До выпуска публичного API сегодняшняя оценкаreasonне сохраняет. - Класс
gradeне хранится отдельно: он вычисляется изscore(A ≥ 75, B 50–74, C 25–49, D < 25). - Оценка без ИИ-переписки не поддерживается.
- Повторная оценка перезаписывает прежнюю.
#Открытые вопросы
- Изменит ли
POST /leads/{id}/scoreстатус (как кнопка «Оценить» в кабинете) или только запишет оценку (техническое). - Стоимость оценки: фактический диапазон будет известен после запуска (техническое).