AgentisIQ · n8n Automation Guide

Autonomous AI Agent for
P&C Claims Processing

A complete hands-on blueprint to build an AI-powered claims agent in n8n — from intake to routing, fraud detection, and automated payouts.

Production-Grade GPT-4o + n8n 11 Node Walkthrough Copy-Paste Ready
Part 01

Scoping the Agent

The agent receives a new insurance claim via webhook, email, or form — then extracts structured data, classifies the claim, assesses damage and risk using AI, routes it to the right handler, and updates your system of record, all autonomously.

📥

Inputs

Claim JSON from portal, supporting documents (PDFs/images), claimant policy profile, and historical claims data for fraud scoring.

📤

Outputs

Structured claim record, AI-generated summary + severity score, routing decision, claimant notification, and full audit log.

🧠

AI Stack

GPT-4o for claim analysis and Vision for document parsing. Optional: embeddings + vector DB for similarity matching.

Part 02

High-Level Architecture

[TRIGGER: Webhook POST /claims/new]
        │
        ▼
[INTAKE & VALIDATION] ── Set + IF nodes
        │
        ▼
[DOCUMENT EXTRACTION] ──────────► (OpenAI Vision / GPT-4o)
        │
        ▼
[AI CLAIM ANALYSIS] ────────────► (GPT-4o Full Analysis)
        │
        ▼
[FRAUD SCORING] ─────────────────► (Rules Engine / ML API)
        │
        ▼
[ROUTING DECISION — Switch Node]
        │
   ┌────┴────────────┬───────────────┐
   ▼                 ▼               ▼
AUTO-APPROVE    ADJUSTER QUEUE   FRAUD FLAG
[Pay + Notify]  [Assign + Alert] [Freeze + SIU]
   │                 │               │
   └────────┬────────┘               │
            ▼                        │
  [STORE CLAIM RECORD] ◄─────────────┘
            │
            ▼
  [AUDIT LOG + NOTIFICATIONS]
            │
            ▼
  [Webhook Response: 200 OK]
Auto Approve
Severity ≤ 4
Fraud < 20
Damage ≤ $5,000
🔍
Adjuster Review
Mid-range severity
Uncertain signals
Complex cases
🚨
Fraud Investigation
Fraud score ≥ 60
Suspicious flags
SIU escalation
Part 03

Node-by-Node Walkthrough

NODE 1 — Webhook Trigger Webhook

Purpose: Receives the new claim submission from your portal or external system via HTTP POST.

HTTP Method:     POST
Path:            /claims/new
Response Mode:   "Last Node"  # returns confirmation to caller
Authentication:  Header Auth  # use a secret token

Expected incoming payload:

{
  "claim_id":         "CLM-2024-00847",
  "claimant_name":    "Jane Doe",
  "policy_number":    "POL-99234",
  "incident_date":    "2024-12-01",
  "incident_type":    "auto_collision",
  "description":      "Rear-end collision on Highway 101. Significant trunk damage.",
  "documents":        ["https://storage.co/photos/CLM-2024-00847/photo1.jpg"],
  "estimated_damage": 8400
}

NODE 2 — Normalize & Enrich Set

Purpose: Standardize the incoming payload and add metadata fields before any processing begins.

claim_id:          {{ $json.claim_id }}
received_at:       {{ new Date().toISOString() }}
status:            "processing"
incident_type:     {{ $json.incident_type }}
description:       {{ $json.description }}
claimant_name:     {{ $json.claimant_name }}
policy_number:     {{ $json.policy_number }}
documents:         {{ $json.documents }}
estimated_damage:  {{ $json.estimated_damage }}

NODE 3 — Fetch Policy Details HTTP Request

Purpose: Pull the claimant's policy data from your internal API or database to validate coverage before proceeding.

Method:  GET
URL:     https://your-policy-api.com/policies/{{ $json.policy_number }}
Auth:    Bearer Token  # add in n8n Credentials
Headers:
  Content-Type: application/json

Extract via Set node after:

coverage_limit:    {{ $json.coverage_limit }}
deductible:        {{ $json.deductible }}
policy_active:     {{ $json.is_active }}
covered_incidents: {{ $json.covered_types }}

NODE 4 — Policy Validation Check IF

Purpose: Immediately reject invalid or inactive policies before wasting AI API calls.

