By Sagar Shankaran, Founder of CallSphere
Build an AI agent that handles insurance claim intake, analyzes supporting documents, assesses damage, calculates payouts, and routes claims through the processing workflow.
Key takeaways
Insurance claims processing is a perfect candidate for AI automation. The typical claim follows a structured workflow — intake, document review, damage assessment, coverage verification, payout calculation — yet most insurers still handle much of this manually. Average processing times of 30 to 45 days frustrate customers and drive up operational costs. An AI agent can compress straightforward claims to minutes while routing complex cases to adjusters with a pre-analyzed package.
Define structured models for claims and supporting documents.
flowchart LR
CALLER(["Policyholder or Lead"])
subgraph TEL["Telephony"]
SIP["Twilio SIP and PSTN"]
end
subgraph BRAIN["Insurance AI Agent"]
STT["Streaming STT<br/>Deepgram or Whisper"]
NLU{"Intent and<br/>Entity Extraction"}
TOOLS["Tool Calls"]
TTS["Streaming TTS<br/>ElevenLabs or Rime"]
end
subgraph DATA["Live Data Plane"]
CRM[("CRM and Notes")]
CAL[("Calendar and<br/>Schedule")]
KB[("Knowledge Base<br/>and Policies")]
end
subgraph OUT["Outcomes"]
O1(["Quote captured"])
O2(["Claim opened in core"])
O3(["Licensed agent handoff"])
end
CALLER --> SIP --> STT --> NLU
NLU -->|Lookup| TOOLS
TOOLS <--> CRM
TOOLS <--> CAL
TOOLS <--> KB
NLU --> TTS --> SIP --> CALLER
NLU -->|Resolved| O1
NLU -->|Schedule| O2
NLU -->|Escalate| O3
style CALLER fill:#f1f5f9,stroke:#64748b,color:#0f172a
style NLU fill:#4f46e5,stroke:#4338ca,color:#fff
style O1 fill:#059669,stroke:#047857,color:#fff
style O2 fill:#0ea5e9,stroke:#0369a1,color:#fff
style O3 fill:#f59e0b,stroke:#d97706,color:#1f2937
from pydantic import BaseModel
from datetime import date, datetime
from enum import Enum
class ClaimType(str, Enum):
AUTO = "auto"
HOME = "home"
HEALTH = "health"
LIFE = "life"
PROPERTY = "property"
class ClaimStatus(str, Enum):
SUBMITTED = "submitted"
UNDER_REVIEW = "under_review"
APPROVED = "approved"
DENIED = "denied"
PENDING_INFO = "pending_info"
class ClaimIntake(BaseModel):
claim_id: str
policy_number: str
claimant_name: str
claim_type: ClaimType
incident_date: date
incident_description: str
estimated_loss: float
documents: list[str] # File paths
submitted_at: datetime
class PolicyDetails(BaseModel):
policy_number: str
holder_name: str
claim_type: ClaimType
coverage_limit: float
deductible: float
exclusions: list[str]
effective_date: date
expiry_date: date
premium_status: str # "current", "lapsed"
The agent analyzes photos, police reports, medical records, and repair estimates.
Hear it before you finish reading
Talk to a live CallSphere AI voice agent for insurance agency in your browser — 60 seconds, no signup.
from openai import OpenAI
client = OpenAI()
class DocumentAnalysis(BaseModel):
document_type: str
key_findings: list[str]
damage_items: list[dict] # {"item": str, "estimated_cost": float}
dates_mentioned: list[str]
parties_involved: list[str]
fraud_indicators: list[str]
def analyze_claim_document(
document_text: str, claim_type: str
) -> DocumentAnalysis:
"""Analyze a claim supporting document."""
response = client.beta.chat.completions.parse(
model="gpt-4o",
messages=[
{
"role": "system",
"content": (
f"You are an insurance claims analyst specializing "
f"in {claim_type} claims. Analyze this document and "
f"extract key findings, itemized damage, dates, "
f"parties involved, and any potential fraud "
f"indicators."
),
},
{"role": "user", "content": document_text},
],
response_format=DocumentAnalysis,
)
return response.choices[0].message.parsed
def analyze_damage_photo(image_path: str, claim_type: str) -> dict:
"""Analyze a damage photo using vision capabilities."""
import base64
with open(image_path, "rb") as f:
image_data = base64.b64encode(f.read()).decode()
response = client.chat.completions.create(
model="gpt-4o",
messages=[
{
"role": "system",
"content": (
"You are an insurance damage assessor. Describe "
"the visible damage, estimate severity (minor, "
"moderate, severe, total loss), and list specific "
"damage items with estimated repair costs."
),
},
{
"role": "user",
"content": [
{
"type": "image_url",
"image_url": {
"url": f"data:image/jpeg;base64,{image_data}"
},
},
{
"type": "text",
"text": f"Assess damage for {claim_type} claim.",
},
],
},
],
)
return {"assessment": response.choices[0].message.content}
Check whether the claim is covered under the policy terms.
class CoverageDecision(BaseModel):
is_covered: bool
applicable_coverage: str
coverage_limit: float
deductible: float
exclusions_triggered: list[str]
coverage_notes: str
def verify_coverage(
claim: ClaimIntake, policy: PolicyDetails
) -> CoverageDecision:
"""Verify claim against policy coverage."""
exclusions_triggered = []
# Check policy is active
if policy.premium_status == "lapsed":
return CoverageDecision(
is_covered=False,
applicable_coverage="None",
coverage_limit=0,
deductible=0,
exclusions_triggered=["Policy lapsed"],
coverage_notes="Policy premiums not current.",
)
# Check incident date is within policy period
if not (policy.effective_date <= claim.incident_date <= policy.expiry_date):
return CoverageDecision(
is_covered=False,
applicable_coverage="None",
coverage_limit=0,
deductible=0,
exclusions_triggered=["Incident outside policy period"],
coverage_notes=(
f"Incident on {claim.incident_date} is outside "
f"policy period {policy.effective_date} to "
f"{policy.expiry_date}."
),
)
# Check exclusions using LLM
response = client.beta.chat.completions.parse(
model="gpt-4o",
messages=[
{
"role": "system",
"content": (
"Determine if any policy exclusions apply to "
"this claim. Be specific about which exclusion "
"applies and why."
),
},
{
"role": "user",
"content": (
f"Incident: {claim.incident_description}\n\n"
f"Policy Exclusions:\n"
+ "\n".join(
f"- {e}" for e in policy.exclusions
)
),
},
],
response_format=CoverageDecision,
)
decision = response.choices[0].message.parsed
decision.coverage_limit = policy.coverage_limit
decision.deductible = policy.deductible
return decision
class PayoutCalculation(BaseModel):
total_claimed: float
total_approved: float
deductible_applied: float
coverage_limit_applied: bool
net_payout: float
line_items: list[dict]
adjustments: list[str]
def calculate_payout(
analyses: list[DocumentAnalysis],
coverage: CoverageDecision,
) -> PayoutCalculation:
"""Calculate the claim payout amount."""
line_items = []
total_claimed = 0.0
for analysis in analyses:
for item in analysis.damage_items:
cost = item.get("estimated_cost", 0)
line_items.append({
"description": item.get("item", "Unknown"),
"claimed_amount": cost,
"approved_amount": cost, # Simplified
})
total_claimed += cost
# Apply deductible
after_deductible = max(0, total_claimed - coverage.deductible)
# Apply coverage limit
limit_applied = after_deductible > coverage.coverage_limit
net_payout = min(after_deductible, coverage.coverage_limit)
adjustments = [
f"Deductible applied: ${coverage.deductible:,.2f}"
]
if limit_applied:
adjustments.append(
f"Coverage limit applied: ${coverage.coverage_limit:,.2f}"
)
return PayoutCalculation(
total_claimed=total_claimed,
total_approved=total_claimed,
deductible_applied=coverage.deductible,
coverage_limit_applied=limit_applied,
net_payout=net_payout,
line_items=line_items,
adjustments=adjustments,
)
def process_claim(claim: ClaimIntake, policy: PolicyDetails) -> dict:
"""Process an insurance claim end to end."""
# Analyze all documents
analyses = []
for doc_path in claim.documents:
text = extract_text(doc_path) # from earlier tutorial
analysis = analyze_claim_document(text, claim.claim_type.value)
analyses.append(analysis)
# Verify coverage
coverage = verify_coverage(claim, policy)
if not coverage.is_covered:
return {"status": "denied", "reason": coverage.coverage_notes}
# Calculate payout
payout = calculate_payout(analyses, coverage)
return {
"status": "approved",
"net_payout": payout.net_payout,
"line_items": payout.line_items,
"adjustments": payout.adjustments,
}
The agent checks for several fraud indicators: inconsistencies between photos and described damage, claims filed shortly after policy inception, duplicate claims across policies, inflated repair estimates compared to market rates, and mismatches between incident descriptions and supporting evidence. High-risk claims are flagged for the Special Investigations Unit.
Still reading? Stop comparing — try CallSphere live.
See the insurance agency AI agent handle a real call — complete, industry-specific, and live in your browser. No signup.
The agent triages claims by complexity. Simple claims (clear documentation, single damage item, within standard parameters) are processed automatically. Complex claims (multiple parties, disputed liability, large losses) are routed to human adjusters with a pre-built analysis package that saves hours of initial investigation.
Most states require acknowledgment within 15 days and decisions within 30-45 days. The agent tracks these deadlines automatically and escalates claims approaching their statutory deadline. It can also generate the required regulatory correspondence at each stage.
#Insurance #ClaimsProcessing #DocumentAnalysis #Automation #AIAgent #AgenticAI #LearnAI #AIEngineering

