ClaimPilot предоставляет приём и триаж обращений по небольшому REST API, чтобы страховая компания
могла встроить его в свои системы по обычному HTTP. API — это набор тонких обёрток над тем же
сервисным слоем, который используют веб-форма, админ-панель Filament и MCP-сервер. Поэтому все
четыре поверхности ведут себя одинаково и не расходятся. Формы ответов на чтение берутся из единого
форматтера (App\Mcp\Support\ClaimPresenter); создание обращения переиспользует валидацию веб-формы
(ClaimIntakeController::textFieldRules()) и конвейер (ClaimPipeline::dispatch()).
Это серверный API: ClaimPilot публикует эндпоинты, ваша система — клиент. Триаж выполняется
асинхронно в фоновой очереди — POST /claims возвращает результат сразу (202), а итог вы узнаёте,
опрашивая GET /claims/{uuid}/status или получая webhook. Как и в MCP, приём только
текстовый — JSON не передаёт бинарные данные, поэтому фотографии повреждений и сканы документов
по-прежнему загружаются через веб-форму (они питают этапы компьютерного зрения); текстовое обращение
всё равно проходит весь конвейер, просто этапам фото/документов нечего анализировать.
Базовый URL: /api/v1 · Формат: JSON in/out · Аутентификация: Sanctum bearer-токен.
Обращения, созданные здесь, получают channel = api и протоколируются (каждый вызов LLM пишется в
ai_calls) так же, как web/MCP-обращения — они отображаются в /admin без какой-либо особой обработки.
Все маршруты /api/v1/* требуют личный токен Laravel Sanctum. Выпустите токен для администратора
демо:
php artisan claimpilot:api-token "acme-integration"
Команда печатает токен в открытом виде один раз (повторно его получить нельзя). Передавайте его как bearer-токен:
Authorization: Bearer 1|abc123...
Отсутствующий или недействительный токен → 401 { "error": "Unauthenticated." }.
Единый формат на всех эндпоинтах:
{ "data": <payload>, "links"?: { ... } }{ "error": "<message>" }{ "error": "The given data was invalid.", "errors": { "<field>": ["<msg>", ...] } }| Метод и путь | Назначение | Успех |
|---|---|---|
POST /claims |
Создать обращение, запустить триаж | 202 |
GET /claims |
Список обращений (фильтры, сначала новые) | 200 |
GET /claims/{uuid} |
Полная карточка обращения для оценщика | 200 |
GET /claims/{uuid}/status |
Прогресс конвейера | 200 |
POST /claims/{uuid}/mark-reply-sent |
Пометить ответ отправленным (идемпотентно) | 200 |
POST /claims — создать обращение (только текст, асинхронно)Тело (все поля обязательны; правила те же, что у веб-формы / MCP submit_claim):
| Поле | Тип | Правила |
|---|---|---|
claimant_name |
string | до 255 |
claimant_contact |
string | телефон или email, до 255 |
incident_description |
string | 10–10000 символов, свободный текст (ожидается русский) |
incident_date |
string | YYYY-MM-DD, сегодня или раньше |
Создаёт обращение со status = received, channel = api, запускает конвейер и сразу возвращает
202:
{
"data": { "uuid": "9b2c…", "status": "received" },
"links": {
"self": "https://.../api/v1/claims/9b2c…",
"status": "https://.../api/v1/claims/9b2c…/status"
}
}
curl -s -X POST https://HOST/api/v1/claims \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" -H "Accept: application/json" \
-d '{"claimant_name":"Иван Иванов","claimant_contact":"+7 900 000-00-00",
"incident_description":"Вечером затопили соседи сверху, повреждён потолок и ламинат.",
"incident_date":"2026-06-10"}'
Некорректное тело → 422 с указанием проблемного поля. Следующий шаг: опрашивайте
GET /claims/{uuid}/status, пока is_finished не станет true, затем читайте GET /claims/{uuid}.
GET /claims — списокВсе query-параметры необязательны, объединяются по И, сначала новые:
| Параметр | Допустимые значения |
|---|---|
status |
received, processing, triaged, needs_info, failed |
incident_type |
auto_accident, property_water, property_fire, theft, health, other |
severity |
minor, moderate, major, total_loss |
limit |
целое 1–100 (по умолчанию 25) |
{ "data": [ { "uuid": "…", "claimant_name": "…", "incident_type": "…", "severity": "…",
"status": "…", "red_flag_count": 1, "created_at": "2026-06-18T16:00:00+00:00" } ] }
curl -s "https://HOST/api/v1/claims?status=triaged&severity=major&limit=10" \
-H "Authorization: Bearer $TOKEN" -H "Accept: application/json"
GET /claims/{uuid} — карточка обращения{ "data": {
"uuid": "…", "status": "triaged", "claimant_name": "…", "claimant_contact": "…",
"incident_type": "property_water", "severity": "moderate", "severity_confidence": 0.82,
"estimated_amount_min": 40000, "estimated_amount_max": 120000,
"ai_summary": "…", "client_reply_draft": "…",
"red_flags": [ { "code": "…", "severity": "low|medium|high", "explanation": "…" } ],
"missing_documents": ["…"]
} }
Суммы — в рублях (RUB), могут быть null (модель оценивает консервативно). incident_type,
severity и суммы равны null, пока не выполнен синтез. Неизвестный uuid → 404
{ "error": "No claim found with uuid [X]." }.
GET /claims/{uuid}/status{ "data": {
"uuid": "…", "status": "received|processing|triaged|needs_info|failed",
"stages_completed": ["vision_photos","vision_documents","synthesis","notify"],
"stages_pending": [], "is_finished": true
} }
is_finished равен true, как только status становится triaged, needs_info или failed. Если
status остаётся received и stages_completed пуст — вероятно, не запущен воркер очереди.
POST /claims/{uuid}/mark-reply-sentУстанавливает client_reply_sent_at, если он ещё не задан (как кнопка «отметить как отправленное» в
админке). Идемпотентно — повторный вызов сохраняет исходную отметку времени.
{ "data": { "uuid": "…", "client_reply_sent_at": "2026-06-18T16:05:00+00:00" } }
Вместо опроса можно настроить исходящий webhook — результат придёт к вам push-уведомлением по завершении триажа.
Конфигурация (.env):
CLAIMPILOT_WEBHOOK_URL=https://your-system.example/claimpilot-hook
CLAIMPILOT_WEBHOOK_SECRET=optional-shared-secret
Когда CLAIMPILOT_WEBHOOK_URL задан, ClaimPilot отправляет (POST) на него такой JSON:
{
"event": "claim.triaged",
"uuid": "…",
"status": "triaged",
"timestamp": "2026-06-18T16:05:00+00:00",
"data": { ...та же карточка обращения, что и GET /claims/{uuid}... }
}
CLAIMPILOT_WEBHOOK_SECRET, он передаётся в заголовке X-ClaimPilot-Secret (простой
общий секрет — не HMAC-подпись запроса; проверяйте на своей стороне обычным сравнением строк)..env.ClaimTriaged, которое NotifyJob
отправляет в конце конвейера — то есть покрывает triaged и needs_info (успешные финальные
состояния). failed-обращения его НЕ запускают (упавший этап останавливает цепочку до
NotifyJob). Это известное ограничение; для уведомлений об ошибках опрашивайте
GET /claims/{uuid}/status.POST /claims → 202 { uuid, status: "received" }
↓ (фоновая очередь — должен быть запущен воркер)
опрашивайте GET /claims/{uuid}/status пока is_finished == true
ИЛИ получите webhook (triaged/needs_info)
↓
GET /claims/{uuid} → итоговая карточка
Должен быть запущен воркер очереди, иначе обращения навсегда останутся в
received:php artisan queue:work --tries=1 --timeout=900
{ "error": "Unauthenticated." }{ "error": "No claim found with uuid [X]." }{ "error": "The given data was invalid.", "errors": { "<field>": [...] } }Намеренно не реализовано (это MVP-поверхность API, а не продакшен-шлюз):
/v1POST /claims