Get In Touch

How to Create, Prepare, and Cancel Prescriptions via NHS EPS-FHIR API

Written by Technical Team Last updated 15.08.2025 13 minute read

Home>Insights>How to Create, Prepare, and Cancel Prescriptions via NHS EPS-FHIR API

What the NHS EPS-FHIR API Does and How It Fits Into Spine

The Electronic Prescription Service (EPS) is the national, Spine-hosted service that routes electronic prescriptions between prescribers and community dispensers in England. The EPS-FHIR REST API exposes the core prescriber interactions you need to automate from secondary care outpatient systems (and, increasingly, other settings): prepare a prescription for signing, create (submit) the prescription to Spine, and cancel a prescription that has already been created. In plain terms, you assemble a standards-based FHIR message, encode and sign it, then deliver it to Spine; EPS takes care of the distribution to the patient’s nominated or chosen dispenser.

“Prepare → Sign → Submit” might sound like a single flow, but each step exists for important safety and legal reasons. Preparing validates and encodes the data for a non-repudiable digital signature; signing binds a specific prescriber identity to that exact payload; submitting deposits the signed payload to Spine where it becomes the operative prescription. The surface area is deliberately small: a $prepare operation, a $process-message to create, and—when you need to reverse course—a further $process-message carrying a cancellation update.

As you design your integration, keep the broader ecosystem in mind. EPS prescriber flows depend on other national services: PDS to match the patient and determine nomination, dm+d for medicine coding, CIS2 for strong authentication and digital signatures, and MESH for certain asynchronous responses (notably some cancellation outcomes). There’s also a tracker API you can use to follow a prescription’s journey once it leaves your system. Building once against the EPS-FHIR specification gives you a pathway to all these capabilities in a consistent way.

EPS integration Prerequisites, Assurance, and Security

Before you can test, let alone go live, you’ll need to complete onboarding and assurance activities for EPS and the supporting national services. The prescriber developer guide sets out the moving parts succinctly: you must be able to look up patients in PDS, work with dm+d codes for medications, and determine dispenser details and nomination correctly. For user sign-in and signing, you’ll use NHS CIS2 authentication; for certain asynchronous messages—especially follow-ups to pending cancellations—you’ll need a MESH mailbox integration. These are separate onboarding tracks that culminate in your system being authorised to call EPS endpoints in the intended environment.

Authentication and authorisation are layered. On the client-to-platform side you authenticate to the NHS API Platform (Apigee) using issued credentials and security arrangements; within your app you must ensure the prescriber is authenticated with CIS2 and holds the correct RBAC roles. When you generate signatures (either locally with your own smartcard-aware module or via the NHS Digital Signing Service API), you’re binding the prescriber’s credential to the payload you prepared. In production practice, systems commonly combine machine-to-machine OAuth credentials for API access, an Accredited System ID (ASID) for Spine-facing identity, and CIS2 sign-in for the human prescriber.

You should also design for the operational realities of EPS. Phase 4 made EPS the default for primary care and removed the need for a pre-set nomination in many journeys by enabling token-based collection, but nomination remains a critical data point because it determines automatic release and batch download behaviour on the dispensing side. Secondary care outpatient prescribing via EPS piggybacks on these same mechanics, so your data quality and nomination logic directly affect the patient experience at the pharmacy counter.

To help your team scope and sequence the work, here’s a concise readiness checklist:

  • Complete supplier onboarding and assurance for EPS, plus the supporting services you rely on (PDS, CIS2, MESH).
  • Implement patient matching and nomination retrieval from PDS; do not maintain local nomination caches.
  • Use dm+d for all items and populate structured dose syntax in DosageInstruction.
  • Decide your signature architecture: integrate the NHS Digital Signing Service API or your local smartcard-aware solution.
  • Stand up monitoring for submission outcomes and learn how to use the EPS Tracker to follow prescriptions through dispensing.

Preparing an EPS Prescription: Assembling the FHIR Message and Calling $prepare

The “prepare” step exists to safeguard the integrity of the message you will sign. At this stage you construct a FHIR message—commonly a Bundle of type message—that contains a MessageHeader and the resources needed to represent the prescription order. At minimum, expect to include Patient, Practitioner (and/or PractitionerRole), Organization for the prescriber’s organisation or cost centre, and a set of one to four MedicationRequest resources for the items you’re issuing on this prescription. EPS enforces a maximum of four items in one prescription message; if the clinician prescribes more than four, you must generate multiple messages that will be signed and submitted individually.

Every medication item must reference a dm+d code. This is non-negotiable; EPS prescribers and dispensers work off a shared medicines dictionary to avoid ambiguous free text. Beyond coding, EPS expects structured dose syntax. Instead of dumping instructions into a free-text field, you populate MedicationRequest.dosageInstruction in a structured way so instructions can be validated and interpreted consistently. It’s tempting to shortcut by copying the text clinicians are used to typing; resist that urge and invest in robust dose builders in your UI. The benefit shows up later in fewer rejections and smoother dispensing.

