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:
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.