# Both conditions must be TRUE to proceed
{{ $json.policy_active }}     equals    true
AND
{{ $json.covered_incidents }} contains {{ $json.incident_type }}

→ TRUE:  Continue to AI Analysis
→ FALSE: Send rejection email + log claim

NODE 5 — Document OCR / Vision Extraction HTTP Request

Purpose: Extract text and damage information from uploaded photos or PDFs using OpenAI Vision (GPT-4o).

{
  "model": "gpt-4o",
  "messages": [{
    "role": "user",
    "content": [
      {
        "type": "text",
        "text": "You are an insurance claims assessor. Analyze this damage photo and extract: 1) Type of damage 2) Estimated severity (low/medium/high/total-loss) 3) Visible damage description 4) Any suspicious indicators. Return as JSON."
      },
      {
        "type": "image_url",
        "image_url": { "url": "{{ $json.documents[0] }}" }
      }
    ]
  }],
  "max_tokens": 800
}

Parse response in Code node immediately after:

const content = $input.first().json.choices[0].message.content;
// Strip markdown code fences if present
const cleaned = content.replace(/```json|```/g, '').trim();
const parsed = JSON.parse(cleaned);

return [{
  json: {
    ...$input.first().json,
    vision_damage_type: parsed.damage_type,
    vision_severity:    parsed.severity,
    vision_description: parsed.description,
    vision_flags:       parsed.suspicious_indicators
  }
}];

NODE 6 — Core Claim Analysis OpenAI

Purpose: The brain of the agent — full AI analysis, claim summary, severity score, fraud score, and routing recommendation.

System Prompt:

You are a senior P&C insurance claims analyst AI. Your job is to:
1. Analyze claim details and document findings
2. Generate a professional claim summary (2-3 sentences)
3. Assign a severity score 1-10 (10 = most severe)
4. Estimate a fair payout range based on the policy and damage
5. Identify any fraud indicators (score 0-100, 100 = highly suspicious)
6. Recommend routing: "AUTO_APPROVE", "ADJUSTER_REVIEW", or "FRAUD_INVESTIGATION"

Routing rules:
- AUTO_APPROVE:        severity <= 4, fraud_score < 20, damage <= $5,000
- FRAUD_INVESTIGATION: fraud_score >= 60
- ADJUSTER_REVIEW:     everything else

Always respond in valid JSON only. No extra text.

User Message (dynamic n8n expression):

Claim ID:          {{ $json.claim_id }}
Incident Type:     {{ $json.incident_type }}
Description:       {{ $json.description }}
Estimated Damage:  ${{ $json.estimated_damage }}
Coverage Limit:    ${{ $json.coverage_limit }}
Deductible:        ${{ $json.deductible }}
Vision Analysis:   {{ $json.vision_description }}
Severity (Vision): {{ $json.vision_severity }}
Suspicious Flags:  {{ $json.vision_flags }}
Incident Date:     {{ $json.incident_date }}

Expected JSON response from GPT:

{
  "summary":              "Claimant reports rear-end collision causing significant trunk damage...",
  "severity_score":       6,
  "fraud_score":          12,
  "estimated_payout_min": 7200,
  "estimated_payout_max": 8800,
  "routing":              "ADJUSTER_REVIEW",
  "notes":               "Damage aligns with described incident. No major fraud indicators."
}

Parse in Code node after:

const raw = $input.first().json.message?.content ||
            $input.first().json.choices?.[0]?.message?.content;
const cleaned = raw.replace(/```json|```/g, '').trim();
const ai = JSON.parse(cleaned);

return [{
  json: {
    ...$input.first().json,
    ai_summary:     ai.summary,
    severity_score: ai.severity_score,
    fraud_score:    ai.fraud_score,
    payout_min:     ai.estimated_payout_min,
    payout_max:     ai.estimated_payout_max,
    routing:        ai.routing,
    ai_notes:       ai.notes
  }
}];

NODE 7 — Routing Decision Switch

Purpose: Branch the workflow into three distinct paths based on the AI's routing recommendation.

Value to switch on: {{ $json.routing }}

Route 1: AUTO_APPROVE
Route 2: ADJUSTER_REVIEW
Route 3: FRAUD_INVESTIGATION
Default: ADJUSTER_REVIEW

