How to Build a claims processing Agent Using CrewAI in TypeScript for healthcare

By Cyprian AaronsUpdated 2026-04-21
claims-processingcrewaitypescripthealthcare

A claims processing agent in healthcare reads incoming claim packets, checks them against policy and clinical rules, flags missing or inconsistent data, and routes clean claims for downstream adjudication. It matters because the manual version is slow, expensive, and error-prone, and every mistake can delay reimbursement or create compliance exposure.

Architecture

  • Claim intake layer

    • Accepts EDI 837, JSON from a portal, or extracted documents from OCR.
    • Normalizes everything into a single internal ClaimPayload shape.
  • Policy and benefits checker

    • Validates member eligibility, coverage dates, copays, prior auth requirements, and plan-specific exclusions.
    • Pulls from payer APIs or cached eligibility snapshots.
  • Clinical rules agent

    • Checks diagnosis/procedure consistency, medical necessity hints, modifiers, and duplicate service patterns.
    • Flags claims that need human review instead of auto-adjudication.
  • Compliance and audit logger

    • Writes every agent decision with timestamps, inputs used, tool calls, and final disposition.
    • Supports HIPAA audit trails and internal model governance.
  • Exception routing layer

    • Sends incomplete or risky claims to a human queue.
    • Produces structured reasons like missing_prior_auth, coverage_lapsed, or coding_mismatch.
  • Secure data access boundary

    • Keeps PHI inside approved storage and only exposes minimum necessary fields to the agent.
    • Enforces data residency if your healthcare org requires region-bound processing.

Implementation

1) Install CrewAI for TypeScript and define your claim shape

CrewAI’s TypeScript package gives you Agent, Task, and Crew primitives. For healthcare work, keep the input model explicit so you can control what PHI enters the workflow.

npm install @crewai/crewai zod
// src/types.ts
import { z } from "zod";

export const ClaimSchema = z.object({
  claimId: z.string(),
  memberId: z.string(),
  providerNpi: z.string(),
  diagnosisCodes: z.array(z.string()),
  procedureCodes: z.array(z.string()),
  serviceDate: z.string(),
  amountBilled: z.number(),
  priorAuthNumber: z.string().optional(),
});

export type ClaimPayload = z.infer<typeof ClaimSchema>;

2) Create specialized agents for validation and exception handling

Use separate agents for policy review and clinical review. That keeps prompts narrow and makes audit trails easier to reason about.

// src/agents.ts
import { Agent } from "@crewai/crewai";

export const policyAgent = new Agent({
  name: "Policy Validator",
  role: "Validate coverage and administrative requirements for healthcare claims",
  goal: "Determine whether a claim has the required administrative data to proceed",
  backstory:
    "You work in a payer operations team reviewing claim completeness against plan rules.",
});

export const clinicalAgent = new Agent({
  name: "Clinical Rules Reviewer",
  role: "Check coding consistency and medical necessity signals",
  goal: "Identify claims that require manual review due to clinical or coding issues",
  backstory:
    "You support utilization management and claims integrity teams.",
});

3) Build tasks that return structured outcomes

For production systems, don’t ask the model for vague prose. Ask for a machine-readable result with a disposition and reasons. That makes routing deterministic.

// src/tasks.ts
import { Task } from "@crewai/crewai";
import { policyAgent, clinicalAgent } from "./agents";
import type { ClaimPayload } from "./types";

export function buildTasks(claim: ClaimPayload) {
  const policyTask = new Task({
    description: `
Review this healthcare claim for administrative completeness.
Return JSON with fields: disposition (approve|reject|review), reasons (array), missingFields (array).

Claim:
${JSON.stringify(claim)}
`,
    expectedOutput: "Strict JSON only",
    agent: policyAgent,
  });

  const clinicalTask = new Task({
    description: `
Review this healthcare claim for coding consistency.
Return JSON with fields: disposition (approve|reject|review), reasons (array), riskFlags (array).

Claim:
${JSON.stringify(claim)}
`,
    expectedOutput: "Strict JSON only",
    agent: clinicalAgent,
    context: [policyTask],
  });

  return [policyTask, clinicalTask];
}

4) Orchestrate the crew and route the result

This is the part that turns analysis into an operational workflow. The crew executes both tasks in order, then your service decides whether to auto-adjudicate or send to an analyst queue.