Nomination handling comes next. If the patient has a nominated dispenser (P1, P2 or P3), you carry that through into the message so Spine can release the prescription automatically to the correct dispenser’s batch. If there’s no nomination (0004), you can still create a prescription; the patient can present a token at any pharmacy to retrieve it. Your system must retrieve the ODS code of the nominated dispenser from PDS (for P1, P2 or P3) or treat the message as non-nominated with type 0004. For one-off nomination scenarios, you’ll populate the P1 nomination type and set the ODS code accordingly, using up-to-date data from PDS or the appropriate directory API rather than any local cache.

Once your prescription-order message is assembled, call the $prepare operation at /FHIR/R4/$prepare. The service returns encoded prescription data that you must sign before submission. This is an important pivot: after preparation, you must not alter any signed content; any change requires a new prepare/sign cycle so the digital signature remains valid. Handle the $prepare response carefully—store the encoded payload temporarily and associate it with the human prescriber who will sign, then present a non-repudiation screen that displays the salient details exactly as they will be bound into the signature.

That non-repudiation moment is where your user experience can make or break safety. A compliant UI will present patient demographics (including NHS number), prescriber identifiers and organisation codes, the nominated dispenser where applicable, and the complete set of items with quantities, units, endorsements, and the structured dose. If you support Controlled Drugs, enforce quantity-in-words generation. Right before applying the signature, re-authenticate the user with their NHS-provisioned CIS2 authenticator to confirm intent. In practice, prescribers expect this step to be quick but unambiguous; keep the screen focused and the confirmation flow crisp.

Creating (Submitting) an EPS Prescription: Signing, Provenance, and $process-message

After $prepare completes, you’ve got a message that is ready to sign. There are two broad paths here. If you already maintain a smartcard-aware signing solution, use it to generate the prescriber’s advanced electronic signature over the prepared content. Alternatively, many suppliers adopt the Digital Signature Service API, which works with the user’s CIS2 session to produce a signature without your app talking directly to smartcard readers. Either way, your signature must bind the prescriber’s identity to the exact prepared content, and you’ll place the resulting signature in a FHIR Provenance resource attached to your message.

With the signature in place, you submit the prescription using the $process-message operation at /FHIR/R4/$process-message. Think of this as handing your sealed envelope to Spine. The response is a FHIR Bundle that includes an OperationOutcome describing success or failure—what legacy EPS documentation calls the “application acknowledgement”. Treat the OperationOutcome as your authoritative receipt: store it, surface it in your UI, and wire it into your monitoring so that failed submissions are alerted and retried, not silently lost.

Release behaviour depends on nomination. For a nominated prescription, Spine schedules it into the relevant dispenser’s batch download automatically—your job is done until a dispenser interacts with it. For a non-nominated prescription, a dispenser can search for the script using the prescription identifier printed (or displayed) as a token, which the patient presents. Your system should generate both paper and electronic tokens; the requirements are set out in assurance documents, but in practice that means enabling print and secure digital sharing.

From this point forward, operational visibility becomes crucial. Build a link from each submitted prescription to the EPS Tracker so staff can confirm its status without ringing round pharmacies. The tracker supports searches by NHS number, date ranges, and status; when something goes awry—an unexpected rejection or a patient who can’t collect—you’ll be grateful for a single, auditable trail. While the tracker isn’t part of the create/prepare/cancel contract itself, designing it into your workflow reduces support load and improves patient communications.

Finally, take error handling seriously. You’ll see two classes of issues: platform-level (e.g., 401/403 from the API gateway if credentials or headers are wrong) and EPS-level (OperationOutcome describing validation failures or business rule breaches). Developers often first encounter 401s in integration environments when assuming an endpoint is open; in reality, bearer tokens are generally required, even in INT. Make authentication explicit in your client and log request IDs to speed up NHS support interactions.

Cancelling an EPS Prescription: Business Rules and Messaging Patterns

Cancellations are not a separate “delete” verb; they are FHIR messages you submit via $process-message to update the state of an existing prescription. Specifically, you send a prescription-order-update message that instructs EPS to cancel one or more items—or the entire prescription when you cancel all items. This preserves a full audit trail and keeps the messaging pattern consistent with creation. Operationally, your UI should make item-level versus script-level cancellation choices clear so prescribers don’t over- or under-cancel by accident.

