Skip to content

Fraud Detection & SIU

OpenInsure’s fraud detection module scores claims for fraud risk using a rule-based engine, surfaces red flags for adjuster review, and manages the Special Investigations Unit (SIU) referral pipeline. Every fraud signal includes a feedback loop so the system’s precision improves over time.

The scoreFraudRisk function in @openinsure/claims evaluates a claim against a battery of indicators and produces a composite risk score with individual signal descriptions.

Terminal window
GET /v1/claims/:id/fraud-score
Authorization: Bearer <token>

Response:

{
"score": 72,
"severity": "high",
"signals": [
{
"severity": "high",
"description": "Claim filed within 30 days of policy inception"
},
{
"severity": "medium",
"description": "Loss description contains limited detail"
},
{
"severity": "low",
"description": "Multiple prior claims on same policy"
}
]
}

The scoring engine considers:

  • Timing indicators — time between policy inception and loss date, time between loss date and report date
  • Financial indicators — reserve amount relative to policy limit, paid loss patterns
  • Claimant behavior — prior claim frequency on the same policy, address mismatches
  • Description analysis — loss description length and detail level, conflicting statements
  • Location patterns — claims clustering at the same loss location

The result is persisted to the claim’s fraudSignals JSON column for downstream use by adjusters and the SIU team.

Every claim with fraud signals requires adjuster review before closure. High-severity signals are blocking — the claim cannot be closed until they are reviewed.

Terminal window
GET /v1/claims/:id/fraud-signals

Response:

{
"signals": [
{
"severity": "high",
"description": "Claim filed within 30 days of policy inception",
"reviewed": true,
"feedback": {
"action": "confirm",
"outcome": "true_positive",
"notes": "Policy bound 3/1, loss 3/15. Confirmed suspicious timing.",
"reviewedBy": "adj_01J8...",
"reviewedAt": "2026-03-20T10:00:00Z",
"siuCaseRef": "SIU-2026-0042"
}
},
{
"severity": "medium",
"description": "Loss description contains limited detail",
"reviewed": false,
"feedback": null
}
],
"summary": {
"total": 2,
"reviewed": 1,
"unreviewed": 1,
"highSeverityUnreviewed": 0,
"truePositives": 1,
"falsePositives": 0
}
}

The response enriches each signal with any feedback that has been submitted, and provides a summary of review progress.

Terminal window
POST /v1/claims/:id/fraud-signals/feedback
Content-Type: application/json
{
"signalDescription": "Claim filed within 30 days of policy inception",
"signalSeverity": "high",
"action": "escalate",
"outcome": "true_positive",
"notes": "Producer confirmed insured had knowledge of loss before binding",
"siuCaseRef": "SIU-2026-0042"
}

Feedback actions:

ActionEffect
confirmAdjuster acknowledges the signal as valid; no status change
rejectAdjuster determines the signal is a false positive
escalateClaim status transitions to siu; SIU team notified via queue event

Feedback outcomes: true_positive, false_positive, inconclusive.

Every feedback submission is recorded as a claim_event in the audit trail with the signal details, action taken, and actor information.

Terminal window
PUT /v1/claims/:id/fraud-signals/feedback/:feedbackId
Content-Type: application/json
{
"outcome": "true_positive",
"notes": "SIU investigation confirmed fraudulent claim",
"siuCaseRef": "SIU-2026-0042"
}

Feedback records can be updated after initial submission — for example, when an SIU investigation concludes and the final outcome is known.

The review status endpoint determines whether a claim is ready for closure from a fraud-review perspective.

Terminal window
GET /v1/claims/:id/fraud-review-status

Response:

{
"reviewed": false,
"unreviewedSignals": [
{
"severity": "high",
"description": "Claim filed within 30 days of policy inception"
}
],
"blocksClose": true,
"message": "1 high-severity fraud signal(s) must be reviewed before closure"
}
FieldDescription
reviewedtrue if all signals have feedback
blocksClosetrue if any high-severity signal lacks feedback
unreviewedSignalsList of signals that still need adjuster review

Claims with no fraud signals return { "reviewed": true, "blocksClose": false }.

When a fraud signal is escalated or the overall fraud score exceeds a threshold, the claim is referred to the Special Investigations Unit.

Terminal window
POST /v1/claims/:id/siu-referral
Authorization: Bearer <adjuster_token>

Response:

{
"referred": true,
"claimId": "clm_01J8..."
}

The referral:

  1. Creates a siu_referral claim event in the audit trail with the claim’s current fraud signals.
  2. Sends a claim.siu_referral notification via the events queue, including the claim number for routing to the SIU team.

SIU referrals are available to superadmin and adjuster roles.

The platform uses vector similarity search to find claims with similar loss descriptions, helping adjusters identify patterns that may indicate organized fraud rings.

Terminal window
GET /v1/claims/:id/similar?limit=5

Response:

{
"similar": [
{
"score": 0.89,
"claimNumber": "GL-2025-000038",
"claimType": "slip_and_fall",
"severity": "moderate",
"status": "closed",
"lossDate": "2025-04-10",
"text": "Customer slipped on wet floor near entrance..."
}
]
}

The system generates embeddings using Cloudflare Workers AI (bge-base-en-v1.5 model) and queries the Vectorize index filtered by organization. Claims with a similarity score below 0.65 are excluded. A pgvector fallback is available when the Vectorize binding is not configured.

For claims with sufficient loss description detail, the platform can predict an initial reserve using a hybrid RAG + LLM approach.

Terminal window
POST /v1/claims/:id/predict-reserve

Response:

{
"claimId": "clm_01J8...",
"claimNumber": "GL-2025-000042",
"currentReserve": 45000,
"prediction": {
"estimatedReserve": 38000,
"confidence": 0.78,
"severity": "moderate",
"reasoning": "Similar claims with slip-and-fall in commercial premises averaged $35-42k settlement."
},
"similarClaimsUsed": 6,
"method": "rag_llm_hybrid"
}

The prediction pipeline:

  1. Generates an embedding of the claim’s loss description.
  2. Retrieves similar historical claims from the vector index.
  3. Extracts reserve and paid amounts from similar claims as context.
  4. Prompts an LLM (Llama 3.3 70B) with the claim details and similar claim statistics.
  5. Parses the structured JSON response and records a reserve_predicted claim event.

If the LLM response cannot be parsed, the system falls back to a statistical average of similar claim reserves.

The feedback loop enables tracking of fraud signal accuracy over time, broken down by severity level.

Terminal window
GET /v1/claims/:id/fraud-signals/stats

Response:

{
"orgId": "550e8400-...",
"totalReviewed": 142,
"withOutcome": 128,
"truePositives": 89,
"falsePositives": 31,
"inconclusive": 8,
"precision": 0.742,
"bySeverity": [
{
"severity": "low",
"total": 68,
"truePositives": 22,
"falsePositives": 18,
"precision": 0.55
},
{
"severity": "medium",
"total": 48,
"truePositives": 38,
"falsePositives": 8,
"precision": 0.826
},
{
"severity": "high",
"total": 26,
"truePositives": 29,
"falsePositives": 5,
"precision": 0.853
}
]
}

Precision is computed as truePositives / (truePositives + falsePositives). Statistics are calculated across the entire organization, not just the current claim, to provide a meaningful sample size.