Prior Authorization Guide
Complete guide to prior authorization (PA) workflows and database design. Learn approval processes, payer integration, denial management, and automation strategies for healthcare systems.
What is Prior Authorization?
Prior authorization (PA) is a utilization management process where healthcare providers must obtain approval from a patient's insurance payer before delivering specific services, procedures, or medications. The payer reviews medical necessity and coverage criteria before authorizing payment.
PA aims to reduce unnecessary healthcare spending and ensure evidence-based care. However, it creates administrative burden, with providers spending an average of 14 hours per week on PA requests. Automated systems and standardized workflows can significantly reduce this burden.
Prior Authorization Workflow
Service Ordered
Provider orders service requiring PA (e.g., MRI, specialty drug)
PA Check
System checks if service requires PA based on payer rules
Request Submission
Submit PA request to payer with clinical documentation
Payer Review
Payer reviews against medical necessity criteria
Decision
Approved, denied, or more information requested
Service Delivery
If approved, service delivered and claim submitted
Prior Authorization Database Schema
-- Prior Authorization Request CREATE TABLE prior_authorization ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), -- Identifiers pa_number VARCHAR(50) UNIQUE NOT NULL, patient_id UUID NOT NULL, encounter_id UUID, -- Request Details service_type VARCHAR(100), -- MRI, surgery, medication procedure_code VARCHAR(10), -- CPT code diagnosis_codes TEXT[], -- ICD-10 array drug_ndc VARCHAR(20), -- For pharmacy PA -- Clinical medical_necessity TEXT, clinical_notes TEXT, supporting_docs TEXT[], -- Document URLs -- Provider requesting_provider UUID, rendering_provider UUID, facility_id UUID, -- Payer payer_id UUID NOT NULL, payer_pa_id VARCHAR(100), -- Payer's tracking number member_id VARCHAR(100), -- Dates service_start_date DATE, service_end_date DATE, requested_date TIMESTAMP NOT NULL DEFAULT NOW(), response_due_date DATE, -- Status status VARCHAR(50), -- pending, approved, denied, expired urgency VARCHAR(20), -- routine, urgent, emergency -- Decision decision_date TIMESTAMP, decision_reason TEXT, approval_number VARCHAR(100), approved_units INTEGER, -- Units/visits approved valid_from DATE, valid_through DATE, -- Contact contact_name VARCHAR(255), contact_phone VARCHAR(20), -- Metadata created_at TIMESTAMP DEFAULT NOW(), updated_at TIMESTAMP DEFAULT NOW() ); CREATE INDEX idx_pa_patient ON prior_authorization(patient_id); CREATE INDEX idx_pa_status ON prior_authorization(status); CREATE INDEX idx_pa_payer ON prior_authorization(payer_id); CREATE INDEX idx_pa_requested ON prior_authorization(requested_date); -- PA Status History (Audit Trail) CREATE TABLE pa_status_history ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), pa_id UUID NOT NULL REFERENCES prior_authorization(id), -- Status Change previous_status VARCHAR(50), new_status VARCHAR(50) NOT NULL, status_date TIMESTAMP NOT NULL DEFAULT NOW(), -- Details changed_by UUID, change_reason TEXT, notes TEXT, -- Payer Communication payer_reference VARCHAR(100), created_at TIMESTAMP DEFAULT NOW() ); CREATE INDEX idx_pa_history_pa ON pa_status_history(pa_id); -- PA Appeals CREATE TABLE pa_appeal ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), pa_id UUID NOT NULL REFERENCES prior_authorization(id), -- Appeal Details appeal_number VARCHAR(50) UNIQUE, appeal_type VARCHAR(50), -- first-level, peer-to-peer, external appeal_reason TEXT, additional_docs TEXT[], -- Dates submitted_date TIMESTAMP NOT NULL DEFAULT NOW(), response_due_date DATE, decision_date TIMESTAMP, -- Decision appeal_status VARCHAR(50), appeal_decision VARCHAR(50), -- upheld, overturned, partially approved decision_notes TEXT, -- Peer-to-Peer peer_review_date TIMESTAMP, peer_reviewer VARCHAR(255), created_at TIMESTAMP DEFAULT NOW(), updated_at TIMESTAMP DEFAULT NOW() ); CREATE INDEX idx_appeal_pa ON pa_appeal(pa_id); CREATE INDEX idx_appeal_status ON pa_appeal(appeal_status); -- PA Requirements (Payer Rules) CREATE TABLE pa_requirement ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), payer_id UUID NOT NULL, plan_type VARCHAR(100), -- Service service_category VARCHAR(100), procedure_code VARCHAR(10), -- CPT code requiring PA -- Criteria requires_pa BOOLEAN DEFAULT TRUE, auto_approve_criteria JSONB, -- Rules for auto-approval documentation_needed TEXT[], -- Timing advance_notice_days INTEGER, -- Must submit X days before decision_timeframe INTEGER, -- Payer must decide in X days -- Status effective_date DATE NOT NULL, termination_date DATE, created_at TIMESTAMP DEFAULT NOW() ); CREATE INDEX idx_req_payer ON pa_requirement(payer_id); CREATE INDEX idx_req_procedure ON pa_requirement(procedure_code);
Common Denial Reasons
Administrative Denials
- • Incomplete documentation
- • Wrong payer contacted
- • Patient not covered
- • Service not covered by plan
- • Timely filing missed
Clinical Denials
- • Medical necessity not met
- • Step therapy not followed
- • Less expensive alternative exists
- • Experimental/investigational
- • Insufficient clinical evidence
SQL Query Examples
Find Pending PAs Approaching Deadline
SELECT pa.pa_number, p.first_name || ' ' || p.last_name as patient_name, pa.service_type, pa.requested_date, pa.response_due_date, pa.response_due_date - CURRENT_DATE as days_until_due, pyr.payer_name FROM prior_authorization pa JOIN patient p ON pa.patient_id = p.id JOIN payer pyr ON pa.payer_id = pyr.id WHERE pa.status = 'pending' AND pa.response_due_date <= CURRENT_DATE + INTERVAL '3 days' ORDER BY pa.response_due_date;
PA Approval Rate by Payer
SELECT
pyr.payer_name,
COUNT(*) as total_requests,
SUM(CASE WHEN pa.status = 'approved' THEN 1 ELSE 0 END) as approved,
SUM(CASE WHEN pa.status = 'denied' THEN 1 ELSE 0 END) as denied,
ROUND(100.0 * SUM(CASE WHEN pa.status = 'approved' THEN 1 ELSE 0 END) / COUNT(*), 2) as approval_rate,
AVG(EXTRACT(DAY FROM pa.decision_date - pa.requested_date)) as avg_days_to_decision
FROM prior_authorization pa
JOIN payer pyr ON pa.payer_id = pyr.id
WHERE pa.requested_date >= CURRENT_DATE - INTERVAL '90 days'
AND pa.status IN ('approved', 'denied')
GROUP BY pyr.payer_name
ORDER BY approval_rate DESC;Automation Strategies
Electronic Prior Authorization (ePA)
Use CRD (Coverage Requirements Discovery) and DTR (Documentation Templates and Rules) to check PA requirements in real-time within EHR workflow.
Define criteria for automatic approval (e.g., routine imaging for patients meeting clinical guidelines). Reduces manual review by 30-40%.
Template-based forms that capture required fields, reducing denials due to incomplete information.
Automated alerts when PA status changes or deadlines approach. Integration with EHR task lists.