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
Receipt & Validation
Claim received via EDI 837, validated for format and required fields
Eligibility Check
Verify patient coverage active on service date
Duplicate Detection
Check for duplicate submissions using service date + provider + patient
Prior Authorization
Verify PA exists if required for service
Medical Necessity
Validate diagnosis codes support procedure codes
Pricing
Apply contracted rates, fee schedule, or usual & customary
COB
Coordinate benefits if patient has multiple policies
Patient Responsibility
Calculate deductible, copay, coinsurance
Payment Decision
Approve, deny, or pend for manual review
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(),
clm_id UUID NOT NULL REFERENCES claim(id),
clm_line_id UUID REFERENCES claim_line(id),
-- Adjudication Status
adjudication_status VARCHAR(50), -- approved, denied, pended
adjudication_dt TIMESTAMP NOT NULL DEFAULT NOW(),
-- Amounts
billed_amt DECIMAL(10,2) NOT NULL,
allowed_amt DECIMAL(10,2),
deductible_amt DECIMAL(10,2) DEFAULT 0,
copay_amt DECIMAL(10,2) DEFAULT 0,
coinsurance_amt DECIMAL(10,2) DEFAULT 0,
cob_amt DECIMAL(10,2) DEFAULT 0, -- Paid by other insurance
paid_amt DECIMAL(10,2),
patient_responsibility DECIMAL(10,2),
-- Adjustments
adjustment_amt 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(clm_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_nm 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_dt DATE,
termination_dt 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(),
clm_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_dt TIMESTAMP DEFAULT NOW()
);Payment Calculation Logic
Step-by-Step Calculation
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 |
SQL Query Examples
Calculate Payment for Claim
WITH clm_totals AS (
SELECT
c.id as clm_id,
SUM(cl.charge_amt) as billed_amt,
SUM(ca.allowed_amt) as allowed_amt,
SUM(ca.deductible_amt) as deductible,
SUM(ca.copay_amt) as copay,
SUM(ca.coinsurance_amt) as coinsurance,
SUM(ca.paid_amt) as insurance_paid
FROM claim c
JOIN claim_line cl ON c.id = cl.clm_id
LEFT JOIN claim_adjudication ca ON cl.id = ca.clm_line_id
WHERE c.clm_number = 'CLM123456'
GROUP BY c.id
)
SELECT
billed_amt,
allowed_amt,
allowed_amt - billed_amt 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_amt) as total_denied_amt FROM claim_adjudication ca JOIN denial_code dc ON ca.denial_code = dc.code WHERE ca.adjudication_dt >= CURRENT_DATE - INTERVAL '30 days' AND ca.adjudication_status = 'denied' GROUP BY dc.code, dc.description ORDER BY denial_count DESC LIMIT 10;
Related Healthcare Guides
Browse Related Definitions
From the Blog
Healthcare Revenue Cycle Data: Complete Analytics Guide for Data Architects and Engineers
17 min readRead Claims & AdjudicationHealthcare Claims Data: Complete Guide for Data Architects and Engineers
15 min readRead Pharmacy DataPharmacy Data Model: Prescription & Dispensing Schema Guide
11 min readReadBrowse all healthcare data guides