// src/index.ts
import { Crew } from "@crewai/crewai";
import { ClaimSchema } from "./types";
import { buildTasks } from "./tasks";

async function processClaim(input: unknown) {
  const claim = ClaimSchema.parse(input);

  const tasks = buildTasks(claim);

  const crew = new Crew({
    agents: tasks.map((t) => t.agent),
    tasks,
    verbose: true,
    memory: false,
    planning: false,
  });

  
    
    
  
    
    
    
    
    
    
    
  
    
    
    
    
  

  
    
    
    
  
  
  
  
  
  
  
  
  
  
  

  
  
  
    
    
    
    
    
  

  
    
    
    
  
  
  
  

  
    
    
    
    
    
  

  
    
    
    
    
    
  

  

  
  
  

  
    
    

    
  

    
  

    
  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  
  
    
    

    

    

    

    

    
  
    
  

  

  
  
  

    
    
    

  
    
    

    
  

    
      
    

  
    
  

  
  
  
    
      
  

  
    
      

    
    
  
  

    
    
    
    
    
    
    
  
    
    
    
    
    
  

  
    
    
    
    
    
  

  
    
    
    
    
    
    
    
  
    
    
    


 

 

 
 
 

 

 

 

 

 

 
 
 

 
  
  
    
    
    
    
    
    
  
    
    
    
    
    
  


 
 

 
  

 
  

   
   

    
 
    
      

   
   

   
    
      

   
    
      

   

   
    
      

   

   
    
      

   
    
      

   
   

   
    
      
     

   
   

   
  



 
 

 

 

 

 

 
 
 

 

 

 

 



 

 

 

 

 







 




























 
 

  

  

  











 
  
    


 
  
  
















 
  





 

 

  

 

  




 

  

 

 
  
  
  
  





 


 
  

  


 
  

  

  

  
  
  
    
      
  


 
  
    


 
    
    

    

    
  


 
    
      

    
      

      
    

    

     
     
     
     

     
     

     

     
     

     

     
     

     

     
     

  

  


    


    


    


    


    


    


    


    


    


    
    
    
    
    
  






const result = await crew.kickoff();

return result;
}

processClaim({
  claimId: "CLM-10001",
  memberId: "M12345",
});

// In production you would persist result.output plus task metadata to an audit store.

The exact shape of result depends on your CrewAI version, but the pattern stays the same:

  • validate input before calling the crew
  • keep each task narrowly scoped
  • use task context to pass upstream findings
  • persist outputs with trace metadata

Production Considerations

  • HIPAA controls

    • Minimize PHI in prompts. Pass only fields needed for adjudication.
    • Encrypt data at rest and in transit.
    • Make sure your vendor agreements cover PHI handling if any external model endpoint is involved.
  • Auditability

    • Store every task input, output, model version, timestamp, claimant identifier hash, and routing decision.
    • Keep immutable logs so compliance teams can reconstruct why a claim was rejected or escalated.
  • Data residency

    • If your healthcare organization requires region-bound processing, pin execution to approved cloud regions.
    • Don’t let intermediate artifacts land in unmanaged object storage or global telemetry systems.
  • Guardrails

    • Use deterministic JSON schemas on outputs before any downstream action. If parsing fails, route to human review.
    • Add rule-based overrides for high-risk cases like oncology, behavioral health, transplant services, or out-of-network exceptions.

Common Pitfalls

  1. Letting the agent see too much PHI

    • Avoid dumping full charts into prompts.
    • Pre-filter fields server-side and redact identifiers not required for the task.
  2. Using free-form text outputs

    • Don’t ask the model to “explain what it thinks.”
    • Require strict JSON so your workflow engine can make safe decisions without regex hacks.
  3. Skipping human fallback paths

    • Never auto-deny on ambiguous results.
    • Route uncertain claims to an analyst queue with clear reasons like insufficient_documentation or coding_conflict.
  4. Ignoring versioning

    • Track prompt versions, rule versions, and model versions separately.
    • Claims teams need reproducibility when disputes happen months later.

Keep learning

By Cyprian Aarons, AI Consultant at Topiax.

Want the complete 8-step roadmap?

Grab the free AI Agent Starter Kit — architecture templates, compliance checklists, and a 7-email deep-dive course.

Get the Starter Kit

Related Guides