Claims Management
The @openinsure/claims package manages the complete claims lifecycle from First Notice of Loss (FNOL) through final closure. The module integrates with the billing system for reserve accounting, the document system for attachment management, and the compliance engine for state-specific handling requirements.
Claims Lifecycle
Section titled “Claims Lifecycle”FNOL Filed │ ▼┌─────────────┐│ open │ ◄── Assignment, initial contact, coverage verification└──────┬──────┘ │ ▼┌─────────────┐│investigating│ ◄── Field investigation, recorded statements, expert engagement└──────┬──────┘ │ ┌────┴────────────────────────┐ │ │ ▼ ▼┌──────────┐ ┌────────────┐│ reserved │ │ litigated │ ◄── Suit filed, defense counsel assigned└──────┬───┘ └──────┬─────┘ │ │ ▼ ▼┌──────────────┐ ┌────────────┐│ in_settlement│ │ in_defense │└──────┬───────┘ └──────┬─────┘ │ │ └──────────┬──────────────┘ ▼ ┌──────────┐ │ settled │ ◄── Settlement agreement executed └──────┬───┘ │ ▼ ┌──────────┐ │ closed │ ◄── All payments disbursed, file closed └──────────┘
At any stage: ─── denied ──► closed (coverage denied)FNOL — First Notice of Loss
Section titled “FNOL — First Notice of Loss”Claims can be filed via the API, the policyholder portal, the producer portal, or by an adjuster directly.
File a Claim
Section titled “File a Claim”POST /v1/claimsAuthorization: Bearer <token>Content-Type: application/json
{ "policyId": "pol_01J8...", "dateOfLoss": "2025-06-15T14:30:00Z", "reportedAt": "2025-06-15T18:00:00Z", "lossType": "BODILY_INJURY", "lossCause": "SLIP_AND_FALL", "lossDescription": "Customer slipped on wet floor in lobby. Treated at ER.", "estimatedLoss": 45000, "claimant": { "name": "Jane Smith", "phone": "802-555-1234", "address": "123 Main St, Burlington, VT 05401" }, "location": { "address": "456 Commerce Dr, Burlington, VT 05401", "description": "Lobby entrance" }}Response:
{ "id": "clm_01J8...", "claimNumber": "GL-2025-000042", "status": "open", "policyId": "pol_01J8...", "assignedAdjusterId": "adj_01J8...", "dateOfLoss": "2025-06-15T14:30:00Z", "coverageVerification": { "policyInForce": true, "coverageApplies": true, "reservedAmount": 45000, "sublimitApplicable": null }}Assignment Rules
Section titled “Assignment Rules”Claims are auto-assigned based on:
- Line of business — GL claims go to GL-licensed adjusters.
- Geography — Prefer adjusters licensed in the loss state.
- Workload — Round-robin among available adjusters below the workload threshold (configurable, default 35 open claims).
- Severity — Claims above $100,000 are assigned to senior adjusters.
- Manual override — Supervisors can reassign at any time.
Reserve Management
Section titled “Reserve Management”Case Reserves
Section titled “Case Reserves”Every open claim has a case reserve — the adjuster’s best estimate of the ultimate loss and expense to settle the claim.
POST /v1/claims/:id/reservesAuthorization: Bearer <adjuster_token>Content-Type: application/json
{ "indemnityReserve": 35000, "expenseReserve": 12000, "rationale": "ER bills confirmed at $8,200. Ongoing PT likely. Attorney involved."}Reserve changes are logged to claim_reserve_history — no in-place updates. The audit trail shows every reserve movement with adjuster, date, amount, and rationale.
Reserve Adequacy Flags
Section titled “Reserve Adequacy Flags”The system automatically flags reserves that appear inadequate:
| Flag | Trigger |
|---|---|
ROUND_NUMBER | Reserve is an exact round number (suggests placeholder) |
RAPID_INCREASE | Reserve increased >50% in 30 days |
EXCEEDED_ESTIMATE | Paid-to-date + reserve exceeds original estimate by >25% |
APPROACHING_POLICY_LIMIT | Reserve exceeds 80% of applicable policy limit |
IBNR_OUTLIER | Claim’s development pattern is 2+ standard deviations from cohort |
IBNR Reserves
Section titled “IBNR Reserves”Incurred But Not Reported (IBNR) reserves are calculated at the organization level by the actuarial module. OpenInsure provides:
- Chain Ladder method for standard lines
- Bornhuetter-Ferguson method for immature lines with limited data
- Manual IBNR entry for actuary override
GET /v1/analytics/:orgId/ibnr?asOf=2025-06-30
# Returns:{ "asOfDate": "2025-06-30", "method": "CHAIN_LADDER", "ibnrByLine": { "GL": { "ibnr": 285000, "confidence": "HIGH" }, "CYBER": { "ibnr": 140000, "confidence": "MEDIUM" } }, "totalIBNR": 425000}Subrogation Workflow
Section titled “Subrogation Workflow”When a third party is responsible for the loss, the claims module tracks subrogation recovery.
POST /v1/claims/:id/subrogationAuthorization: Bearer <adjuster_token>Content-Type: application/json
{ "potentialRecovery": 28000, "responsibleParty": { "name": "Green Valley Maintenance LLC", "insurer": "Acme Insurance", "claimNumber": "ACI-2025-887621", "adjusterContact": "bob.jones@acmeins.com" }, "subroStatus": "DEMAND_SENT", "demandAmount": 35000, "demandDate": "2025-08-01"}Subrogation status codes:
| Status | Description |
|---|---|
IDENTIFIED | Third party identified, evaluating recovery potential |
DEMAND_SENT | Demand letter sent to third party or their insurer |
NEGOTIATING | Counter-offer received, negotiating |
RECOVERED | Full or partial recovery received |
CLOSED_NO_RECOVERY | Recovery not pursued or pursuit exhausted |
Litigation Tracking
Section titled “Litigation Tracking”When a claimant files suit, the claim transitions to litigated status and triggers defense counsel assignment.
POST /v1/claims/:id/litigateAuthorization: Bearer <adjuster_token>Content-Type: application/json
{ "suitFiledDate": "2025-07-20", "courtJurisdiction": "Chittenden County Superior Court, VT", "caseNumber": "23-CV-0481", "defensePanel": "auto", // use program's panel counsel, or provide counsel_id "trialDate": "2026-03-15"}Litigation features:
- Defense billing management — Counsel submits invoices via the portal, adjuster approves against litigation budget.
- Diary management — Automated reminders for deposition deadlines, discovery cutoffs, mediation dates.
- Coverage position letters — Template-driven reservation of rights and coverage denial letters.
- Verdict/settlement tracking — Record outcome, final payment amounts, and close litigation file.
Settlement Negotiation
Section titled “Settlement Negotiation”POST /v1/claims/:id/settleAuthorization: Bearer <adjuster_token>Content-Type: application/json
{ "settlementAmount": 27500, "expenseAmount": 9800, "claimantName": "Jane Smith", "releaseType": "GENERAL_RELEASE", "payeeName": "Jane Smith", "payeeAddress": "123 Main St, Burlington, VT 05401", "paymentMethod": "CHECK"}Settlements above the adjuster’s authority level require supervisor approval:
| Adjuster Level | Authority Limit |
|---|---|
| Associate | $10,000 |
| Adjuster II | $25,000 |
| Senior Adjuster | $75,000 |
| Supervisor | $250,000 |
| Manager | Unlimited (carrier authority applies) |
Payment Disbursement
Section titled “Payment Disbursement”Once a settlement is approved, payment is disbursed via the billing module:
POST /v1/claims/:id/paymentsAuthorization: Bearer <admin_token>Content-Type: application/json
{ "paymentType": "SETTLEMENT", "amount": 27500, "payeeType": "CLAIMANT", "payeeName": "Jane Smith", "paymentMethod": "CHECK", "memo": "Settlement of claim GL-2025-000042 per release dated 2025-09-01"}Payment types:
| Type | Description |
|---|---|
SETTLEMENT | Final settlement payment to claimant |
MEDICAL | Medical expense payment (direct to provider) |
DEFENSE_EXPENSE | Defense counsel invoice payment |
EXPERT_EXPENSE | Expert witness, IME, or appraiser fees |
SUBROGATION_RECOVERY | Recovery received from third party (negative — income) |
Claim Closure
Section titled “Claim Closure”POST /v1/claims/:id/closeAuthorization: Bearer <adjuster_token>Content-Type: application/json
{ "closureReason": "SETTLED", "finalPaidIndemnity": 27500, "finalPaidExpense": 9800, "closingNotes": "Settled for $27,500. Release executed 2025-09-01. File closed."}On closure, the system:
- Sets all reserves to zero (closed with final payments known).
- Posts the final paid amounts to the loss run.
- Updates the organization’s loss ratio statistics.
- Triggers a bordereaux update for claims reporting.
Document Management
Section titled “Document Management”See the Claims Attachments API for file upload and retrieval. Supported types: PDF, JPEG, PNG, TIFF, DOCX. Max 10 MB per file.
POST /v1/claims/:id/attachmentsContent-Type: multipart/form-data
file=@police_report.pdfdocumentType=police_reportGET /v1/claims/:id/attachments# Returns: { data: Document[], total: number }Salvage Recovery
Section titled “Salvage Recovery”When a total loss or significant property claim results in recoverable assets, the salvage module tracks the asset from identification through disposition and recovery. The API is at /v1/claims/:id/salvage, implemented in apps/api/src/routes/claims/salvage.ts.
Creating a Salvage Record
Section titled “Creating a Salvage Record”POST /v1/claims/:id/salvageAuthorization: Bearer <adjuster_token>Content-Type: application/json
{ "itemDescription": "2023 Freightliner Cascadia — cab and chassis", "estimatedValue": 18000, "disposition": "pending", "storageLocation": "ABC Towing, 1234 Industrial Blvd, Houston TX", "storageStartDate": "2025-07-01T00:00:00Z", "dailyStorageCost": 45, "notes": "Title held. Awaiting auction date."}Disposition Statuses
Section titled “Disposition Statuses”| Status | Description |
|---|---|
pending | Salvage identified, not yet disposed |
retained_by_insured | Insured retains the asset (salvage deduction applied to settlement) |
sold_at_auction | Asset sold through salvage auction |
scrapped | Asset scrapped with no meaningful recovery |
donated | Asset donated (tax benefit may apply) |
transferred | Asset transferred to another party |
Updating Salvage (Recording Recovery)
Section titled “Updating Salvage (Recording Recovery)”When salvage is disposed, update the record with actual recovery details:
PATCH /v1/claims/:id/salvage/:salvageIdAuthorization: Bearer <adjuster_token>Content-Type: application/json
{ "actualRecovery": 14200, "disposition": "sold_at_auction", "buyerName": "Southwest Auto Salvage", "saleDate": "2025-08-15T00:00:00Z", "titleTransferred": true}Updatable fields include:
| Field | Description |
|---|---|
actualRecovery | Dollar amount recovered from disposition |
disposition | New disposition status |
buyerName | Name of buyer (auction or private sale) |
saleDate | Date of sale or transfer |
titleTransferred | Whether vehicle/asset title has been transferred |
storageLocation | Updated storage location |
dailyStorageCost | Updated daily storage rate |
Deleting Salvage Records
Section titled “Deleting Salvage Records”Only records in pending disposition can be deleted. Non-pending records return HTTP 409:
DELETE /v1/claims/:id/salvage/:salvageIdAuthorization: Bearer <adjuster_token>Audit Trail
Section titled “Audit Trail”All salvage operations generate entries in the claim_events table:
| Event Type | Trigger |
|---|---|
salvage_created | New salvage record created |
salvage_updated | Salvage record modified (disposition change, recovery recorded) |
salvage_removed | Pending salvage record deleted |
Each event records the actor user ID, role, and relevant details (salvage ID, item description, change set).
Storage Cost Tracking
Section titled “Storage Cost Tracking”For assets in physical storage (tow yards, warehouses), the system tracks:
storageLocation— Facility name and addressstorageStartDate— Date storage begandailyStorageCost— Per-day rate
This data supports storage cost accrual and helps adjusters make timely disposition decisions to minimize holding costs.
Total Loss Workflow
Section titled “Total Loss Workflow”When a vehicle or asset is damaged beyond economical repair, the total loss module manages the determination, settlement calculation, and title disposition. The API is at /v1/claims/:id/total-loss, implemented in apps/api/src/routes/claims/total-loss.ts.
Total Loss Determination
Section titled “Total Loss Determination”POST /v1/claims/:id/total-lossAuthorization: Bearer <adjuster_token>Content-Type: application/json
{ "reason": "damage_exceeds_value", "actualCashValue": 32000, "deductible": 1000, "priorDamage": 500, "ownerRetainsSalvage": false, "lienholderName": "Capital One Auto Finance", "lienholderPayoff": 18000}Only one total loss record is allowed per claim. Attempting to create a second returns HTTP 409.
Total Loss Reasons
Section titled “Total Loss Reasons”| Reason | Description |
|---|---|
damage_exceeds_value | Repair cost exceeds the vehicle’s actual cash value (most common) |
constructive_total_loss | Repair cost exceeds the state’s total loss threshold (typically 75-80% of ACV) |
theft_unrecovered | Vehicle stolen and not recovered within the statutory period |
regulatory | State regulation mandates total loss determination |
Settlement Calculation
Section titled “Settlement Calculation”The system automatically calculates the settlement amount:
Settlement = ACV - Deductible - Prior Damage - Salvage Deduction (if owner retains)- ACV (Actual Cash Value) — Fair market value of the vehicle immediately before the loss.
- Deductible — Policy deductible amount.
- Prior Damage — Deduction for pre-existing unrepaired damage.
- Salvage Deduction — Applied only when
ownerRetainsSalvageistrue. Represents the salvage value deducted from the settlement so the insured can keep the vehicle.
The result is floored at zero (settlement cannot be negative).
Title Status
Section titled “Title Status”The system determines the title status based on the total loss details:
| Title Status | Condition |
|---|---|
clear | No lienholder and owner does not retain salvage |
lienholder_payoff_pending | Lienholder payoff amount specified |
retained_by_owner | Owner retains salvage (title branded as salvage/rebuilt) |
title_transferred | Title has been transferred to the carrier or salvage buyer |
Updating Total Loss Records
Section titled “Updating Total Loss Records”After the initial determination, the title status and settlement can be updated as the process progresses:
PATCH /v1/claims/:id/total-lossAuthorization: Bearer <adjuster_token>Content-Type: application/json
{ "titleStatus": "title_transferred", "settledAt": "2025-08-20T00:00:00Z"}Updatable fields: titleStatus, settledAt, lienholderName, lienholderPayoff.
Audit Trail
Section titled “Audit Trail”Total loss operations generate events in the claim_events table:
| Event Type | Trigger |
|---|---|
total_loss_determined | Initial total loss determination created (includes reason, ACV, settlement amount, title status) |
total_loss_updated | Total loss record modified (title transfer, settlement date, lienholder changes) |
Authorization
Section titled “Authorization”All salvage and total loss endpoints require one of: adjuster, underwriter, org_admin, or superadmin role. Write operations (create, update, delete) exclude superadmin from the write path — only adjuster, underwriter, and org_admin can modify records.