StarlightContact Us
2026-03-02·9 min read

Pharmacy Switch API Integration Guide

If you're building software that needs to submit pharmacy claims, you need to connect to the pharmacy claims network through a pharmacy switch. This guide covers the architecture, authentication, error handling, and best practices for both the traditional integration path and the Starlight API approach.

Architecture overview

The pharmacy claims data flow is straightforward once you see the full picture. Every claim passes through the same layers:

Your Application
↓ JSON (Starlight) or NCPDP binary (traditional)
Starlight API / Direct Switch Connection
↓ NCPDP Telecom D.0
Pharmacy Switch (RelayHealth, Change Healthcare, etc.)
↓ NCPDP Telecom D.0
PBM / Insurance Company
↓ Adjudication response
...back through the chain to your app

With the traditional approach, you implement everything above "Pharmacy Switch." With Starlight, you implement everything above "Starlight API," which is just standard HTTP.

Traditional switch integration

Integrating directly with a pharmacy switch requires several components:

Network connectivity

Dedicated VPN or private line to the switch. Some switches offer internet connectivity with TLS, but many still require VPN tunnels with specific configurations.

NCPDP encoder/decoder

A library that converts your internal data model to NCPDP Telecom binary format and back. You'll need to handle all segment types, field identifiers, and data types defined in the spec.

Transaction manager

Claims are synchronous request/response over persistent connections. You need connection pooling, timeout handling, and retry logic for network failures.

Payer configuration

Each PBM has slightly different field requirements. You'll maintain a database of per-payer rules that dictate which fields to send, required vs optional, and payer-specific validation rules.

Starlight API integration

Starlight replaces the entire traditional stack with a standard REST API. Here's what the integration looks like:

Step 1: Authentication

Every request uses the X-API-Key header. Your API key is scoped to your organization and environment:

X-API-Key: your_live_api_key

# Sandbox environment
X-API-Key: your_sandbox_api_key

Step 2: Submit a claim

Send a POST request with the claim data as JSON. The API documentation defines every field, but here's the minimal structure:

POST /v1/submit
Content-Type: application/json
X-API-Key: your_api_key

{
  "transaction_type": "B1",
  "patient": { "first_name": "...", "last_name": "...", ... },
  "insurance": { "bin_number": "...", "pcn": "...", "cardholder_id": "...", ... },
  "prescription": { "product_id": "...", "quantity_dispensed": "...", ... },
  "pricing": { "gross_amount_due": "..." }
}

Step 3: Handle the response

Parse the JSON response and branch on the response status:

// Response status values:
// "A" = Accepted (claim paid)
// "R" = Rejected (check rejectCodes[])
// "D" = Duplicate (claim already processed)
// "C" = Captured (deferred adjudication)

if (response.header.responseStatus === "A") {
  // Claim paid - show patient copay
  const copay = response.pricing.patientPayAmount;
} else if (response.header.responseStatus === "R") {
  // Rejected - handle reject codes
  for (const reject of response.rejectCodes) {
    console.log(reject.code, reject.description);
  }
}

Error handling best practices

There are two categories of errors: API-level errors (HTTP 4xx/5xx) and claim-level rejections (HTTP 200 with rejection data). Handle both:

  • 400 Bad Request: malformed JSON or missing required fields. Fix your request before retrying.
  • 401 Unauthorized: invalid or expired API key.
  • 429 Too Many Requests: rate limit hit. Back off and retry with exponential delay.
  • 500/503: server error or switch downtime. Retry with backoff. These are transient.
  • 200 with responseStatus "R": the claim reached the PBM but was rejected. Do NOT retry without changing the claim data.

Critical rule: never auto-retry a rejected claim (status "R") without human review or logic changes. The PBM rejected it for a reason. Resubmitting the same data will get the same result and may flag your account.

Idempotency and duplicate prevention

Pharmacy claims are financially significant. A duplicate submission means a patient might be charged twice. Starlight supports idempotency keys to prevent this:

POST /v1/claims/b1
Idempotency-Key: rx-7891011-20260302-001
Content-Type: application/json

If the same idempotency key is sent within 24 hours, you'll receive the original response without reprocessing the claim. Use a combination of prescription number, date of service, and a sequence counter for your key.

Production readiness checklist

Before going live with real claims, verify:

  • All claim types tested in sandbox (B1 billing, B2 reversal, E1 eligibility)
  • Rejection handling covers the top 20 NCPDP reject codes
  • Idempotency keys implemented to prevent duplicate claims
  • Retry logic with exponential backoff for transient errors
  • Audit logging captures full request/response for compliance
  • Timeout handling: claims should timeout after 30 seconds
  • PHI encryption at rest and in transit (TLS 1.2+)

Ready to integrate?

Get started with our sandbox environment. Submit test claims in minutes, go live when you're ready.