The most important business rule is whether the prescription is “with a dispenser”. If it has not yet been downloaded or acted upon, cancellation usually succeeds immediately and you’ll get a successful response synchronously. If it is with a dispenser, your cancellation request will not succeed immediately; instead it becomes “pending” until the dispenser returns the prescription to Spine. That return can happen because the dispenser actively withdraws it, or because they reject it (for example, if the patient never turns up), at which point EPS can complete the cancellation and you’ll receive a subsequent response—often via MESH. This is why your MESH integration matters even if you rarely use it elsewhere.

From an implementation standpoint, build humane workflows for pending cancellations. Show prescribers the dispenser details that EPS includes in responses so they can call the pharmacy if needed, and log a follow-up task in your system to check for the subsequent response. Where possible, surface expected timeframes in your training materials; dispensing workflows vary, but the prescriber’s experience improves markedly when your product guides them through what to do next. Consider embedding a quick link to the EPS Tracker in the cancellation view for extra reassurance.

To reduce avoidable cancellations, add validation earlier in the chain. Catch dosage omissions (structured syntax required), missing dm+d codes, and nomination inconsistencies at prepare time. If your product supports Controlled Drugs, force the “quantity in words” rule to avoid legal non-compliance that would otherwise result in a downstream cancellation and re-issue. These nudges cost little and pay for themselves in fewer failed submissions, fewer calls to community pharmacies, and a calmer clinic.

Practical teams also prepare for edge cases and failure modes. Use the following playbook to cover the most common scenarios without improvisation on the day:

  • Cancellation requested after download – Mark the request as pending, display the dispenser’s ODS/name, and prompt the user to contact the pharmacy. Subscribe for or poll the subsequent cancellation outcome via MESH; once received, update the patient record and notify the prescriber.
  • Partial cancellation – Allow item-level cancellation with a clear summary of what remains active. If the clinical intent is to replace one item with another, guide the user to issue a fresh prescription for the replacement item after cancellation.
  • Prescription returned by dispenser – Handle FHIR Task/return flows appropriately in your dispenser-facing integrations and reflect the returned status in the prescriber UI so a pending cancellation can complete. This is especially relevant where no dispensing has occurred.
  • Token-related confusion (non-nominated) – Provide a “resend token” function and patient-friendly wording that explains how to collect. Remind staff that non-nominated prescriptions won’t appear in a dispenser’s batch until the patient presents the token.

Planning a Robust, Patient-Centred EPS Integration

Designing a great EPS-FHIR integration is about more than moving JSON around; it’s about helping clinicians issue safe prescriptions quickly, helping pharmacies receive unambiguous instructions, and sparing patients a return trip because of fixable data issues. The pathway starts with sound prerequisites: get your PDS, CIS2 and MESH integrations into shape, treat dm+d as your single source of truth for coding, and make nomination logic transparent in your UI so clinicians can see at a glance where a script will go. With those foundations laid, the prepare-sign-submit loop becomes predictable and safe.

At prepare time, invest in clinical quality. Excellent dose builders with structured DosageInstruction fields save pharmacists from guesswork. Non-repudiation screens that are readable at a glance protect prescribers from mistakes. When you call $prepare, capture and display exactly what will be signed; when you sign, either through your own smartcard-aware module or the Digital Signature Service API, ensure your Provenance is attached properly and that nothing in the payload changes between signing and submission. In practice, most implementation bugs cluster around these boundaries, so logging, idempotency, and crisp error messages are your friends.

On submission, treat $process-message responses as first-class domain events. Persist OperationOutcomes, attach them to your patient and prescription records, and expose them in support tooling so your first-line teams can answer “where is my prescription?” without involving developers. Then wire in EPS Tracker lookups from your UI; that single step dramatically shortens resolution time when a patient is at the counter and the dispenser can’t immediately find the script. This is also where you’ll feel the benefits of making tokens easy to print or share electronically for non-nominated prescriptions.

Cancellations deserve a final nuance: culturally, prescribers regard them as “undo”, but technically they are new messages with their own lifecycles and dependencies. When cancellations are immediate, feed confirmation back to the prescriber and the patient record straight away; when they’re pending, guide the user on next steps and let your system do the waiting by subscribing for outcomes via MESH. You’ll also want to ensure your audit model records not just the fact of cancellation but also the reason and the outcome path—this matters for safe practice as well as compliance. The more legible you make this in your UI, the less likely clinicians are to issue a second prescription prematurely while the first is still active.

As NHS EPS continues to evolve—bringing richer FHIR resources, better tracking, and smoother dispenser interactions—the fundamentals in this guide will hold: encode using dm+d, structure your dose syntax, use $prepare before you sign, submit with $process-message, and cancel by sending a prescription-order-update. Wrap those interactions with strong identity via CIS2, store and surface OperationOutcomes, and keep the patient journey front and centre. Done this way, your EPS integration won’t just be compliant; it will be calm, predictable, and genuinely helpful to clinicians and patients alike.

Need help with EPS integration?

Is your team looking for help with EPS integration? Click the button below.

Get in touch