NODE 8A — Auto Approve Branch Code HTTP

8A-1: Calculate Final Payout

const deductible   = $json.deductible || 0;
const midpoint     = ($json.payout_min + $json.payout_max) / 2;
const final_payout = Math.max(0, midpoint - deductible);

return [{ json: { ...$json, final_payout, approval_status: "APPROVED" } }];

8A-2: Trigger Payment API

// POST https://your-claims-system.com/api/payments
{
  "claim_id": "{{ $json.claim_id }}",
  "amount":   {{ $json.final_payout }},
  "policy":   "{{ $json.policy_number }}"
}

8A-3: Email Claimant

To:      {{ $json.claimant_email }}
Subject: Your Claim {{ $json.claim_id }} Has Been Approved

Hi {{ $json.claimant_name }},

Your claim has been approved. A payout of
${{ $json.final_payout }} will be processed within 2 business days.

Summary: {{ $json.ai_summary }}

NODE 8B — Adjuster Review Branch HTTP

8B-1: Create Ticket (Jira / ServiceNow / Salesforce)

{
  "title":            "Claim Review: {{ $json.claim_id }}",
  "priority":         "{{ $json.severity_score > 7 ? 'HIGH' : 'NORMAL' }}",
  "description":      "{{ $json.ai_summary }}",
  "estimated_payout": "${{ $json.payout_min }} – ${{ $json.payout_max }}",
  "assigned_queue":   "claims_adjusters"
}

8B-2: Slack Alert to Adjuster Team

Channel: #claims-queue

🔍 *New Claim for Review*
Claim:       {{ $json.claim_id }} | Severity: {{ $json.severity_score }}/10
Claimant:    {{ $json.claimant_name }}
Est. Payout: ${{ $json.payout_min }}–${{ $json.payout_max }}
AI Notes:    {{ $json.ai_notes }}

NODE 8C — Fraud Investigation Branch Set

8C-1: Flag the Claim

fraud_flagged:        true
freeze_payment:       true
investigation_status: "OPEN"

8C-2: Immediate Fraud Alert to Slack

Channel: #fraud-alerts

🚨 *FRAUD ALERT — Claim {{ $json.claim_id }}*
Fraud Score:  {{ $json.fraud_score }}/100
Claimant:     {{ $json.claimant_name }}
Vision Flags: {{ $json.vision_flags }}
⚠️ Immediate review required — payment frozen.
🔒
SIU EscalationFollow with an HTTP Request to freeze the claim in your claims management system and create a Special Investigations Unit (SIU) ticket automatically.

NODE 9 — Store Claim Record Google Sheets

Purpose: Persist every claim with full AI analysis for audit, reporting, and future model retraining.

Operation: Append Row
Sheet:     Claims_Log

Column Mapping:
  A: claim_id       B: received_at    C: claimant_name
  D: policy_number  E: incident_type  F: severity_score
  G: fraud_score    H: routing        I: final_payout
  J: ai_summary     K: status         L: vision_severity

NODE 10 — Error Handling Code

Step 1: On any node → Settings → "On Error" → set to "Continue (using error output)"

Step 2: Add an Error Trigger node at the workflow level.

Step 3: Format error in Code node:

const error = $input.first().json;
return [{
  json: {
    workflow:      "P&C Claims Agent",
    error_message: error.error?.message || "Unknown error",
    node:          error.node?.name,
    claim_id:      error.execution?.data?.claim_id || "UNKNOWN",
    timestamp:     new Date().toISOString()
  }
}];

Step 4: Route to #errors Slack channel and log to a Google Sheets error tab.

NODE 11 — Retry Logic Code + Wait

const retryCount = $json.retry_count || 0;

if (retryCount >= 3) {
  throw new Error(`Max retries reached for claim ${$json.claim_id}`);
}

return [{
  json: {
    ...$json,
    retry_count: retryCount + 1
  }
}];
💡
Wait Node PatternAdd a Wait node set to 30 seconds after this Code node, then loop back to the failing HTTP Request via an IF check on retry_count.

Part 04

Memory & Data Persistence

Short-Term Memory: n8n automatically passes data between nodes. Use Set nodes liberally to carry all needed fields forward through every branch.

Option A — Redis (Fast Key-Value) HTTP Request

