Back to Guides
Claims Processing
Claims Adjudication Guide
Complete guide to healthcare claims adjudication engine design. Learn payment calculation, denial codes, coordination of benefits, and automated processing rules.
Claims Adjudication Process
1
Receipt & Validation
Claim received via EDI 837, validated for format and required fields
2
Eligibility Check
Verify patient coverage active on service date
3
Duplicate Detection
Check for duplicate submissions using service date + provider + patient
4
Prior Authorization
Verify PA exists if required for service
5
Medical Necessity
Validate diagnosis codes support procedure codes
6
Pricing
Apply contracted rates, fee schedule, or usual & customary
7
COB
Coordinate benefits if patient has multiple policies
8
Patient Responsibility
Calculate deductible, copay, coinsurance
9
Payment Decision
Approve, deny, or pend for manual review
10
Remittance
Generate ERA/EOB (EDI 835) with payment details
Adjudication Database Schema
-- Claim Adjudication
CREATE TABLE claim_adjudication (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
claim_id UUID NOT NULL REFERENCES claim(id),
claim_line_id UUID REFERENCES claim_line(id),
-- Adjudication Status
adjudication_status VARCHAR(50), -- approved, denied, pended
adjudication_date TIMESTAMP NOT NULL DEFAULT NOW(),
-- Amounts
billed_amount DECIMAL(10,2) NOT NULL,
allowed_amount DECIMAL(10,2),
deductible_amount DECIMAL(10,2) DEFAULT 0,
copay_amount DECIMAL(10,2) DEFAULT 0,
coinsurance_amount DECIMAL(10,2) DEFAULT 0,
cob_amount DECIMAL(10,2) DEFAULT 0, -- Paid by other insurance
paid_amount DECIMAL(10,2),
patient_responsibility DECIMAL(10,2),
-- Adjustments
adjustment_amount DECIMAL(10,2) DEFAULT 0,
adjustment_reason VARCHAR(10), -- CARC code
-- Denial
denial_code VARCHAR(10), -- CARC code
denial_reason TEXT,
remark_code VARCHAR(10), -- RARC code
-- Pricing
contract_rate DECIMAL(10,2),
fee_schedule_rate DECIMAL(10,2),
pricing_method VARCHAR(50), -- contracted, fee_schedule, UCR
-- Processing
auto_adjudicated BOOLEAN DEFAULT FALSE,
reviewer_id UUID,
review_notes TEXT,
created_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX idx_adj_claim ON claim_adjudication(claim_id);
CREATE INDEX idx_adj_status ON claim_adjudication(adjudication_status);
-- Payment Calculation Rules
CREATE TABLE adjudication_rule (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
rule_name VARCHAR(255) NOT NULL,
rule_type VARCHAR(50), -- eligibility, pricing, medical_necessity
priority INTEGER,
-- Conditions (JSON for flexibility)
conditions JSONB, -- e.g., {"service_type": "surgery", "place_of_service": "11"}
-- Actions
action_type VARCHAR(50), -- approve, deny, pend, adjust
action_config JSONB, -- Action parameters
-- Status
active BOOLEAN DEFAULT TRUE,
effective_date DATE,
termination_date DATE,
created_at TIMESTAMP DEFAULT NOW()
);
-- Denial Codes Reference
CREATE TABLE denial_code (
code VARCHAR(10) PRIMARY KEY,
code_type VARCHAR(10), -- CARC, RARC
description TEXT,
category VARCHAR(100), -- CO, OA, PR, PI
patient_responsibility BOOLEAN,
created_at TIMESTAMP DEFAULT NOW()
);
-- Coordination of Benefits
CREATE TABLE cob_calculation (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
claim_id UUID NOT NULL REFERENCES claim(id),
-- Primary Insurance
primary_payer_id UUID,
primary_allowed DECIMAL(10,2),
primary_paid DECIMAL(10,2),
-- Secondary Insurance
secondary_payer_id UUID,
secondary_allowed DECIMAL(10,2),
secondary_paid DECIMAL(10,2),
-- Tertiary (if applicable)
tertiary_payer_id UUID,
tertiary_paid DECIMAL(10,2),
-- Total
total_paid DECIMAL(10,2),
patient_balance DECIMAL(10,2),
calculated_date TIMESTAMP DEFAULT NOW()
);Payment Calculation Logic
Step-by-Step Calculation
Example Claim:
Billed Amount: $500.00
Contracted Rate: $350.00
Deductible Remaining: $100.00
Coinsurance: 20%
Copay: $20.00
1. Allowed Amount$350.00
2. Apply Deductible-$100.00
Remaining After Deductible$250.00
3. Apply Coinsurance (20% × $250)-$50.00
4. Apply Copay-$20.00
Insurance Pays$180.00
Patient Owes$170.00
Common Denial Codes
| Code | Category | Description |
|---|---|---|
| CO-16 | Contractual | Claim lacks information needed for adjudication |
| CO-50 | Contractual | Non-covered charges |
| PR-1 | Patient | Deductible amount |
| PR-2 | Patient | Coinsurance amount |
| OA-23 | Other | Impact of prior payer adjudication |
| CO-97 | Contractual | Benefit for this service included in another service |
Category Codes: CO = Contractual Obligation, PR = Patient Responsibility, OA = Other Adjustment, PI = Payer Initiated
SQL Query Examples
Calculate Payment for Claim
WITH claim_totals AS (
SELECT
c.id as claim_id,
SUM(cl.charge_amount) as billed_amount,
SUM(ca.allowed_amount) as allowed_amount,
SUM(ca.deductible_amount) as deductible,
SUM(ca.copay_amount) as copay,
SUM(ca.coinsurance_amount) as coinsurance,
SUM(ca.paid_amount) as insurance_paid
FROM claim c
JOIN claim_line cl ON c.id = cl.claim_id
LEFT JOIN claim_adjudication ca ON cl.id = ca.claim_line_id
WHERE c.claim_number = 'CLM123456'
GROUP BY c.id
)
SELECT
billed_amount,
allowed_amount,
allowed_amount - billed_amount as adjustment,
deductible + copay + coinsurance as patient_responsibility,
insurance_paid
FROM claim_totals;Top Denial Reasons
SELECT dc.code, dc.description, COUNT(*) as denial_count, SUM(ca.billed_amount) as total_denied_amount FROM claim_adjudication ca JOIN denial_code dc ON ca.denial_code = dc.code WHERE ca.adjudication_date >= CURRENT_DATE - INTERVAL '30 days' AND ca.adjudication_status = 'denied' GROUP BY dc.code, dc.description ORDER BY denial_count DESC LIMIT 10;