NCPDP SCRIPT Standard: e-Prescribing Guide (2026)
CTO & Co-Founder
CTO & Co-Founder at Nirmitee.io. Architects healthcare integrations across FHIR, SMART on FHIR, ABDM and NHCX, writing from production experience taking hospital software from sandbox to go-live.

What are the key NCPDP SCRIPT facts?
NCPDP writes the U.S. pharmacy data standards. SCRIPT carries prescriptions, and Telecommunication carries pharmacy claims. Medicare Part D requires SCRIPT, with version 2023011 the only one allowed from January 1, 2028. Surescripts routes most e-prescriptions, DEA rules govern controlled substances, and the specifications themselves are for NCPDP members.
| Fact | Detail | Source |
|---|---|---|
| Who writes the standards | NCPDP, an ANSI-accredited, not-for-profit membership organization | 89 FR 51238 (June 17, 2024) |
| Prescriptions | NCPDP SCRIPT, versions 2017071 and 2023011 named in federal rules | 42 CFR 423.160(c) |
| Pharmacy claims | NCPDP Telecommunication, version D.0 today, F6 next | 45 CFR part 162; NCPDP HIPAA page |
| The network | Surescripts checks and routes e-prescriptions; software must pass its certification first | Surescripts E-Prescribing FAQ |
| Controlled substances | DEA rules for electronic prescriptions, plus a Part D electronic prescribing requirement | 21 CFR part 1311; 42 CFR 423.160(a)(5) |
| Who can read the specs | NCPDP members; non-members pay a fee. Field-level detail is in the member-only implementation guide. | NCPDP Access to Standards; 89 FR 51242 |
The dates are in the plain-English timeline and, with every rule citation, in Part 2.
Who is this guide for, and where should you start?
This guide is for anyone who needs to understand or build U.S. e-prescribing. Part 1 serves founders, pharmacy owners, product managers, operations and compliance staff, in plain English with no field names. Part 2 serves engineers and architects, with messages, XML examples, certification and testing. The FAQ answers the short questions.
| If you are... | Start with |
|---|---|
| New to the topic | What is NCPDP? and How an e-prescription travels |
| A founder or product lead | Business use cases, Limitations, Cost and certification |
| A pharmacy owner or pharmacist | Your NCPDP number, What to ask your software vendor |
| Compliance or operations | Deadlines, EPCS requirements |
| An integration engineer | What a SCRIPT message looks like, Message catalog, How to integrate, Edge cases |
We follow one prescription through the whole guide. A patient we'll call Ana takes lisinopril 10 mg for blood pressure. Her doctor sends a 30-day prescription to her local pharmacy.
If you are scoping a build, our pharmacy integration page explains how we work with pharmacy and e-prescribing products.
Part 1: For everyone
What is NCPDP?
NCPDP stands for the National Council for Prescription Drug Programs. It is an ANSI-accredited, not-for-profit membership organization that writes the data standards U.S. pharmacies, prescribers, drug plans and software vendors use to exchange prescription and pharmacy claim information. Federal rules for Medicare and HIPAA name its standards, so most of the industry must use them.
Think of NCPDP as the group that agrees on the shape of the paperwork. It doesn't run a network and it doesn't move prescriptions. It publishes the rules for how a prescription or a claim must be written so that any system can read it. ANSI accreditation means it writes standards through an open, consensus-based process.
What is an NCPDP number, and how does a pharmacy keep it current?
An NCPDP number, also called the NCPDP Provider ID, is a 7-character ID that NCPDP assigns to each licensed U.S. pharmacy. CMS data dictionaries describe it this way and note that in the NCPDP database it used to be called the NABP number. Plans and networks use it to identify the pharmacy.
Pharmacies keep their own record current through NCPDP's pharmacy profile, which NCPDP's sign-in page at sso.ncpdp.org describes as the place to update and maintain pharmacy information. NCPDP sells the resulting pharmacy database to subscribers as dataQ.
Is NCPDP the same as NABP?
No. NABP is the National Association of Boards of Pharmacy, a different organization. The only overlap is the old name of the pharmacy ID.
Why does NCPDP exist?
NCPDP exists because thousands of pharmacies, drug plans and prescriber systems need one shared format to exchange prescriptions and claims. Without one, every pair of systems would need its own custom link. Federal law later made NCPDP's formats mandatory: HIPAA for pharmacy claims and Medicare Part D for e-prescribing.
A pharmacy that bills ten plans could otherwise face ten claim layouts, and a doctor's system that sends prescriptions to thousands of pharmacies faces the same problem. A common format turns that tangle into one format everyone writes and reads.
HIPAA, the 1996 health privacy and transactions law, requires plans and providers to use the transaction standards HHS adopts, and HHS adopted NCPDP's Telecommunication standard for retail pharmacy claims. The 2003 Medicare Modernization Act created the Part D e-prescribing program, and CMS named NCPDP SCRIPT for it. CMS lists SCRIPT 5.0 as the first foundation standard, effective January 1, 2006.
What are the main types of NCPDP standards?
NCPDP publishes about forty standards and guides. Five matter most for e-prescribing and pharmacy products: SCRIPT for prescriptions, Telecommunication for real-time pharmacy claims, Batch for claims sent in files, Formulary and Benefit for drug coverage lists, and Real-Time Prescription Benefit for live price and coverage checks.
| Standard | What it does | Who uses it |
|---|---|---|
| SCRIPT | Prescriptions and the conversation about them | Doctors' systems, pharmacies, networks, plans |
| Telecommunication | The pharmacy's claim to the drug plan, answered in seconds | Pharmacies, drug plans and PBMs |
| Batch | The same claims, sent many at once in a file | Pharmacies, claims processors |
| Formulary and Benefit | Which drugs a plan covers, shown in the doctor's system | Plans and PBMs, EHR vendors |
| Real-Time Prescription Benefit | This patient's price and cheaper options, at the moment of prescribing | EHRs, plans, PBMs |
A PBM is a pharmacy benefit manager, the company that runs the drug benefit for a health plan. The full list of standards is in Part 2.
What is the NCPDP SCRIPT standard?
The NCPDP SCRIPT standard is the message format for electronic prescriptions in the United States. It defines how a prescriber's system sends a new prescription, how a pharmacy asks for a change or a renewal, how either side cancels or reports a fill, and how medication history and prior authorization requests move.
For Ana, SCRIPT is the envelope and the form inside it. The doctor's system fills in the drug, strength, quantity, directions, patient and pharmacy, then sends it as a message called NewRx. The pharmacy system finds the same facts in the same places, so nobody retypes anything.
SCRIPT has versions with date-style names: 2017071 was approved in 2017 and 2023011 in January 2023. Federal rules say which version each group must use and when.
What is the NCPDP Telecommunication standard, and how is it different from SCRIPT?
The NCPDP Telecommunication standard carries pharmacy claims to drug plans in real time: the pharmacy asks the plan to pay, and the plan answers paid or rejected. SCRIPT carries the prescription between prescriber and pharmacy. Version D.0 is the current HIPAA claim standard, and HHS has adopted version F6 to replace it.
For Ana, two different conversations happen. The doctor's system sends the prescription to the pharmacy using SCRIPT. Then, at the counter, the pharmacy system sends a Telecommunication claim to Ana's plan to learn what the plan pays and what Ana owes.
The two meet in one place. If the plan rejects the claim because it needs prior authorization, that rejection can start an electronic prior authorization, which runs over SCRIPT. Our CoverMyMeds integration guide shows that hand-off.
| SCRIPT | Telecommunication | |
|---|---|---|
| Purpose | The prescription and the conversation about it | The claim for payment and the eligibility check |
| Who talks | Prescriber and pharmacy (and plans, for prior authorization and history) | Pharmacy and drug plan or PBM |
| Required by | Medicare Part D e-prescribing rules | HIPAA transaction rules |
| Version now | 2017071 or 2023011; only 2023011 from Jan 1, 2028 | D.0; F6 from April 14, 2028 |
How does an e-prescription travel from the doctor to the pharmacy?
The prescriber's electronic health record builds a SCRIPT message and sends it to the Surescripts network. Surescripts checks the message and delivers it to the pharmacy the patient chose. The pharmacy can reply through the same network to ask questions, request renewals or report that the patient picked up the prescription.
Here is Ana's prescription, step by step.
- The doctor picks lisinopril 10 mg, 30 tablets, one a day, and Ana's usual pharmacy. Before sending, the EHR can check Ana's plan for the price and pull her medication history.
- The EHR sends a NewRx message to Surescripts, which checks it.
- Surescripts delivers the NewRx to the pharmacy system, where it lands in the pharmacist's queue.
- The pharmacist fills it, bills Ana's plan with a Telecommunication claim, and Ana picks up her tablets.
- If the doctor's system asked for fill notices, the pharmacy sends an RxFill message saying Ana picked it up.
- Near day 30, the pharmacy sends an RxRenewalRequest asking the doctor for more refills.
An EHR is an electronic health record, the software a doctor's office uses for charts and orders. Surescripts describes the same workflow on its E-Prescribing page.
What can a business do with NCPDP SCRIPT?
SCRIPT supports nine common business uses: sending new prescriptions, handling renewals, answering pharmacy change requests, cancelling prescriptions, tracking fills, pulling medication history, running electronic prior authorization, prescribing controlled substances, and supporting specialty, REMS and long-term care workflows. Most products start with new prescriptions and add the rest as users ask.
Each card gives the value, who it is for, how hard it is, and what works well or is limited. Build estimates for each are in one table in Part 2.
1. New prescriptions
The doctor sends Ana's lisinopril straight to her pharmacy, with no paper, fax or phone call.
- Value: fewer reading errors and faster starts. Surescripts reports 2.64 billion e-prescriptions filled in 2025.
- For: any prescriber product, such as EHRs, telehealth and specialty clinics.
- Complexity: medium. You need a drug list, pharmacy search, directions and patient matching.
- Limited: compounds and unusual directions can still need a call.
2. Renewals
Ana's refills run out. The pharmacy asks the doctor electronically, and the doctor approves in the EHR inbox.
- Value: refill requests arrive in the inbox instead of by phone or fax.
- For: primary and chronic care, where refills are frequent.
- Complexity: medium. Each request must match the original prescription and reach the right doctor.
- Limited: a request for a patient the practice can't match needs manual review.
3. Change requests
Ana's plan prefers a different product. The pharmacist asks the doctor to approve the change instead of phoning.
- Value: questions get answered inside the doctor's workflow. Surescripts counted 32.9 million of these change transactions in 2025.
- For: any prescriber product, and pharmacies that work with plan rules every day.
- Complexity: medium to high. The doctor must see the original and the proposed change side by side.
- Limited: if the doctor doesn't answer, the patient still waits.
4. Cancellations
The doctor stops Ana's lisinopril and starts a different drug. A cancel message tells the pharmacy not to fill the old one.
- Value: Surescripts reports that 93 percent of discontinued medications were cancelled at the pharmacy after electronic cancellation was in place, citing a 2022 study.
- For: health systems, EHRs, medication safety programs.
- Complexity: low to medium. The pharmacy may already have dispensed.
- Limited: it can't take back a drug already picked up.
5. Fill status
The doctor learns that Ana picked up her tablets, or that she didn't.
- Value: a real adherence signal for care teams.
- For: care management and chronic disease programs.
- Complexity: low to receive, medium to act on.
- Limited: the doctor's system chooses which notices it wants, so the data can be partial.
6. Medication history
Before writing the prescription, the doctor sees what Ana filled in the last year.
- Value: Surescripts returns 12 months of history from pharmacies and PBMs, including prescriber, pickup date and directions.
- For: EHRs, urgent care, hospitals at admission.
- Complexity: low. It is read-only, but patient matching decides the quality.
- Limited: fills outside these sources may be missing.
7. Electronic prior authorization (ePA)
Ana's plan requires approval for a drug. The doctor answers the plan's questions inside the EHR and gets a decision electronically.
- Value: Surescripts reports more than 2 days of wait time saved for patients and responses in under 4 minutes on average.
- For: specialty drugs, high-cost brands, any practice with heavy prior authorization volume.
- Complexity: high. Questions differ by plan and drug, and can branch.
- Limited: plans that only take fax still fall outside the flow.
8. Controlled substances (EPCS)
If the doctor prescribes a Schedule II to V drug, DEA rules require the prescription to be signed with two-factor authentication.
- Value: for Medicare Part D, electronic prescribing of controlled substances is required by law from January 1, 2021. CMS measures it against a 70 percent threshold, with compliance actions from January 1, 2023.
- For: any prescriber product that handles pain, ADHD, anxiety or addiction treatment.
- Complexity: high. Identity checks, two-person access control, signing, audit logs and an outside audit.
- Limited: the outside audit is repeated every two years. State EPCS laws apply too; CMS says its program is separate from state EPCS requirements.
9. Specialty, REMS and long-term care
Some drugs carry FDA safety programs, and nursing homes need resupply and administration messages.
- Value: keeps high-risk drugs and facility work electronic.
- For: specialty pharmacy, long-term and post-acute care.
- Complexity: high. More parties take part.
- Limited: messages among doctor, facility and pharmacy together need the 2023011 version.
REMS means Risk Evaluation and Mitigation Strategy, an FDA-required safety program for certain drugs.
What are the limitations of NCPDP SCRIPT?
SCRIPT carries messages but doesn't make clinical or coverage decisions, can't force anyone to reply, and can't undo a fill. It doesn't cover payment. The specifications are for members, the network needs certification, and the quality of each prescription still depends on how well each system fills in drugs, directions and patient details.
- Access: the guides are free to NCPDP members and cost a fee for others, so you can't build to the field level from public material alone.
- No reply guarantee: a pharmacy can ask for a change or a renewal, and the doctor can ignore it.
- No payment: the claim is a separate Telecommunication transaction.
- Directions vary: many prescriptions still carry typed directions. NCPDP publishes a separate structured format for them.
- Network gate: Surescripts requires certification before software can exchange messages, and controlled substances need a DEA-required audit.
Version gaps and the FHIR comparison are in Part 2, under versions and SCRIPT vs FHIR.
What goes wrong in everyday e-prescribing?
Most everyday problems come from seven situations: a patient the system can't match, a prescription sent twice, a pharmacy that can't accept a message, a cancel that arrives after the drug was dispensed, a move to another pharmacy, a change request nobody answers, and a prior authorization that stalls. Each one has a known fix.
Ana's prescription can hit any of these. If her pharmacy closes and she moves stores, that is a transfer. If the doctor stops the drug the same afternoon the pharmacy filled it, that is a cancel after dispense. Part 2 has 23 edge case cards, each starting with what the patient and staff see.
What are the federal deadlines?
Four dates matter most. Medicare Part D has required SCRIPT 2017071 since January 1, 2020. Part D plans have had to support electronic prior authorization since January 1, 2022. New benefit-check versions apply from January 1, 2027. From January 1, 2028, only SCRIPT 2023011 is allowed.
| Date | What changes, in plain words |
|---|---|
| January 1, 2020 | Everyone in Medicare Part D moves to SCRIPT 2017071 on the same day. |
| January 1, 2022 | Part D plans must accept electronic prior authorization over SCRIPT. |
| January 1, 2027 | New versions of the price-check and coverage-list standards apply. |
| January 1, 2028 | Only SCRIPT 2023011 is allowed, and nursing home prescriptions join the controlled substance rule. |
The full list with every rule citation, including the HIPAA claim change on April 14, 2028, is in Part 2.
What does certification cost, and how long does it take?
Neither Surescripts nor NCPDP publishes certification prices or durations. NCPDP standards are free for members and paid for non-members. Controlled substances add an outside audit before first use and every two years. Building usually takes weeks per feature, and the certification wait comes on top of that.
- Specifications: NCPDP membership, or a non-member fee. NCPDP doesn't publish the price on its Access to Standards page, so ask NCPDP.
- Network access: direct certification with Surescripts, or a contract with a certified e-prescribing vendor. Surescripts says it guides organizations through certification step by step; terms are not public. We name no vendors here, to stay neutral.
- Controlled substances audit: required before first use, then every two years or when those functions change.
- Build and support: see the build estimate table, plus monitoring once live.
If prescribing is one feature of a bigger product, a certified vendor is usually faster to market. If e-prescribing is the product, direct certification gives you control.
What should a pharmacy or practice ask its software vendor?
- When will you support SCRIPT 2023011, and which of its new messages will you turn on before January 1, 2028?
- For pharmacies: when will your claims move from Telecommunication D.0 to F6, ahead of April 14, 2028?
- Can you send and receive electronic transfers of controlled substance prescriptions?
- Is your controlled substance module audited, and when is the next audit due?
- Which messages do you support today: change requests, cancels, fill notices, prior authorization?
Part 2: For integration teams
Part 2 builds on Part 1 and links back instead of repeating it. Our XML examples use element names from public ONC test messages; cardinality, rules and code lists are in the member-only NCPDP guide.
What does an NCPDP SCRIPT XML message look like?
A SCRIPT message is an XML document with one Message root. Inside it, a Header says who sent it, who gets it and which message it answers, and a Body holds exactly one transaction, such as NewRx or Status. A NewRx then carries Patient, Pharmacy, Prescriber and MedicationPrescribed blocks.
CMS notes that SCRIPT 2017071 uses XML syntax. NCPDP also lists a separate XML Standard and a JSON Standard as base formats for its transactions. The element names below come from the public ONC electronic prescribing test messages, which NIST built for SCRIPT 2017071 certification testing. They are not copied from the NCPDP guide.
Reading a SCRIPT message, for beginners
- Start at the root. The
Messageelement's attributes name the version, such asTransactionVersion="20170715"in the 2017071 test files. - Read the
Headernext.ToandFromsay who is talking. TheirQualifiersays what kind of ID follows: in the ONC files D is a prescriber, P a pharmacy, PY a payer and M the network mailbox. - Find the IDs.
MessageIDis unique to this message.RelatesToMessageIDappears on replies and points at the message being answered.PrescriberOrderNumberandRxReferenceNumberare the doctor's and the pharmacy's own IDs for the prescription. - Open the
Body. Its first child names the transaction. Everything else is detail for that transaction. - Read the blocks. Patient, Pharmacy and Prescriber identify the people;
MedicationPrescribedsays what was ordered.
The skeleton, element names only
<Message ...version attributes...>
<Header>
<To Qualifier="P"> receiver ID (pharmacy)
<From Qualifier="D"> sender ID (prescriber)
<MessageID> unique per message
<RelatesToMessageID> on replies only
<SentTime> 2026-11-13T09:00:00
<SenderSoftware> developer, product, version
<RxReferenceNumber> pharmacy's prescription ID, once known
<PrescriberOrderNumber> doctor's order ID
<Body>
<NewRx>
<Patient><HumanPatient> Name, Gender, DateOfBirth, Address
<Pharmacy> Identification (NCPDPID, NPI), BusinessName
<Prescriber><NonVeterinarian> Identification (NPI, DEA), Name
<MedicationPrescribed>
DrugDescription, DrugCoded (ProductCode + Qualifier, Strength, DrugDBCode)
Quantity (Value, CodeListQualifier, QuantityUnitOfMeasure)
DaysSupply, WrittenDate, Substitutions, NumberOfRefills
Diagnosis, Sig (SigText, optional structured Instruction), Note
Element names from the ONC/NIST SCRIPT 2017071 test messages. Cardinality, order rules and code values are in the member-only NCPDP guide and schema.
Data types, simply
- Codes come from code lists. In
ProductCode, the qualifier ND says the code is an NDC, the 11-digit drug product code.DrugDBCodewith SCD or SBD points at an RxNorm concept. - Units are codes too. The ONC files pair C48542 with "Tablet" and C28253 with milligrams.
- Qualifiers tell you how to read the value next to them, so always read the two together.
- Dates are written year-month-day, such as 2026-11-13, and
SentTimeadds the time.
What changes structurally in 2023011
The public rules list a few structural additions: an optional OtherReferenceNumber in the header for multi-party messages, a Pending response type, RequestExpirationDate on three request messages, NoneChoiceID in PA questions, REMSReproductivePotential replacing REMSPatientRiskCategory, and a ReviewingProvider group on Resupply and Recertification (89 FR 51242). Since 2023011 is backwards compatible with 2017071, the envelope above stays the same.
What do the main SCRIPT messages look like for Ana's prescription?
Below are nine example messages for one prescription thread: NewRx, Status, Error, RxChangeRequest and RxChangeResponse, CancelRx and its response, RxRenewalRequest and its response, RxFill, and a PAInitiationRequest. Each block is collapsed, starts with one plain line, and ends with notes on the elements that matter. IDs stay consistent so you can follow the thread.
The thread starts with NewRx MessageID 1001. Every reply carries RelatesToMessageID pointing at the message it answers: 2001 and 2002 answer 1001, 3002 answers 3001, and so on. The NDC 00093111310 and RxNorm 314076 are real public codes for lisinopril 10 mg oral tablet (NLM RxNav, November 13, 2026). Every name, NPI, NCPDP ID and member ID is fake.
NewRx: the doctor sends Ana's prescription
The prescriber's system (From D) sends a new prescription to the pharmacy (To P). MessageID 1001 starts the thread.
Show the XML
Illustrative example built from public ONC test materials; validate against the NCPDP XSD for your version before use. All names and IDs are fake.
<?xml version="1.0" encoding="utf-8"?>
<Message DatatypesVersion="20170715" TransportVersion="20170715" TransactionDomain="SCRIPT"
TransactionVersion="20170715" StructuresVersion="20170715" ECLVersion="20170715">
<Header>
<To Qualifier="P">9999999992</To>
<From Qualifier="D">9999999991</From>
<MessageID>1001</MessageID>
<SentTime>2026-11-13T09:00:00</SentTime>
<SenderSoftware>
<SenderSoftwareDeveloper>Example EHR</SenderSoftwareDeveloper>
<SenderSoftwareProduct>Demo</SenderSoftwareProduct>
<SenderSoftwareVersionRelease>1.0</SenderSoftwareVersionRelease>
</SenderSoftware>
<PrescriberOrderNumber>ORD-ANA-0001</PrescriberOrderNumber>
</Header>
<Body>
<NewRx>
<Patient>
<HumanPatient>
<Name><LastName>Test</LastName><FirstName>Ana</FirstName></Name>
<Gender>F</Gender>
<DateOfBirth><Date>1964-05-02</Date></DateOfBirth>
<Address>
<AddressLine1>1 Example Street</AddressLine1><City>Springfield</City>
<StateProvince>IL</StateProvince><PostalCode>62701</PostalCode><CountryCode>US</CountryCode>
</Address>
</HumanPatient>
</Patient>
<Pharmacy>
<Identification>
<NCPDPID>0000001</NCPDPID> <!-- fake -->
<NPI>9999999992</NPI> <!-- fake -->
</Identification>
<BusinessName>Example Corner Pharmacy</BusinessName>
</Pharmacy>
<Prescriber>
<NonVeterinarian>
<Identification><NPI>9999999991</NPI></Identification> <!-- fake -->
<Name><LastName>Example</LastName><FirstName>Sam</FirstName></Name>
</NonVeterinarian>
</Prescriber>
<MedicationPrescribed>
<DrugDescription>lisinopril 10 MG Oral Tablet</DrugDescription>
<DrugCoded>
<ProductCode><Code>00093111310</Code><Qualifier>ND</Qualifier></ProductCode>
<Strength>
<StrengthValue>10</StrengthValue>
<StrengthForm><Code>C42998</Code></StrengthForm>
<StrengthUnitOfMeasure><Code>C28253</Code></StrengthUnitOfMeasure>
</Strength>
<DrugDBCode><Code>314076</Code><Qualifier>SCD</Qualifier></DrugDBCode>
</DrugCoded>
<Quantity>
<Value>30</Value>
<CodeListQualifier>38</CodeListQualifier>
<QuantityUnitOfMeasure><Code>C48542</Code></QuantityUnitOfMeasure>
</Quantity>
<DaysSupply>30</DaysSupply>
<WrittenDate><Date>2026-11-13</Date></WrittenDate>
<Substitutions>0</Substitutions>
<NumberOfRefills>2</NumberOfRefills>
<Sig><SigText>Take 1 tablet by mouth once a day</SigText></Sig>
</MedicationPrescribed>
</NewRx>
</Body>
</Message>
To Qualifier="P"andFrom Qualifier="D"say the receiver is a pharmacy and the sender a prescriber; the value is the NPI (fake here).MessageID1001 is unique per message. Every reply points back to it.PrescriberOrderNumberis the doctor's own order ID. It stays the same across the whole thread.ProductCodewithQualifierND is an NDC;DrugDBCode314076 with SCD is the RxNorm concept for lisinopril 10 mg oral tablet.Quantity30 with unit code C48542 (tablet in the ONC files),DaysSupply30,NumberOfRefills2.
Status: the network or pharmacy confirms receipt
A Status reply carries only a code. Code 010 is the code the ONC test files use for a successful receipt.
Show the XML
Illustrative example built from public ONC test materials; validate against the NCPDP XSD for your version before use. All names and IDs are fake.
<?xml version="1.0" encoding="utf-8"?>
<Message DatatypesVersion="20170715" TransportVersion="20170715" TransactionDomain="SCRIPT"
TransactionVersion="20170715" StructuresVersion="20170715" ECLVersion="20170715">
<Header>
<To Qualifier="D">9999999991</To>
<From Qualifier="P">9999999992</From>
<MessageID>2001</MessageID>
<RelatesToMessageID>1001</RelatesToMessageID>
<SentTime>2026-11-13T09:00:04</SentTime>
<SenderSoftware>
<SenderSoftwareDeveloper>Example Pharmacy System</SenderSoftwareDeveloper>
<SenderSoftwareProduct>Demo</SenderSoftwareProduct>
<SenderSoftwareVersionRelease>1.0</SenderSoftwareVersionRelease>
</SenderSoftware>
<PrescriberOrderNumber>ORD-ANA-0001</PrescriberOrderNumber>
</Header>
<Body>
<Status>
<Code>010</Code>
</Status>
</Body>
</Message>
RelatesToMessageID1001 ties this Status to the NewRx.ToandFromswap: the reply goes back to the prescriber.- Treat a Status as delivered, and anything else (or nothing) as not yet delivered.
Error: a message is rejected
An Error carries a code, a more specific description code, and text. The values below are the ones in the ONC context-free Error sample.
Show the XML
Illustrative example built from public ONC test materials; validate against the NCPDP XSD for your version before use. All names and IDs are fake.
<?xml version="1.0" encoding="utf-8"?>
<Message DatatypesVersion="20170715" TransportVersion="20170715" TransactionDomain="SCRIPT"
TransactionVersion="20170715" StructuresVersion="20170715" ECLVersion="20170715">
<Header>
<To Qualifier="D">9999999991</To>
<From Qualifier="M">0000000</From> <!-- the network mailbox; fake -->
<MessageID>2002</MessageID>
<RelatesToMessageID>1001</RelatesToMessageID>
<SentTime>2026-11-13T09:00:04</SentTime>
<SenderSoftware>
<SenderSoftwareDeveloper>Example Pharmacy System</SenderSoftwareDeveloper>
<SenderSoftwareProduct>Demo</SenderSoftwareProduct>
<SenderSoftwareVersionRelease>1.0</SenderSoftwareVersionRelease>
</SenderSoftware>
<PrescriberOrderNumber>ORD-ANA-0001</PrescriberOrderNumber>
</Header>
<Body>
<Error>
<Code>900</Code>
<DescriptionCode>1000</DescriptionCode>
<Description>parser message of invalid sender</Description>
</Error>
</Body>
</Message>
From Qualifier="M"is the qualifier the ONC sample uses for the network's mailbox.Code900 withDescriptionCode1000 is the ONC sample's rejection; the full code list is in the NCPDP External Code List (member-only).- Show the
Descriptionto support staff, and the plain meaning to the user.
RxChangeRequest: the pharmacy asks for a different drug
The pharmacy (From P) asks the prescriber to change the prescription. MessageRequestCode T is the code the ONC test story uses for a formulary-driven therapeutic change.
Show the XML
Illustrative example built from public ONC test materials; validate against the NCPDP XSD for your version before use. All names and IDs are fake.
<?xml version="1.0" encoding="utf-8"?>
<Message DatatypesVersion="20170715" TransportVersion="20170715" TransactionDomain="SCRIPT"
TransactionVersion="20170715" StructuresVersion="20170715" ECLVersion="20170715">
<Header>
<To Qualifier="D">9999999991</To>
<From Qualifier="P">9999999992</From>
<MessageID>3001</MessageID>
<RelatesToMessageID>1001</RelatesToMessageID>
<SentTime>2026-11-13T11:20:00</SentTime>
<SenderSoftware>
<SenderSoftwareDeveloper>Example Pharmacy System</SenderSoftwareDeveloper>
<SenderSoftwareProduct>Demo</SenderSoftwareProduct>
<SenderSoftwareVersionRelease>1.0</SenderSoftwareVersionRelease>
</SenderSoftware>
<RxReferenceNumber>RX-ANA-0001</RxReferenceNumber>
<PrescriberOrderNumber>ORD-ANA-0001</PrescriberOrderNumber>
</Header>
<Body>
<RxChangeRequest>
<MessageRequestCode>T</MessageRequestCode>
<Patient>
<HumanPatient>
<Name><LastName>Test</LastName><FirstName>Ana</FirstName></Name>
<Gender>F</Gender>
<DateOfBirth><Date>1964-05-02</Date></DateOfBirth>
<Address>
<AddressLine1>1 Example Street</AddressLine1><City>Springfield</City>
<StateProvince>IL</StateProvince><PostalCode>62701</PostalCode><CountryCode>US</CountryCode>
</Address>
</HumanPatient>
</Patient>
<Pharmacy>
<Identification>
<NCPDPID>0000001</NCPDPID> <!-- fake -->
<NPI>9999999992</NPI> <!-- fake -->
</Identification>
<BusinessName>Example Corner Pharmacy</BusinessName>
</Pharmacy>
<Prescriber>
<NonVeterinarian>
<Identification><NPI>9999999991</NPI></Identification> <!-- fake -->
<Name><LastName>Example</LastName><FirstName>Sam</FirstName></Name>
</NonVeterinarian>
</Prescriber>
<MedicationPrescribed>
<DrugDescription>lisinopril 10 MG Oral Tablet</DrugDescription>
<DrugCoded>
<ProductCode><Code>00093111310</Code><Qualifier>ND</Qualifier></ProductCode>
<Strength>
<StrengthValue>10</StrengthValue>
<StrengthForm><Code>C42998</Code></StrengthForm>
<StrengthUnitOfMeasure><Code>C28253</Code></StrengthUnitOfMeasure>
</Strength>
<DrugDBCode><Code>314076</Code><Qualifier>SCD</Qualifier></DrugDBCode>
</DrugCoded>
<Quantity>
<Value>30</Value>
<CodeListQualifier>38</CodeListQualifier>
<QuantityUnitOfMeasure><Code>C48542</Code></QuantityUnitOfMeasure>
</Quantity>
<DaysSupply>30</DaysSupply>
<WrittenDate><Date>2026-11-13</Date></WrittenDate>
<Substitutions>0</Substitutions>
<NumberOfRefills>2</NumberOfRefills>
<Sig><SigText>Take 1 tablet by mouth once a day</SigText></Sig>
</MedicationPrescribed>
<MedicationRequested>
<DrugDescription>[the plan's preferred product]</DrugDescription>
<DrugCoded>
<ProductCode><Code>[NDC]</Code><Qualifier>ND</Qualifier></ProductCode>
<Strength>
<StrengthValue>10</StrengthValue>
<StrengthForm><Code>C42998</Code></StrengthForm>
<StrengthUnitOfMeasure><Code>C28253</Code></StrengthUnitOfMeasure>
</Strength>
<DrugDBCode><Code>[RxNorm]</Code><Qualifier>SCD</Qualifier></DrugDBCode>
</DrugCoded>
<Quantity>
<Value>30</Value>
<CodeListQualifier>38</CodeListQualifier>
<QuantityUnitOfMeasure><Code>C48542</Code></QuantityUnitOfMeasure>
</Quantity>
<DaysSupply>30</DaysSupply>
<WrittenDate><Date>2026-11-13</Date></WrittenDate>
<Substitutions>0</Substitutions>
<NumberOfRefills>2</NumberOfRefills>
<Sig><SigText>Take 1 tablet by mouth once a day</SigText></Sig>
</MedicationRequested>
</RxChangeRequest>
</Body>
</Message>
RxReferenceNumberis the pharmacy's own ID for the prescription; it appears once the pharmacy has it.MessageRequestCodesays why: in the ONC test stories, G is generic substitution, T therapeutic (formulary), D drug use or allergy, S clarification, U prescriber authorization.MedicationPrescribedis what the doctor wrote;MedicationRequestedis what the pharmacy proposes. Placeholders are in brackets.
RxChangeResponse: the doctor answers
The prescriber denies the change here. The ONC samples also contain Approved, ApprovedWithChanges and Validated answers.
Show the XML
Illustrative example built from public ONC test materials; validate against the NCPDP XSD for your version before use. All names and IDs are fake.
<?xml version="1.0" encoding="utf-8"?>
<Message DatatypesVersion="20170715" TransportVersion="20170715" TransactionDomain="SCRIPT"
TransactionVersion="20170715" StructuresVersion="20170715" ECLVersion="20170715">
<Header>
<To Qualifier="P">9999999992</To>
<From Qualifier="D">9999999991</From>
<MessageID>3002</MessageID>
<RelatesToMessageID>3001</RelatesToMessageID>
<SentTime>2026-11-13T12:05:00</SentTime>
<SenderSoftware>
<SenderSoftwareDeveloper>Example EHR</SenderSoftwareDeveloper>
<SenderSoftwareProduct>Demo</SenderSoftwareProduct>
<SenderSoftwareVersionRelease>1.0</SenderSoftwareVersionRelease>
</SenderSoftware>
<RxReferenceNumber>RX-ANA-0001</RxReferenceNumber>
<PrescriberOrderNumber>ORD-ANA-0001</PrescriberOrderNumber>
</Header>
<Body>
<RxChangeResponse>
<MessageRequestCode>T</MessageRequestCode>
<Response>
<Denied>
<ReasonCode>AL</ReasonCode>
<DenialReason>Patient is stable on current therapy</DenialReason>
</Denied>
</Response>
<Patient>
<HumanPatient>
<Name><LastName>Test</LastName><FirstName>Ana</FirstName></Name>
<Gender>F</Gender>
<DateOfBirth><Date>1964-05-02</Date></DateOfBirth>
<Address>
<AddressLine1>1 Example Street</AddressLine1><City>Springfield</City>
<StateProvince>IL</StateProvince><PostalCode>62701</PostalCode><CountryCode>US</CountryCode>
</Address>
</HumanPatient>
</Patient>
<Pharmacy>
<Identification>
<NCPDPID>0000001</NCPDPID> <!-- fake -->
<NPI>9999999992</NPI> <!-- fake -->
</Identification>
<BusinessName>Example Corner Pharmacy</BusinessName>
</Pharmacy>
<Prescriber>
<NonVeterinarian>
<Identification><NPI>9999999991</NPI></Identification> <!-- fake -->
<Name><LastName>Example</LastName><FirstName>Sam</FirstName></Name>
</NonVeterinarian>
</Prescriber>
<MedicationPrescribed>
<DrugDescription>lisinopril 10 MG Oral Tablet</DrugDescription>
<DrugCoded>
<ProductCode><Code>00093111310</Code><Qualifier>ND</Qualifier></ProductCode>
<Strength>
<StrengthValue>10</StrengthValue>
<StrengthForm><Code>C42998</Code></StrengthForm>
<StrengthUnitOfMeasure><Code>C28253</Code></StrengthUnitOfMeasure>
</Strength>
<DrugDBCode><Code>314076</Code><Qualifier>SCD</Qualifier></DrugDBCode>
</DrugCoded>
<Quantity>
<Value>30</Value>
<CodeListQualifier>38</CodeListQualifier>
<QuantityUnitOfMeasure><Code>C48542</Code></QuantityUnitOfMeasure>
</Quantity>
<DaysSupply>30</DaysSupply>
<WrittenDate><Date>2026-11-13</Date></WrittenDate>
<Substitutions>0</Substitutions>
<NumberOfRefills>2</NumberOfRefills>
<Sig><SigText>Take 1 tablet by mouth once a day</SigText></Sig>
</MedicationPrescribed>
</RxChangeResponse>
</Body>
</Message>
RelatesToMessageID3001 points at the change request, not the original NewRx.Responseholds exactly one answer;ReasonCodeAL is the code used in the ONC denial sample.- In 2023011 the answer can also be Pending (89 FR 51242). A 2017071 partner won't understand it.
CancelRx and CancelRxResponse: the doctor stops the drug
The prescriber cancels; the pharmacy confirms nothing was dispensed. Both use the same thread IDs.
Show the XML
Illustrative example built from public ONC test materials; validate against the NCPDP XSD for your version before use. All names and IDs are fake.
<?xml version="1.0" encoding="utf-8"?>
<Message DatatypesVersion="20170715" TransportVersion="20170715" TransactionDomain="SCRIPT"
TransactionVersion="20170715" StructuresVersion="20170715" ECLVersion="20170715">
<Header>
<To Qualifier="P">9999999992</To>
<From Qualifier="D">9999999991</From>
<MessageID>4001</MessageID>
<RelatesToMessageID>1001</RelatesToMessageID>
<SentTime>2026-11-14T08:00:00</SentTime>
<SenderSoftware>
<SenderSoftwareDeveloper>Example EHR</SenderSoftwareDeveloper>
<SenderSoftwareProduct>Demo</SenderSoftwareProduct>
<SenderSoftwareVersionRelease>1.0</SenderSoftwareVersionRelease>
</SenderSoftware>
<PrescriberOrderNumber>ORD-ANA-0001</PrescriberOrderNumber>
</Header>
<Body>
<CancelRx>
<Patient>
<HumanPatient>
<Name><LastName>Test</LastName><FirstName>Ana</FirstName></Name>
<Gender>F</Gender>
<DateOfBirth><Date>1964-05-02</Date></DateOfBirth>
<Address>
<AddressLine1>1 Example Street</AddressLine1><City>Springfield</City>
<StateProvince>IL</StateProvince><PostalCode>62701</PostalCode><CountryCode>US</CountryCode>
</Address>
</HumanPatient>
</Patient>
<Pharmacy>
<Identification>
<NCPDPID>0000001</NCPDPID> <!-- fake -->
<NPI>9999999992</NPI> <!-- fake -->
</Identification>
<BusinessName>Example Corner Pharmacy</BusinessName>
</Pharmacy>
<Prescriber>
<NonVeterinarian>
<Identification><NPI>9999999991</NPI></Identification> <!-- fake -->
<Name><LastName>Example</LastName><FirstName>Sam</FirstName></Name>
</NonVeterinarian>
</Prescriber>
<MedicationPrescribed>
<DrugDescription>lisinopril 10 MG Oral Tablet</DrugDescription>
<DrugCoded>
<ProductCode><Code>00093111310</Code><Qualifier>ND</Qualifier></ProductCode>
<Strength>
<StrengthValue>10</StrengthValue>
<StrengthForm><Code>C42998</Code></StrengthForm>
<StrengthUnitOfMeasure><Code>C28253</Code></StrengthUnitOfMeasure>
</Strength>
<DrugDBCode><Code>314076</Code><Qualifier>SCD</Qualifier></DrugDBCode>
</DrugCoded>
<Quantity>
<Value>30</Value>
<CodeListQualifier>38</CodeListQualifier>
<QuantityUnitOfMeasure><Code>C48542</Code></QuantityUnitOfMeasure>
</Quantity>
<DaysSupply>30</DaysSupply>
<WrittenDate><Date>2026-11-13</Date></WrittenDate>
<Substitutions>0</Substitutions>
<NumberOfRefills>2</NumberOfRefills>
<Sig><SigText>Take 1 tablet by mouth once a day</SigText></Sig>
</MedicationPrescribed>
</CancelRx>
</Body>
</Message>
<?xml version="1.0" encoding="utf-8"?>
<Message DatatypesVersion="20170715" TransportVersion="20170715" TransactionDomain="SCRIPT"
TransactionVersion="20170715" StructuresVersion="20170715" ECLVersion="20170715">
<Header>
<To Qualifier="D">9999999991</To>
<From Qualifier="P">9999999992</From>
<MessageID>4002</MessageID>
<RelatesToMessageID>4001</RelatesToMessageID>
<SentTime>2026-11-14T08:10:00</SentTime>
<SenderSoftware>
<SenderSoftwareDeveloper>Example Pharmacy System</SenderSoftwareDeveloper>
<SenderSoftwareProduct>Demo</SenderSoftwareProduct>
<SenderSoftwareVersionRelease>1.0</SenderSoftwareVersionRelease>
</SenderSoftware>
<RxReferenceNumber>RX-ANA-0001</RxReferenceNumber>
<PrescriberOrderNumber>ORD-ANA-0001</PrescriberOrderNumber>
</Header>
<Body>
<CancelRxResponse>
<Response>
<Approved>
<Note>No prior dispensing.</Note>
</Approved>
</Response>
</CancelRxResponse>
</Body>
</Message>
- The CancelRx repeats the medication so the pharmacy can match it.
Approvedwith the note "No prior dispensing." is the ONC sample's answer; a pharmacy that already dispensed answers differently (edge case E5).- Close the order in your EHR only after the response.
RxRenewalRequest and RxRenewalResponse: more refills
Near day 30 the pharmacy asks for refills; the prescriber approves.
Show the XML
Illustrative example built from public ONC test materials; validate against the NCPDP XSD for your version before use. All names and IDs are fake.
<?xml version="1.0" encoding="utf-8"?>
<Message DatatypesVersion="20170715" TransportVersion="20170715" TransactionDomain="SCRIPT"
TransactionVersion="20170715" StructuresVersion="20170715" ECLVersion="20170715">
<Header>
<To Qualifier="D">9999999991</To>
<From Qualifier="P">9999999992</From>
<MessageID>5001</MessageID>
<RelatesToMessageID>1001</RelatesToMessageID>
<SentTime>2026-12-10T09:00:00</SentTime>
<SenderSoftware>
<SenderSoftwareDeveloper>Example Pharmacy System</SenderSoftwareDeveloper>
<SenderSoftwareProduct>Demo</SenderSoftwareProduct>
<SenderSoftwareVersionRelease>1.0</SenderSoftwareVersionRelease>
</SenderSoftware>
<RxReferenceNumber>RX-ANA-0001</RxReferenceNumber>
<PrescriberOrderNumber>ORD-ANA-0001</PrescriberOrderNumber>
</Header>
<Body>
<RxRenewalRequest>
<Patient>
<HumanPatient>
<Name><LastName>Test</LastName><FirstName>Ana</FirstName></Name>
<Gender>F</Gender>
<DateOfBirth><Date>1964-05-02</Date></DateOfBirth>
<Address>
<AddressLine1>1 Example Street</AddressLine1><City>Springfield</City>
<StateProvince>IL</StateProvince><PostalCode>62701</PostalCode><CountryCode>US</CountryCode>
</Address>
</HumanPatient>
</Patient>
<Pharmacy>
<Identification>
<NCPDPID>0000001</NCPDPID> <!-- fake -->
<NPI>9999999992</NPI> <!-- fake -->
</Identification>
<BusinessName>Example Corner Pharmacy</BusinessName>
</Pharmacy>
<Prescriber>
<NonVeterinarian>
<Identification><NPI>9999999991</NPI></Identification> <!-- fake -->
<Name><LastName>Example</LastName><FirstName>Sam</FirstName></Name>
</NonVeterinarian>
</Prescriber>
<MedicationDispensed>
<DrugDescription>lisinopril 10 MG Oral Tablet</DrugDescription>
<DrugCoded>
<ProductCode><Code>00093111310</Code><Qualifier>ND</Qualifier></ProductCode>
<Strength>
<StrengthValue>10</StrengthValue>
<StrengthForm><Code>C42998</Code></StrengthForm>
<StrengthUnitOfMeasure><Code>C28253</Code></StrengthUnitOfMeasure>
</Strength>
<DrugDBCode><Code>314076</Code><Qualifier>SCD</Qualifier></DrugDBCode>
</DrugCoded>
<Quantity>
<Value>30</Value>
<CodeListQualifier>38</CodeListQualifier>
<QuantityUnitOfMeasure><Code>C48542</Code></QuantityUnitOfMeasure>
</Quantity>
<DaysSupply>30</DaysSupply>
<WrittenDate><Date>2026-11-13</Date></WrittenDate>
<Substitutions>0</Substitutions>
<NumberOfRefills>0</NumberOfRefills>
<Sig><SigText>Take 1 tablet by mouth once a day</SigText></Sig>
</MedicationDispensed>
<MedicationPrescribed>
<DrugDescription>lisinopril 10 MG Oral Tablet</DrugDescription>
<DrugCoded>
<ProductCode><Code>00093111310</Code><Qualifier>ND</Qualifier></ProductCode>
<Strength>
<StrengthValue>10</StrengthValue>
<StrengthForm><Code>C42998</Code></StrengthForm>
<StrengthUnitOfMeasure><Code>C28253</Code></StrengthUnitOfMeasure>
</Strength>
<DrugDBCode><Code>314076</Code><Qualifier>SCD</Qualifier></DrugDBCode>
</DrugCoded>
<Quantity>
<Value>30</Value>
<CodeListQualifier>38</CodeListQualifier>
<QuantityUnitOfMeasure><Code>C48542</Code></QuantityUnitOfMeasure>
</Quantity>
<DaysSupply>30</DaysSupply>
<WrittenDate><Date>2026-11-13</Date></WrittenDate>
<Substitutions>0</Substitutions>
<NumberOfRefills>2</NumberOfRefills>
<Sig><SigText>Take 1 tablet by mouth once a day</SigText></Sig>
</MedicationPrescribed>
</RxRenewalRequest>
</Body>
</Message>
<?xml version="1.0" encoding="utf-8"?>
<Message DatatypesVersion="20170715" TransportVersion="20170715" TransactionDomain="SCRIPT"
TransactionVersion="20170715" StructuresVersion="20170715" ECLVersion="20170715">
<Header>
<To Qualifier="P">9999999992</To>
<From Qualifier="D">9999999991</From>
<MessageID>5002</MessageID>
<RelatesToMessageID>5001</RelatesToMessageID>
<SentTime>2026-12-10T15:30:00</SentTime>
<SenderSoftware>
<SenderSoftwareDeveloper>Example EHR</SenderSoftwareDeveloper>
<SenderSoftwareProduct>Demo</SenderSoftwareProduct>
<SenderSoftwareVersionRelease>1.0</SenderSoftwareVersionRelease>
</SenderSoftware>
<RxReferenceNumber>RX-ANA-0001</RxReferenceNumber>
<PrescriberOrderNumber>ORD-ANA-0001</PrescriberOrderNumber>
</Header>
<Body>
<RxRenewalResponse>
<Response>
<Approved/>
</Response>
<Patient>
<HumanPatient>
<Name><LastName>Test</LastName><FirstName>Ana</FirstName></Name>
<Gender>F</Gender>
<DateOfBirth><Date>1964-05-02</Date></DateOfBirth>
<Address>
<AddressLine1>1 Example Street</AddressLine1><City>Springfield</City>
<StateProvince>IL</StateProvince><PostalCode>62701</PostalCode><CountryCode>US</CountryCode>
</Address>
</HumanPatient>
</Patient>
<Pharmacy>
<Identification>
<NCPDPID>0000001</NCPDPID> <!-- fake -->
<NPI>9999999992</NPI> <!-- fake -->
</Identification>
<BusinessName>Example Corner Pharmacy</BusinessName>
</Pharmacy>
<Prescriber>
<NonVeterinarian>
<Identification><NPI>9999999991</NPI></Identification> <!-- fake -->
<Name><LastName>Example</LastName><FirstName>Sam</FirstName></Name>
</NonVeterinarian>
</Prescriber>
<MedicationPrescribed>
<DrugDescription>lisinopril 10 MG Oral Tablet</DrugDescription>
<DrugCoded>
<ProductCode><Code>00093111310</Code><Qualifier>ND</Qualifier></ProductCode>
<Strength>
<StrengthValue>10</StrengthValue>
<StrengthForm><Code>C42998</Code></StrengthForm>
<StrengthUnitOfMeasure><Code>C28253</Code></StrengthUnitOfMeasure>
</Strength>
<DrugDBCode><Code>314076</Code><Qualifier>SCD</Qualifier></DrugDBCode>
</DrugCoded>
<Quantity>
<Value>30</Value>
<CodeListQualifier>38</CodeListQualifier>
<QuantityUnitOfMeasure><Code>C48542</Code></QuantityUnitOfMeasure>
</Quantity>
<DaysSupply>30</DaysSupply>
<WrittenDate><Date>2026-11-13</Date></WrittenDate>
<Substitutions>0</Substitutions>
<NumberOfRefills>2</NumberOfRefills>
<Sig><SigText>Take 1 tablet by mouth once a day</SigText></Sig>
</MedicationPrescribed>
</RxRenewalResponse>
</Body>
</Message>
- The request carries
MedicationDispensed(what was filled) andMedicationPrescribed(the original), as in the ONC renewal sample. - The response's
RelatesToMessageIDis 5001, the request. - 2023011 adds RequestExpirationDate to the request, telling the prescriber not to answer after that date (89 FR 51242).
RxFill: Ana picked it up
The pharmacy reports the fill status. The ONC samples use Dispensed, PartiallyDispensed and NotDispensed.
Show the XML
Illustrative example built from public ONC test materials; validate against the NCPDP XSD for your version before use. All names and IDs are fake.
<?xml version="1.0" encoding="utf-8"?>
<Message DatatypesVersion="20170715" TransportVersion="20170715" TransactionDomain="SCRIPT"
TransactionVersion="20170715" StructuresVersion="20170715" ECLVersion="20170715">
<Header>
<To Qualifier="D">9999999991</To>
<From Qualifier="P">9999999992</From>
<MessageID>6001</MessageID>
<RelatesToMessageID>1001</RelatesToMessageID>
<SentTime>2026-11-13T17:45:00</SentTime>
<SenderSoftware>
<SenderSoftwareDeveloper>Example Pharmacy System</SenderSoftwareDeveloper>
<SenderSoftwareProduct>Demo</SenderSoftwareProduct>
<SenderSoftwareVersionRelease>1.0</SenderSoftwareVersionRelease>
</SenderSoftware>
<RxReferenceNumber>RX-ANA-0001</RxReferenceNumber>
<PrescriberOrderNumber>ORD-ANA-0001</PrescriberOrderNumber>
</Header>
<Body>
<RxFill>
<FillStatus>
<Dispensed/>
</FillStatus>
<Patient>
<HumanPatient>
<Name><LastName>Test</LastName><FirstName>Ana</FirstName></Name>
<Gender>F</Gender>
<DateOfBirth><Date>1964-05-02</Date></DateOfBirth>
<Address>
<AddressLine1>1 Example Street</AddressLine1><City>Springfield</City>
<StateProvince>IL</StateProvince><PostalCode>62701</PostalCode><CountryCode>US</CountryCode>
</Address>
</HumanPatient>
</Patient>
<Pharmacy>
<Identification>
<NCPDPID>0000001</NCPDPID> <!-- fake -->
<NPI>9999999992</NPI> <!-- fake -->
</Identification>
<BusinessName>Example Corner Pharmacy</BusinessName>
</Pharmacy>
<Prescriber>
<NonVeterinarian>
<Identification><NPI>9999999991</NPI></Identification> <!-- fake -->
<Name><LastName>Example</LastName><FirstName>Sam</FirstName></Name>
</NonVeterinarian>
</Prescriber>
<MedicationDispensed>
<DrugDescription>lisinopril 10 MG Oral Tablet</DrugDescription>
<DrugCoded>
<ProductCode><Code>00093111310</Code><Qualifier>ND</Qualifier></ProductCode>
<Strength>
<StrengthValue>10</StrengthValue>
<StrengthForm><Code>C42998</Code></StrengthForm>
<StrengthUnitOfMeasure><Code>C28253</Code></StrengthUnitOfMeasure>
</Strength>
<DrugDBCode><Code>314076</Code><Qualifier>SCD</Qualifier></DrugDBCode>
</DrugCoded>
<Quantity>
<Value>30</Value>
<CodeListQualifier>38</CodeListQualifier>
<QuantityUnitOfMeasure><Code>C48542</Code></QuantityUnitOfMeasure>
</Quantity>
<DaysSupply>30</DaysSupply>
<WrittenDate><Date>2026-11-13</Date></WrittenDate>
<Substitutions>0</Substitutions>
<NumberOfRefills>2</NumberOfRefills>
<Sig><SigText>Take 1 tablet by mouth once a day</SigText></Sig>
</MedicationDispensed>
</RxFill>
</Body>
</Message>
FillStatusholds one choice.NotDispensedwith a note such as "Patient did not pick up medication" appears in the ONC files.- A prescriber only gets RxFill if it asked for fill notices.
- Route NotDispensed to whoever follows up on adherence.
PAInitiationRequest: start an electronic prior authorization
The prescriber asks the plan (To PY) whether a drug needs prior authorization and for its questions.
Show the XML
Illustrative example built from public ONC test materials; validate against the NCPDP XSD for your version before use. All names and IDs are fake.
<?xml version="1.0" encoding="utf-8"?>
<Message DatatypesVersion="20170715" TransportVersion="20170715" TransactionDomain="SCRIPT"
TransactionVersion="20170715" StructuresVersion="20170715" ECLVersion="20170715">
<Header>
<To Qualifier="PY">PAYER-TEST-01</To>
<From Qualifier="D">9999999991</From>
<MessageID>7001</MessageID>
<SentTime>2026-11-13T09:30:00</SentTime>
<SenderSoftware>
<SenderSoftwareDeveloper>Example EHR</SenderSoftwareDeveloper>
<SenderSoftwareProduct>Demo</SenderSoftwareProduct>
<SenderSoftwareVersionRelease>1.0</SenderSoftwareVersionRelease>
</SenderSoftware>
<PrescriberOrderNumber>ORD-ANA-0002</PrescriberOrderNumber>
</Header>
<Body>
<PAInitiationRequest>
<PAReferenceID>PA-ANA-0001</PAReferenceID>
<BenefitsCoordination>
<PBMMemberID>MEMBER-TEST-0001</PBMMemberID> <!-- fake -->
</BenefitsCoordination>
<Patient>
<HumanPatient>
<Name><LastName>Test</LastName><FirstName>Ana</FirstName></Name>
<Gender>F</Gender>
<DateOfBirth><Date>1964-05-02</Date></DateOfBirth>
<Address>
<AddressLine1>1 Example Street</AddressLine1><City>Springfield</City>
<StateProvince>IL</StateProvince><PostalCode>62701</PostalCode><CountryCode>US</CountryCode>
</Address>
</HumanPatient>
</Patient>
<Pharmacy>
<Identification>
<NCPDPID>0000001</NCPDPID> <!-- fake -->
<NPI>9999999992</NPI> <!-- fake -->
</Identification>
<BusinessName>Example Corner Pharmacy</BusinessName>
</Pharmacy>
<Prescriber>
<NonVeterinarian>
<Identification><NPI>9999999991</NPI></Identification> <!-- fake -->
<Name><LastName>Example</LastName><FirstName>Sam</FirstName></Name>
</NonVeterinarian>
</Prescriber>
<MedicationPrescribed>
<DrugDescription>[a drug that needs PA]</DrugDescription>
<DrugCoded>
<ProductCode><Code>[NDC]</Code><Qualifier>ND</Qualifier></ProductCode>
<Strength>
<StrengthValue>10</StrengthValue>
<StrengthForm><Code>C42998</Code></StrengthForm>
<StrengthUnitOfMeasure><Code>C28253</Code></StrengthUnitOfMeasure>
</Strength>
<DrugDBCode><Code>[RxNorm]</Code><Qualifier>SCD</Qualifier></DrugDBCode>
</DrugCoded>
<Quantity>
<Value>30</Value>
<CodeListQualifier>38</CodeListQualifier>
<QuantityUnitOfMeasure><Code>C48542</Code></QuantityUnitOfMeasure>
</Quantity>
<DaysSupply>30</DaysSupply>
<WrittenDate><Date>2026-11-13</Date></WrittenDate>
<Substitutions>0</Substitutions>
<NumberOfRefills>2</NumberOfRefills>
<Sig><SigText>Take 1 tablet by mouth once a day</SigText></Sig>
</MedicationPrescribed>
</PAInitiationRequest>
</Body>
</Message>
To Qualifier="PY"marks a payer, as in the ONC PA samples.PAReferenceIDtracks this PA through PAInitiationResponse, PARequest and PAResponse.BenefitsCoordinationcarries the plan member ID (fake here). Lisinopril rarely needs PA, so the drug is a placeholder.
Where can you see more NCPDP SCRIPT examples?
The best free source is ONC's electronic prescribing test tool and its public copy on GitHub, which hold hundreds of SCRIPT 2017071 test messages. The NCPDP guide and schemas are member-only. CMS and Surescripts publish rules and workflow pages, and a few open-source projects show parsing code. Each link below was checked on November 13, 2026.
| Resource | Type | What you get |
|---|---|---|
| ONC test method for 170.315(b)(3) | Official, federal | The e-prescribing certification test procedure and links to the test tool |
| ONC ePrescribing Test Suite | Official, federal | The online eRx testing tool used for certification testing |
| onc-healthit/erx-testing-tool | Official copy, not for certification | A free copy of the validation tool for SCRIPT 2017071, with test messages by scenario. ONC says it is for internal testing only and is not actively updated (last push October 27, 2021). |
| NCPDP Access to Standards | Official, member-only | The SCRIPT implementation guide, XSD schemas and code lists |
| CMS e-prescribing standards | Official, federal | Which versions apply and when |
| Surescripts E-Prescribing | Official, vendor | The workflow and transaction list in plain terms; technical documentation needs a partner login |
| dgoradia/ncpdp | Community | Go decoder for SCRIPT 2017071 with a sample NewRx; MIT license, last push April 20, 2023 |
| kdar/health | Community | Go library for NCPDP and other EDI formats; MIT license, last push January 17, 2019 |
The ONC copy also contains the NCPDP schemas. Those are NCPDP's copyrighted files, so get your own from NCPDP rather than reusing them.
Which messages does NCPDP SCRIPT define?
The Part D rule lists the SCRIPT transactions in use: NewRx, RxChange, RxRenewal, CancelRx, RxFill, RxFillIndicatorChange, NewRxRequest and NewRxResponseDenied, RxTransfer messages, RxHistory, Status, Error, Verify, GetMessage, Resupply, DrugAdministration, Recertification, four REMS messages, and nine ePA messages including PANotification, new in 2023011.
The list below is the one in 42 CFR 423.160(b)(1) as of November 2026. "New in 2017071" comes from the 2018 CMS rule, which named the transactions added over 10.6. "New in 2023011" comes from the 2024 rule. Other rows were already in use before 2017071; their first version isn't stated in the public rules, so we don't guess it.
| Message | What it does | Direction | Version note |
|---|---|---|---|
NewRx | A new prescription | Prescriber to pharmacy | Before 2017071 |
RxChangeRequest / RxChangeResponse | Pharmacy asks to change a new or existing prescription; prescriber answers | Pharmacy to prescriber, then back | Before 2017071; Pending response added in 2023011 |
RxRenewalRequest / RxRenewalResponse | Pharmacy asks for more refills; prescriber answers | Pharmacy to prescriber, then back | Before 2017071; Pending response and RequestExpirationDate in 2023011 |
CancelRx / CancelRxResponse | Prescriber cancels a prescription sent to the pharmacy; pharmacy answers | Prescriber to pharmacy, then back | Before 2017071 |
RxFill | Tells the prescriber the status of the prescription, such as pickup | Pharmacy to prescriber | Before 2017071 |
RxFillIndicatorChange | Changes which fill notices the prescriber wants | Prescriber to pharmacy | New in 2017071 |
NewRxRequest | Pharmacy asks for a new prescription on the patient's behalf | Pharmacy to prescriber | New in 2017071; RequestExpirationDate in 2023011 |
NewRxResponseDenied | Prescriber declines a NewRxRequest | Prescriber to pharmacy | New in 2017071 |
RxTransferInitiationRequest, RxTransfer, RxTransferConfirm | Moves a prescription between pharmacies | Pharmacy to pharmacy | New in 2017071 as RxTransferRequest / RxTransferResponse / RxTransferConfirm; renamed in 2023011, which also adds push transfers |
RxHistoryRequest / RxHistoryResponse | Medication history query and answer | Prescriber to history source, then back | 2017071 adopted for history in Part D |
Status, Error, Verify | Acknowledgements and failures for a message | Network or receiver back to sender | Before 2017071 |
GetMessage | Named in the rule; its use is described in the guide | See the guide | Before 2017071 |
Resupply, DrugAdministration, Recertification | Long-term care supply, administration and recertification messages | Field-level direction is in the guide | DrugAdministration and Recertification new in 2017071; ReviewingProvider group added to Resupply and Recertification in 2023011 |
REMSInitiationRequest / Response, REMSRequest / Response | Starts and runs a REMS safety-program check for a drug | Request and response pair; parties are in the guide | New in 2017071; REMSReproductivePotential replaces REMSPatientRiskCategory in 2023011 |
PAInitiationRequest / Response | Asks whether PA is needed and gets the question set | Prescriber to plan, then back | In 2017071; Part D required 2022 |
PARequest / PAResponse | Sends the answers; returns the decision | Prescriber to plan, then back | In 2017071; NoneChoiceID added in 2023011 |
PAAppealRequest / Response | Appeals a PA decision | Prescriber to plan, then back | In 2017071 |
PACancelRequest / Response | Cancels an open PA | Prescriber to plan, then back | In 2017071 |
PANotification | Alerts the pharmacist or prescriber about a PA request or decision | Plan to pharmacist or prescriber | New in 2023011 |
Directions for the ePA rows reflect the 2020 rule, which describes ePA between prescribers and payers. The Surescripts FAQ confirms the directions for NewRx, RxChange, RxRenewal, RxTransfer, RxFill, CancelRx and NewRxRequest. Medication history sources are pharmacies and PBMs, per Surescripts.
What does each NCPDP standard cover?
Beyond the five main standards in Part 1, NCPDP publishes standards for post-payment data, prescription and prior authorization transfers, structured directions, state drug monitoring, audits, census and central fill, and more. The table lists the ones an e-prescribing or pharmacy integration is most likely to meet, from NCPDP's Access to Standards page.
| Standard | What it does | Who uses it |
|---|---|---|
| Post Adjudication | Detailed drug and use data after a claim is paid | Processors, plans |
| Specialized | Messages for census, query and central fill functions | Pharmacies, long-term care, central fill sites |
| Prescription Transfer | A file format for moving prescriptions between pharmacies | Pharmacies, chains |
| Prior Authorization Transfer | A file format for moving existing approvals between payers | Plans, PBMs |
| Structured Sig Format | A coded way to write the directions for use | Prescriber systems, pharmacies |
| Prescription Drug Monitoring | Two-way messages between dispensers and state PDMP programs | Pharmacies, PDMP facilitators |
| Audit Transaction | Requests and results when a plan audits a pharmacy | Auditors, pharmacies |
| Batch Standard Subrogation | Post-payment claims when another payer should have paid | State Medicaid agencies, processors |
| XML Standard and JSON Standard | Base formats that other NCPDP transactions build on | Standard implementers |
| Data Dictionary and External Code List | Definitions and allowed values for data elements across the standards | Every implementer |
A PDMP is a state prescription drug monitoring program, the database of controlled substance fills.
What changed from SCRIPT 10.6 to 2017071 to 2023011?
SCRIPT 2017071 added transfers, fill-notice changes, new-prescription requests, REMS and long-term care messages, and broke compatibility with 10.6, so Part D switched on one day in 2020. 2023011 is backwards compatible with 2017071 and adds PANotification, controlled-substance transfers, three-way messages and Pending answers.
Every date, with its rule
| Date | What changes | Who it binds | Source |
|---|---|---|---|
| Nov 1, 2013 | SCRIPT 10.6 becomes the Part D standard | Part D plans, prescribers, pharmacies | CMS e-prescribing page; 77 FR 69329 |
| Jan 1, 2020 | 2017071 required; 10.6 retired. No transition period, because 2017071 is not fully backward compatible with 10.6 | Part D | 83 FR 16440, 16636 |
| Jan 1, 2021 | Electronic prescribing of Schedule II to V drugs under Part D required by law; CMS measures it against a 70 percent threshold | Prescribers | 42 CFR 423.160(a)(5); CMS EPCS program page |
| Jan 1, 2022 | SCRIPT 2017071 ePA transactions required | Part D plans | 85 FR 86824 |
| Jan 1, 2023 | CMS compliance actions on the 70 percent threshold begin (outside long-term care) | Prescribers | 42 CFR 423.160(a)(5) |
| Jul 17, 2024 | Transition opens: 2017071 or 2023011 | Part D | 89 FR 51238 |
| Aug 4, 2025 | HTI-4 published in the Federal Register (document 2025-14681, part of CMS-1833-F; ASTP announced it July 31, 2025). It updates the EHR e-prescribing criterion to 2023011 and adds an RTPB criterion | Certified health IT developers | Federal Register; ASTP HTI-4 page |
| Oct 1, 2025 | HTI-4 takes effect; optional transactions no longer available for certification in 170.315(b)(3) | Certified health IT developers | ASTP HTI-4 page and key dates |
| Jan 1, 2027 | RTPB version 13 and F&B version 60 required | Part D plans' benefit tools | 42 CFR 423.160(b)(3), (b)(5) |
| Dec 31, 2027 | Transition ends | Part D and certified health IT | 89 FR 51246; ASTP |
| Jan 1, 2028 | 2017071 expires; 2023011 only. Long-term care prescriptions join the EPCS rule | Part D, certified health IT, LTC prescribers | 45 CFR 170.205(b); 42 CFR 423.160(a)(5) |
| Apr 14, 2028 | Telecommunication F6 and Batch 15 required for pharmacy claims | HIPAA covered entities | NCPDP HIPAA page |
The F6 dates come from NCPDP's HIPAA page: HHS published the F6 rule on December 13, 2024 (89 FR 100763), then delayed it, and NCPDP gives April 14, 2028 as the compliance date. ASTP/ONC is the federal office that certifies EHR software. Its criterion 45 CFR 170.315(b)(3) is the e-prescribing test that certified EHRs must pass. HTI-4 also requires any module certified to (b)(3) to certify to the new RTPB criterion, (b)(4), after January 1, 2028.
10.6 to 2017071 (Part D switch on January 1, 2020)
CMS said in 2018 that 2017071 "is not fully backward compatible" with 10.6, so it could not allow a period where both were accepted. Every Part D participant moved on the same date. New transactions named in that rule: drug administration, new prescription requests, new prescription response denials, prescription transfer, fill indicator change, recertification, and the four REMS messages.
2017071 to 2023011 (transition July 17, 2024 to December 31, 2027)
The 2024 rule says 2023011 is fully backwards compatible with 2017071, which is why both can run at once without a translator. NCPDP's listed enhancements, as quoted in that rule:
- An optional header element, OtherReferenceNumber, for multi-party messages such as long-term care.
- A Pending response type for RxChangeResponse and RxRenewalResponse.
- A RequestExpirationDate on NewRxRequest, RxChangeRequest and RxRenewalRequest, telling the prescriber not to answer after that date.
- NoneChoiceID, so a provider can answer "none of the above" in a PA question and branch to the next question.
- REMSReproductivePotential, replacing REMSPatientRiskCategory.
- A ReviewingProvider group on Resupply and Recertification.
- PANotification, a new ePA transaction.
- Renamed transfer messages, and push transfers that let a pharmacy send a controlled substance prescription to another pharmacy.
- Three-way messaging among prescriber, facility and pharmacy, which the rule says will enable EPCS in long-term care.
The rule also says that during the transition, a system on 2017071 isn't expected to support transactions that exist only in 2023011. The regulation's wording is "as applicable to the version of the standard in use."
How does Surescripts route SCRIPT messages?
Surescripts sits between prescriber systems and pharmacies. It validates every inbound message (sender identity, recipient, the trading agreement between them, syntax and code values, and its own business rules), looks up the recipient in its directory, and delivers the message. During a receiver outage, its message queue holds messages and sends them in order.
The validation list is from Surescripts' own E-Prescribing FAQ. It also says every participant completes certification before joining, that its Master Patient Index helps match the right patient, and that it validates data such as the National Drug Code (NDC), the 10-digit U.S. drug product ID. Its network holds certifications from DirectTrust and EHNAC, the Electronic Healthcare Network Accreditation Commission.
Network participants are the four groups Surescripts names on its pages: EHR and e-prescribing vendors, pharmacies and pharmacy technology vendors, health systems and long-term care, and plans and PBMs for history, benefits and PA. The directory tells your system which pharmacies exist and what each one supports. The exact directory format, identifiers and transport are in Surescripts' partner documentation, which wasn't publicly readable when we checked (its documentation site returned 403 Forbidden on November 13, 2026).
For the network-side services beyond SCRIPT (eligibility, formulary, RTPB), see our Surescripts integration guide.
How do you integrate NCPDP SCRIPT, step by step?
Choose a route first: certify directly with Surescripts, or connect through a certified e-prescribing vendor. Then get the NCPDP guide, build a message builder and parser, schema validation, a directory lookup, routing with retries, Status and Error handling, and an audit log. Test against a simulator, pass certification testing, then pilot with a few prescribers.
Route 1 or route 2?
| Direct Surescripts certification | Through a certified e-prescribing vendor | |
|---|---|---|
| Who certifies | You, for each message type you send and receive | The vendor already did; you integrate with its API |
| What you build | Everything below, in SCRIPT XML | Calls to the vendor's API; the vendor builds SCRIPT |
| Control | Full: your screens, your release schedule | Limited to what the vendor exposes |
| Best for | Products where e-prescribing is core | Products that need prescribing as one feature |
| Published timeline or price | None | Depends on the vendor |
What you build on route 1
- Message builder: Turns your order into SCRIPT XML for the version you support. Keep one builder per version during the transition.
- Parser: Reads inbound messages: RxChangeRequest, RxRenewalRequest, RxFill, NewRxRequest, Status, Error, Verify.
- Schema validator: Checks every outbound message against the NCPDP schema before sending. Surescripts checks field lengths, data types, repeats and code values, so catch them first.
- Directory lookup and cache: Finds the pharmacy and what it accepts. Refresh it on a schedule and on any routing error.
- Router with retries: An outbox that sends, waits for Status or Error, and retries with the same message ID so a resend is recognizable.
- Inbox and task routing: Puts each inbound request in the right prescriber's queue, matched to the original prescription.
- EPCS module: Two-factor signing and access control, if you prescribe controlled substances. See EPCS requirements.
- Audit log: Every message in and out, every user action, kept for investigation and for the EPCS rules.
The order steps are our recommended design. The validation and certification gates are Surescripts'. Our Mirth Connect NCPDP SCRIPT guide shows the same pieces built as interface-engine channels.
How does electronic prior authorization work over SCRIPT?
The prescriber's system sends PAInitiationRequest, the plan returns a question set in PAInitiationResponse, the prescriber answers in PARequest, and the plan returns its decision in PAResponse. Appeals and cancellations have their own request and response pairs, and 2023011 adds PANotification. Part D plans must support these transactions since January 1, 2022.
CMS chose SCRIPT for drug ePA after an NCPDP task group found that the X12 278 standard, the HIPAA transaction for referrals and authorizations, had gaps for medications. One gap the 2020 rule names is that X12 278 couldn't support attachments for PA decisions.
Surescripts runs an Electronic Prior Authorization service and a Prior Authorization Portal for providers whose EHR doesn't yet support ePA. CoverMyMeds is another ePA network; our CoverMyMeds guide covers its API.
What are the EPCS technical requirements?
DEA rules in 21 CFR part 1311 require identity proofing by an approved credential provider, two-factor authentication using two of three factors, two-person control over who can sign, a signing screen with a legal statement, daily audit-log review, and a third-party audit before first use and every two years. Surescripts requires proof of that audit before EPCS traffic.
| Requirement | What the rule says, in plain words | Section |
|---|---|---|
| Identity proofing | A two-factor credential from a GSA-approved credential service provider at NIST SP 800-63-1 Assurance Level 3 or above, or a Federal Bridge cross-certified authority | 1311.105 |
| Two factors | Two of: something you know, something you are (biometric), something you have (a hard token separate from the computer) | 1311.115 |
| Hard token | Meets at least FIPS 140-2 Security Level 1 | 1311.115(b) |
| Biometrics | False match rate of 0.001 or lower | 1311.116 |
| Access control | At least two people manage signing rights; a second person with a two-factor credential completes each grant or revoke | 1311.125, 1311.130 |
| Signing | The app shows the prescription data and a statement that completing two-factor authentication signs and authorizes transmission | 1311.140 |
| Audit trail | List of auditable events; review at least once every calendar day; report incidents within one business day | 1311.150 |
| Third-party audit | Before first use, then every two years or whenever an EPCS function changes | 1311.300 |
| Pharmacy side | Digitally sign and archive on receipt, back up daily, keep records at least two years | 1311.205 |
| Lost token | The practitioner reports loss or compromise within one business day | 1311.102 |
Surescripts' EPCS page lays out the vendor steps: certify the EHR for e-prescribing, get approved for EPCS, set up identity proofing, multifactor authentication and access controls, then train prescribers. States have their own EPCS rules as well; CMS says its EPCS program is separate from state EPCS requirements, so check each state you serve.
How do you test SCRIPT messages without production?
Start with ONC's free electronic prescribing test tool, which validates SCRIPT 2017071 messages against test scenarios. Network testing is Surescripts certification, arranged after sign-up, with details not public. Community GitHub code can parse messages but isn't certified. Most teams also build a simulator around a schema check and scripted responders.
Official and community tools we checked
| Tool | Type | What it does | License, last update |
|---|---|---|---|
| Surescripts certification testing | Official, network | Required testing before production; Surescripts guides participants through it | Contract; not public |
| NCPDP implementation guide and schema | Official, standard | The source of truth for elements and code values | Free to members, fee for others |
| ONC ePrescribing Test Suite | Official, federal | The eRx testing tool named on ONC's (b)(3) test method page, used for certification testing | Free, online at erx.healthit.gov |
| onc-healthit/erx-testing-tool | Official copy | Downloadable copy of the SCRIPT 2017071 validation tool with 711 test messages; ONC says it is for internal testing only and doesn't qualify for certification | No license file; last push October 27, 2021 |
| dgoradia/ncpdp | Community | Go structs to decode SCRIPT 2017071 XML, with sample NewRx tests | MIT; last push April 20, 2023 |
| uwcirg/script-fhir-facade | Community | A FHIR facade over SCRIPT interfaces used for PDMP queries | No license file; last push October 6, 2026 |
| kdar/health | Community | Go library for NCPDP and other EDI formats | MIT; last push January 17, 2019 |
| apiv/dzero | Community | Parser and serializer for Telecommunication D.0 (claims, not SCRIPT) | No license file; last push December 19, 2018 |
Repository dates are from the GitHub API on November 13, 2026. A repository without a license file can't safely be reused in a product. None of these is endorsed by NCPDP or Surescripts.
What your own simulator must fake
- The network: Return Status, Error and Verify, and hold or delay messages so retries get tested.
- A pharmacy: Scripted replies: RxChangeRequest, RxRenewalRequest, RxFill, NewRxRequest, CancelRxResponse with both outcomes.
- A directory: Fake pharmacies that support different message types and versions.
- A plan: PA question sets with branches, pended answers and denials.
- The schema check: Validate every message against the NCPDP schema you licensed.
- A scenario runner: One scripted test per edge case below, with an assertion on every message and every state change.
Use synthetic patients only. Never copy real names, dates of birth or member IDs into fixtures.
What edge cases does a SCRIPT integration have to handle?
A SCRIPT build has to handle at least 23 edge cases across seven groups: prescribing, pharmacy-side requests, patient identity, controlled substances, prior authorization, network and version issues, and long-term care or specialty drugs. Each card below gives the message order, what each person sees, the risk if ignored, the fix, and its source.
Message flows in the cards are illustrative and schematic. They use transaction names only, never spec text. Where a card says "industry practice," no public NCPDP or Surescripts source states it; it is our recommendation.
Prescribing
E1. Free-text directions instead of structured ones
- What happens
- The doctor types "1 po qd" for Ana's lisinopril instead of picking structured directions.
- Messages
NewRxwith text directions only- Who sees what
- The pharmacist reads abbreviations and may call to confirm. Ana waits.
- If unhandled
- Misread directions, extra calls, slower fills.
- How to handle
- Offer coded directions in the picker and send them with the text. NCPDP publishes a Structured Sig Format standard for this.
- Source
- NCPDP Access to Standards (Structured Sig Format); Surescripts E-Prescribing page on structuring data
<Sig>
<SigText>Take 1 tablet by mouth once a day</SigText>
<!-- structured form, as in the ONC files: Instruction with
DoseAdministration, Dosage, RouteOfAdministration, TimingAndDuration -->
</Sig>
Illustrative, built from public ONC test materials; validate against the NCPDP XSD for your version.
E2. Compound medications
- What happens
- A dermatologist prescribes a cream mixed from several ingredients.
- Messages
NewRxdescribing more than one ingredient- Who sees what
- The pharmacy may receive a description it can't map to one product.
- If unhandled
- The pharmacist phones the office; the electronic trail breaks.
- How to handle
- Test compounds as their own certification scenario, and show the pharmacy-facing preview before send.
- Source
- Industry practice. Compound fields are described only in the member-only guide.
E3. Duplicate NewRx after a timeout
- What happens
- The EHR sends Ana's NewRx, the network is slow, and the user clicks send again.
- Messages
NewRx(ID A1) thenNewRx(new ID A2) then twoStatus- Who sees what
- The pharmacy sees two identical prescriptions. Ana could get double the tablets.
- If unhandled
- Duplicate fills or confused pharmacists.
- How to handle
- Lock the order while waiting for Status. Retry with the same message ID, never a new one, and show "sending" in the UI.
- Source
- Industry practice
<!-- first try -->
<Header><MessageID>1001</MessageID> ... </Header>
<!-- no Status in time: resend the SAME message -->
<Header><MessageID>1001</MessageID> ... </Header>
<!-- wrong: a new ID makes a second prescription -->
<Header><MessageID>1009</MessageID> ... </Header>
Illustrative, built from public ONC test materials; validate against the NCPDP XSD for your version.
E4. Cancel before the pharmacy fills
- What happens
- The doctor switches Ana to another drug an hour after sending.
- Messages
CancelRxthenCancelRxResponse- Who sees what
- The pharmacy removes the old prescription. The doctor sees the cancel confirmed.
- If unhandled
- Ana picks up both drugs. Surescripts cites a study where about 10 percent of discontinued prescriptions were still dispensed before CancelRx.
- How to handle
- Send CancelRx automatically when a prescription is discontinued in the chart, and show the response.
- Source
- Surescripts E-Prescribing page
E5. Cancel after the drug was dispensed
- What happens
- The cancel arrives after Ana picked up her tablets.
- Messages
NewRx,RxFill(picked up), thenCancelRxand aCancelRxResponsewith Denied- Who sees what
- The doctor sees the cancel wasn't fully applied. Ana has the old drug at home.
- If unhandled
- The doctor assumes she stopped. She keeps taking it.
- How to handle
- Treat a Denied cancel response as a task: someone calls the patient.
- Source
- Industry practice; message names from 42 CFR 423.160(b)(1)
<CancelRxResponse>
<Response>
<Denied>
<ReasonCode>AR</ReasonCode> <!-- code used in the ONC denial sample -->
<DenialReason>Already dispensed on 2026-11-13</DenialReason>
</Denied>
</Response>
</CancelRxResponse>
Illustrative, built from public ONC test materials; validate against the NCPDP XSD for your version.
Pharmacy-side requests
E6. Pharmacy requests a change
- What happens
- Ana's plan prefers another product, so the pharmacist asks the doctor to switch.
- Messages
RxChangeRequestthenRxChangeResponse(Pending is possible on 2023011)- Who sees what
- The doctor sees original and proposed side by side. The pharmacy waits.
- If unhandled
- Ana leaves without medicine.
- How to handle
- Route to the prescriber's inbox with a clear deadline. Use Pending on 2023011 when a decision will take time.
- Source
- Surescripts FAQ; 89 FR 51242
E7. Renewal where the doctor wants changes
- What happens
- At day 30 the pharmacy asks for refills, but the doctor wants to raise Ana's dose.
- Messages
RxRenewalRequestthenRxRenewalResponsewith a replacement medication- Who sees what
- The pharmacy receives the new dose as the answer to its request.
- If unhandled
- The doctor denies and sends a separate NewRx; the pharmacy holds two records.
- How to handle
- Let the prescriber answer with a replacement in the same response. Honor RequestExpirationDate on 2023011: don't answer after it.
- Source
- 89 FR 51242 (replace medication group, RequestExpirationDate)
E8. Patient moves to another pharmacy
- What happens
- Ana's pharmacy closes and she asks a new store to take over.
- Messages
RxTransferInitiationRequest,RxTransfer,RxTransferConfirm(2017071 names: RxTransferRequest and RxTransferResponse)- Who sees what
- The new pharmacy receives the remaining refills. The old one closes its record.
- If unhandled
- Phone transfers and retyping.
- How to handle
- Map both name sets during the transition. Surescripts lists RxTransfer in its network messages.
- Source
- 89 FR 51244; Surescripts FAQ
E9. Pharmacy asks for a brand-new prescription
- What happens
- Ana has no refills and the prescription expired. The pharmacy asks the doctor for a new one.
- Messages
NewRxRequestthenNewRx, orNewRxResponseDenied- Who sees what
- The doctor gets a request tied to Ana; the pharmacy gets a NewRx or a denial.
- If unhandled
- Requests sit unanswered; Ana runs out.
- How to handle
- Show the request in the same inbox as renewals. Answer a request you decline with NewRxResponseDenied.
- Source
- 83 FR 16636; Surescripts FAQ
E10. Prescription never picked up
- What happens
- Ana doesn't collect her tablets.
- Messages
RxFill(not picked up), if the prescriber asked for that notice;RxFillIndicatorChangeto change the notices wanted- Who sees what
- The care team sees a not-picked-up flag.
- If unhandled
- Nobody notices non-adherence.
- How to handle
- Request fill notices for drugs where adherence matters and route not-picked-up notices to care management.
- Source
- Surescripts E-Prescribing page; 83 FR 16636
Patient and identity
E11. Medication history finds no match
- What happens
- Ana's history comes back empty because her name or date of birth differs from the plan's record.
- Messages
RxHistoryRequestthenRxHistoryResponsewith no or partial data- Who sees what
- The doctor thinks Ana takes nothing else.
- If unhandled
- Missed interactions.
- How to handle
- Show "no match" differently from "no medications." Send complete demographics. Surescripts uses a Master Patient Index to match.
- Source
- Surescripts E-Prescribing FAQ (Master Patient Index)
E12. Pharmacy can't take this message type
- What happens
- Ana picks a pharmacy that isn't set up for a message, or isn't on the network.
- Messages
NewRxthenError(recipient or agreement check fails)- Who sees what
- The doctor sees an error; Ana's pharmacy sees nothing.
- If unhandled
- The prescription is lost and nobody knows.
- How to handle
- Check the directory before send and offer print or fax as a fallback, with a clear message.
- Source
- Surescripts validation FAQ (recipient identification, contractual agreement)
E13. Error versus Status
- What happens
- The EHR treats every response as success.
- Messages
NewRxthenStatus, orError, orVerify- Who sees what
- The doctor sees "sent" even when the network rejected it.
- If unhandled
- Silent failures.
- How to handle
- Track each message to a final state. Alert on Error and on no response after a set time.
- Source
- 42 CFR 423.160(b)(1) (Status, Error, Verify); industry practice for the state machine
<Status><Code>010</Code></Status> <!-- delivered -->
<Error>
<Code>900</Code><DescriptionCode>1000</DescriptionCode>
<Description>parser message of invalid sender</Description>
</Error> <!-- failed -->
<!-- nothing back after your timeout: stuck, alert -->
Illustrative, built from public ONC test materials; validate against the NCPDP XSD for your version.
Controlled substances
E14. Prescriber loses the EPCS token
- What happens
- The doctor's phone with the authenticator is lost.
- Messages
- None until access is restored; no unsigned EPCS message can be sent
- Who sees what
- The doctor can't sign controlled prescriptions.
- If unhandled
- A compromised token could sign prescriptions.
- How to handle
- The practitioner reports within one business day; two admins revoke and re-grant under two-person control.
- Source
- 21 CFR 1311.102, 1311.125
E15. EPCS function changed without a new audit
- What happens
- A release changes the signing screen.
- Messages
- EPCS
NewRxblocked - Who sees what
- Prescribers may have to stop EPCS until the new audit is done.
- If unhandled
- Non-compliant prescriptions.
- How to handle
- Re-audit when any controlled-substance function changes, or every two years, whichever comes first. Notify registrants within five business days of a finding.
- Source
- 21 CFR 1311.300; Surescripts E-Prescribing FAQ (proof of audit)
E16. Transferring a controlled prescription
- What happens
- A patient on a controlled drug moves pharmacies.
- Messages
- On 2017071: not supported electronically. On 2023011: push or pull
RxTransfermessages - Who sees what
- On 2017071 the pharmacies fall back to other processes.
- If unhandled
- Delays for patients on controlled drugs.
- How to handle
- Support 2023011 transfers and detect the partner's version.
- Source
- 89 FR 51243-51244
E17. Long-term care three-way messages
- What happens
- A nursing home resident needs a controlled drug: prescriber, facility and pharmacy all take part.
- Messages
- 2023011 multi-party messages using the OtherReferenceNumber header
- Who sees what
- All three parties see the same prescription thread.
- If unhandled
- Paper or fax workarounds.
- How to handle
- Plan for January 1, 2028, when long-term care joins the Part D EPCS rule.
- Source
- 89 FR 51242; 42 CFR 423.160(a)(5)
Prior authorization
E18. Question set needs "none of the above"
- What happens
- No answer fits the doctor's case.
- Messages
PAInitiationResponse(questions),PARequest(answers)- Who sees what
- On 2017071 the doctor may be forced to pick a poor answer.
- If unhandled
- Denials based on the wrong answer.
- How to handle
- Render NoneChoiceID on 2023011 and follow the branch to the next question.
- Source
- 89 FR 51242
E19. PA pended, denied or no longer needed
- What happens
- The plan needs time, denies, or the doctor changes the drug.
- Messages
PAResponse,PANotification(2023011),PAAppealRequest/Response,PACancelRequest/Response- Who sees what
- A task that stays open until there is a final answer.
- If unhandled
- Open PAs nobody tracks.
- How to handle
- Keep a PA state per request; cancel open PAs when the drug changes.
- Source
- 85 FR 86824; 89 FR 51244-51245
Network and version
E20. Version mismatch during the transition
- What happens
- Your EHR sends 2023011; the pharmacy still runs 2017071.
- Messages
- Any 2023011-only feature, such as a Pending response or PANotification
- Who sees what
- The older side may not act on the newer feature.
- If unhandled
- A Pending answer that the pharmacy never understands.
- How to handle
- Use 2023011-only features only when the partner supports them. The rule expects each side to support transactions "as applicable to the version of the standard in use."
- Source
- 89 FR 51242, 51244
E21. Receiver outage
- What happens
- Ana's pharmacy system is down for an hour.
- Messages
NewRxheld in the Surescripts queue, then delivered in order- Who sees what
- Nothing, if it works.
- If unhandled
- Staff resend by fax, creating duplicates (see E3).
- How to handle
- Don't resend on delay alone. Trust the queue, and alert on Error.
- Source
- Surescripts E-Prescribing page (message queue service)
Long-term care and specialty
E22. A drug with a REMS program
- What happens
- A drug needs a safety-program check before dispensing.
- Messages
REMSInitiationRequest/Response, thenREMSRequest/Response- Who sees what
- The prescriber answers REMS questions; the pharmacy can dispense.
- If unhandled
- The pharmacy can't dispense.
- How to handle
- Support REMSReproductivePotential on 2023011 in place of the older field.
- Source
- 83 FR 16636; 89 FR 51242
E23. Long-term care resupply and recertification
- What happens
- A facility needs more supply of an ongoing drug, or a recertification.
- Messages
Resupply,Recertification,DrugAdministration- Who sees what
- The pharmacy and prescriber exchange supply and review data.
- If unhandled
- Manual reorders.
- How to handle
- Carry the ReviewingProvider group on 2023011 when another provider reviews.
- Source
- 83 FR 16636; 89 FR 51242
How should you handle errors and known issues?
Give every message a final state: delivered, failed or stuck. Retry with the same message ID, never a new one. Validate against the schema before sending, because the network rejects bad syntax and code values. Refresh the directory on routing errors, and turn every failure a person must act on into a visible task.
- Syntax and code values: Surescripts checks field lengths, data types, repeats and code values. Run the same check in your build pipeline.
- Recipient and agreement errors: Usually a directory problem. Refresh and re-select the pharmacy.
- Silent waits: A request with no response is a common invisible failure. Alert when a response is late, as well as on Error.
- Version features: Gate 2023011-only features on the partner's support (E20).
- Cancel and transfer races: Expect responses that don't confirm what you asked (E5).
- Logs: Keep every message in and out. EPCS rules require daily audit review; the same log answers support tickets.
The Status, Error and Verify names are from the rule. The state model and retry rules are our recommended design.
How is NCPDP SCRIPT different from FHIR MedicationRequest?
SCRIPT is the regulated message format for sending prescriptions across the U.S. network, with defined requests, responses and acknowledgements. FHIR MedicationRequest is an HL7 data model many EHRs use to store and share the order through APIs. They overlap in content, but federal Part D rules and Surescripts require SCRIPT on the wire.
In Ana's EHR, the order may live as a FHIR MedicationRequest. When it leaves for the pharmacy, it becomes a SCRIPT NewRx. Mapping between them is where many details get lost: directions, drug codes, and the follow-up messages that FHIR has no single equivalent for.
HTI-4 also adopted HL7 Da Vinci FHIR specifications for provider prior authorization APIs. Those are separate from SCRIPT ePA for drugs. We cover the mapping in our FHIR MedicationRequest vs NCPDP SCRIPT gap post. Nirmitee builds SMART on FHIR apps, HL7 interfaces and bulk data pipelines; see our SMART on FHIR app development page.
How long does an NCPDP SCRIPT integration take?
No public source gives a certification timeline. Our build estimates, once access is in place, are 1 to 2 weeks for read-only features such as medication history, 2 to 4 weeks for a workflow such as NewRx or renewals, and 4 to 6 weeks for multi-party work such as ePA or EPCS. Certification and audit waits come on top.
| Phase | Our estimate | What drives it |
|---|---|---|
| Route decision, contracts, NCPDP access | Not published | Vendor or Surescripts timelines |
| Simulator and schema checks | 1 to 2 weeks | Number of messages and versions |
| NewRx, Status, Error, CancelRx | 2 to 4 weeks | Drug and pharmacy pickers, directory |
| RxChange, RxRenewal, NewRxRequest, RxFill inbox | 2 to 4 weeks | Matching to originals, task routing |
| Medication history | 1 to 2 weeks | Patient matching display |
| ePA | 4 to 6 weeks | Dynamic question sets, attachments |
| EPCS | 4 to 6 weeks plus audit | Identity proofing partner, two-person control |
| Certification testing and pilot | Not published | Surescripts schedule, fixes found |
Sources
All read on November 13, 2026.
- 42 CFR 423.160, Medicare Part D e-prescribing standards (eCFR, current): ecfr.gov
- 45 CFR 170.205, health IT standards (eCFR, current): ecfr.gov
- 21 CFR part 1311, electronic orders and prescriptions for controlled substances (eCFR, current): ecfr.gov
- Federal Register, June 17, 2024, 89 FR 51238, CMS-4205-F2 (SCRIPT 2023011, RTPB 13, F&B 60): govinfo.gov
- Federal Register, December 31, 2020, 85 FR 86824, Secure Electronic Prior Authorization for Part D: govinfo.gov
- Federal Register, April 16, 2018, 83 FR 16440, CY 2019 Part D rule adopting SCRIPT 2017071: govinfo.gov
- CMS, E-Prescribing Standards and Requirements: cms.gov
- ASTP/ONC, HTI-4 final rule fact sheet: healthit.gov; HTI-4 key dates: healthit.gov
- NCPDP, Access to Standards: standards.ncpdp.org
- NCPDP, What Do I Need for HIPAA? (revised January 2026): ncpdp.org
- CMS Blue Button, NCPDP_ID variable: bluebutton.cms.gov
- Surescripts, E-Prescribing (including FAQ): surescripts.com
- Surescripts, E-Prescribing for Controlled Substances: surescripts.com
- Surescripts, Electronic Prior Authorization: surescripts.com
- Surescripts, Medication History for Ambulatory: surescripts.com
- Surescripts, Real-Time Prescription Benefit: surescripts.com
- GitHub repositories listed in the testing table, via the GitHub API
Ready to scale?
Talk to our healthcare engineering team about building, integrating, and shipping faster.
Frequently Asked Questions
What is NCPDP?
What does NCPDP stand for in pharmacy?
What is an NCPDP number?
What is the NCPDP SCRIPT standard?
What is the current NCPDP SCRIPT version?
What is the difference between NCPDP SCRIPT and the Telecommunication standard?
What is NCPDP D.0?
What does an NCPDP SCRIPT message look like?
Is NCPDP SCRIPT free?
Do I need Surescripts certification to send e-prescriptions?
What are the EPCS requirements?
When did NCPDP SCRIPT 2017071 become required?
What is new in NCPDP SCRIPT 2023011?
Does NCPDP SCRIPT support electronic prior authorization?
Can I test NCPDP SCRIPT messages without production access?