# Store fraud patterns and past decisions per policy
Key:   "claim_history:{{ $json.policy_number }}"
Value: JSON.stringify(claimRecord)
TTL:   2592000  # 30 days in seconds

Option B — Pinecone / Qdrant (Vector DB) HTTP Request

# Step 1 — Embed the claim description
POST https://api.openai.com/v1/embeddings
{ "input": "{{ $json.description }}", "model": "text-embedding-3-small" }

# Step 2 — Query Pinecone for top-5 similar past claims
POST https://your-index.pinecone.io/query
{ "vector": [...embedding], "topK": 5, "includeMetadata": true }

# Step 3 — Inject similar claims into GPT prompt for RAG
📊
Option C — Google Sheets (Simplest)Already covered in Node 9. Best for getting started — upgrade to Supabase or Redis when volume grows beyond ~10K rows.
Part 05

Authentication Setup

ServiceAuth Typen8n Setup Path
OpenAIAPI KeyCredentials → OpenAI API → paste key
Google SheetsOAuth2Credentials → Google Sheets OAuth2
SlackOAuth2Credentials → Slack OAuth2
Policy Internal APIBearer TokenHeader Auth → Authorization: Bearer <token>
PineconeAPI KeyHTTP Header Auth → Api-Key: <key>
Salesforce / CRMOAuth2Credentials → Salesforce OAuth2
🔑
Pro Tip — Credentials VaultStore ALL secrets in n8n's Credentials vault. Never hardcode API keys in node settings or JavaScript. Reference dynamically as {{ $credentials.apiKey }}.
Part 06

Complete Workflow Summary

[Webhook: POST /claims/new]
        │
[Set: Normalize fields]
        │
[HTTP: Fetch Policy from API]
        │
[IF: Policy valid + covered?]
   │              │
[YES]      [NO → Email Rejection + Log]
   │
[HTTP: OpenAI Vision → Damage Analysis]
        │
[Code: Parse Vision JSON]
        │
[OpenAI: Full Claim Analysis]
        │
[Code: Parse AI JSON + enrich fields]
        │
[Switch: {{ $json.routing }}]
   │           │           │
[AUTO]    [ADJUSTER]   [FRAUD]
   │           │           │
[Calc      [CRM Ticket]  [Freeze +
 Payout]   [Slack Alert]  SIU Alert]
[Pay API]
[Email]
   │
[ALL PATHS MERGE]
        │
[Google Sheets: Append Claim Log]
        │
[Webhook Response: 200 OK + { claim_id }]
Part 07

Making the Agent More Powerful

🔗

Chain Sub-Workflows

Split into modular Execute Workflow nodes: Document Extraction, Fraud Analysis, Payout Calc, Notifications — each independently testable.

📡

Multi-Channel Intake

IMAP email trigger, Twilio SMS, WhatsApp webhook, and mobile app POST — all routing into the same processing pipeline.

🧠

Persistent AI Memory

Supabase + pgvector or Pinecone to detect serial filers, benchmark payouts, and feed RAG context into GPT.

📊

Live Dashboard

Connect Google Sheets to Looker Studio or push to Supabase — track resolution time, fraud rate, auto-approval rate.

🤖

Human-in-the-Loop

Email adjuster an Approve/Reject link → Wait node pauses until clicked → resume with their decision token.

🛡️

PII Masking

Code node before every OpenAI call redacts claimant names, masks policy numbers — keeps sensitive data out of AI logs.

PII Masking — Copy-Paste Code Code

// Run this Code node BEFORE any OpenAI call
const masked = {
  ...$json,
  claimant_name:  "REDACTED",
  policy_number: $json.policy_number.replace(/.(?=.{4})/g, '*')
};
return [{ json: masked }];

Scheduled Reprocessing Cron

# Cron trigger use cases:
 Re-run stale claims in ADJUSTER_REVIEW > 48 hours
 Generate daily fraud pattern summary reports
 Sync claim statuses from external systems every 4 hours

Checklist

Quick-Start Build Order

Build in this order — validate each stage before layering in the next.

🚀
Start Small, Scale FastBegin with the 5-node core loop (Webhook → Validate → OpenAI Analysis → Switch → Log), verify it works end-to-end with test data, then layer in branches, error handling, and memory. Treat it like assembling modules — not one big monolith.