Written by
Sagar Shankaran· Founder, CallSphere
LinkedInSagar Shankaran is the founder of CallSphere, where he builds production AI voice and chat agents deployed across healthcare, hospitality, real estate, and home services. He writes about agentic AI, LLM engineering, and shipping voice agents that handle real calls in production.
See how AI voice agents work for your industry. Live demo available -- no signup required.
How NBFCs, insurance agencies, loan DSAs, and financial advisors in Mumbai, Delhi, and Chennai use CallSphere AI voice + chat agents to qualify and capture every finance lead 24/7, DPDP-ready.
UK insurance brokers and financial advisers in London, Birmingham and Glasgow lose business the moment a quote call hits voicemail. How a CallSphere AI voice agent captures and qualifies every enquiry.
A practical guide for South African brokers, advisers and insurers on using CallSphere AI voice and chat agents to handle claims calls, quotes and after-hours enquiries — POPIA-aware, multilingual, 24/7.
Anthropic shipped 10 finance agent templates for KYC and back-office. CallSphere covers the customer-facing phone line. Here is how the two stack for insurance.
Aviva saved £60M ($82M) on motor claims with 80+ AI models. Lemonade pays claims in 3 seconds. Aspire's Liberate FNOL launched March 2026. Real numbers, real builds.
Enterprise CIO Guide perspective on Klarna's AI agent pioneered the resolution-equivalent metric and is now in its third year of production data.
© 2026 CallSphere LLC. All rights reserved.
Made within New York
Watch how CallSphere handles real customer calls, schedules appointments, and processes payments — live.
Try Live DemoBook a DemoCalculate Your ROI