Back to Guides
Utilization Management

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

1

Service Ordered

Provider orders service requiring PA (e.g., MRI, specialty drug)

2

PA Check

System checks if service requires PA based on payer rules

3

Request Submission

Submit PA request to payer with clinical documentation

4

Payer Review

Payer reviews against medical necessity criteria

5

Decision

Approved, denied, or more information requested

6

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)

FHIR-Based PA:

Use CRD (Coverage Requirements Discovery) and DTR (Documentation Templates and Rules) to check PA requirements in real-time within EHR workflow.

Auto-Approval Rules:

Define criteria for automatic approval (e.g., routine imaging for patients meeting clinical guidelines). Reduces manual review by 30-40%.

Smart Documentation:

Template-based forms that capture required fields, reducing denials due to incomplete information.

Status Tracking:

Automated alerts when PA status changes or deadlines approach. Integration with EHR task lists.

Related Healthcare Guides