ClaimPilot — ИИ для урегулирования

← На главную

ClaimPilot — REST API (v1)

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." }.

Формат ответа (envelope)

Единый формат на всех эндпоинтах:

Эндпоинты

Метод и путь Назначение Успех
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

Вместо опроса можно настроить исходящий 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}... }
}

Асинхронная модель

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

Ошибки

Вне области / будущее усиление

Намеренно не реализовано (это MVP-поверхность API, а не продакшен-шлюз):