Building an E-Prescription Integration — A Real-World Case Study

The Problem

Our healthcare platform helps patients manage their weight loss journey. Part of this includes prescriptions — doctors write them, and patients send them to their pharmacy.

The system worked well for one region using email-based prescriptions. But when we expanded to a new region, we needed a different approach. The new region required legally compliant electronic prescriptions — sending a PDF by email was not enough.

We needed to integrate with a third-party e-prescription platform that handles the legal requirements, digital signatures, and pharmacy notifications.


The Solution

We added a region selector to the patient app. Depending on the patient’s location:

  • Region A — existing email flow (unchanged)
  • Region B — electronic prescription via a third-party API

The patient searches for their pharmacy from a curated list, selects it, and clicks send. The rest happens automatically — the prescription is signed, the pharmacy gets notified, and the patient sees a confirmation.


How It Works

Here is the high-level flow:

Patient App — selects region, searches pharmacy, sends prescription

Our Backend — loads prescription, doctor, and patient data, builds the API payload, sends to the e-prescription platform

E-Prescription Platform — validates and signs the prescription, notifies the pharmacy by email with a secure token

Pharmacy — receives the email, opens the prescription using the token, dispenses the medication, marks as dispensed

Webhook — the platform sends a status update back to our system, our database updates automatically (signed to dispensed)


Technical Architecture

The integration involves four main components:

  1. Patient Frontend (Angular) — region selector, pharmacy search dropdown with address display, send button
  2. Backend API (Node.js / TypeScript) — handles authentication, builds the prescription payload, manages webhook events
  3. Third-Party E-Prescription API — processes the prescription, manages digital signatures, notifies pharmacies
  4. Database (PostgreSQL) — stores prescription status, tokens, and pharmacy data

The backend runs on AWS EKS (Kubernetes), with CI/CD through Bitbucket Pipelines. Environment variables are managed through Kubernetes secrets, injected from the CI/CD pipeline.


Key Challenges and Lessons Learned

1. Two-Step Authentication

The third-party API uses a two-step authentication process:

  1. OAuth token — using client credentials (client ID + secret) to get an access token
  2. Prescriber login — using the access token + prescriber credentials to get a session token

Both tokens are needed for every API call. The backend caches them and refreshes automatically when they expire.

Lesson: Always check if a third-party API requires multiple authentication steps. Read the docs carefully — the login endpoint might need a token from a previous step.

2. Internal IDs vs Display IDs

The platform’s dashboard showed a clinic ID like 201334. But the API expected a different internal ID (994) for the same clinic. Using the dashboard ID caused an “unauthorized clinic” error.

This took days to debug because the error message was not clear, and the API documentation did not explain the difference between the two IDs.

Lesson: Never assume that the ID you see in a dashboard is the same one the API expects. When something fails with an “unauthorized” error, check if there is a different internal identifier.

3. API Errors Returned as HTTP 200

The API returned errors with HTTP status code 200 (OK) but with success: false in the response body. Our code initially treated every 200 response as a success, so failed prescriptions were saved as “sent” in our database.

{
  "success": false,
  "message": "You trying to issue prescription to unauthorized clinic."
}

Lesson: Always check the response body for a success flag, not just the HTTP status code. Some APIs use 200 for everything and put the real status in the JSON body.

4. Response Structure Discovery

The API documentation did not clearly show the response structure for creating a prescription. We had to add temporary debug logging to capture the full response and find the correct path to the prescription token.

The token was nested deep in the response:

response.data.data.prescription.id

Not at the top level where we expected it.

Lesson: When integrating with a third-party API, expect to spend time discovering the actual response format. Add debug logging early, test with real calls, and remove the debug code before going to production.

5. Webhook Integration

The platform supports webhooks to notify our system when a prescription status changes (signed, dispensed, expired, voided). Setting it up required:

  • A publicly accessible HTTPS endpoint on our backend
  • HMAC-SHA256 signature verification for security
  • Returning a 2xx response immediately before doing any processing

The webhook allows us to track the full prescription lifecycle without polling the API.

Prescription Status Flow:
issued → signed → dispensed
                → expired (if patient does not collect)
                → voided (if cancelled)

Lesson: Implement webhooks early in the integration. They are essential for keeping your data in sync with the third-party platform.

6. Don’t Change What Works

At one point, the integration was working perfectly. I made a change to “improve” the authentication header format — and it broke everything. Multiple hours were spent debugging something that was not broken before.

Lesson: If the integration works, do not refactor the API call format. Test any changes in isolation first before deploying. This applies especially to authentication headers — third-party APIs can be very specific about the exact format they expect.


Testing with Limited Resources

E-prescription integrations are tricky to test because:

  • Each prescription uses a token — you cannot reset and resend the same prescription
  • Staging environments may behave differently — credentials, clinic IDs, and permissions can differ between staging and production
  • Manual steps are needed — creating test prescriptions in the database, seeding pharmacy data, setting up doctor credentials

We created SQL scripts to bulk-insert test prescriptions with medications, so we always had fresh ones available for testing.


The Stack

ComponentTechnology
Patient FrontendAngular
Backend APINode.js, TypeScript, Express
DatabasePostgreSQL, TypeORM
InfrastructureAWS EKS (Kubernetes)
CI/CDBitbucket Pipelines
Container RegistryAWS ECR
SecretsKubernetes Secrets

Results

After the integration:

  • Patients can send prescriptions electronically to pharmacies in the new region
  • Prescriptions are digitally signed and legally compliant
  • Pharmacies receive instant email notifications with a secure dispensing link
  • Our system tracks the full lifecycle: issued, signed, dispensed
  • The existing email-based flow for the original region remains unchanged

Final Thoughts

Integrating with a third-party healthcare API is not just about writing code. It involves:

  • Understanding their authentication model
  • Discovering undocumented API behaviors
  • Coordinating with their support team when things break
  • Testing carefully with limited resources
  • Being patient when things do not work as expected

The most important lesson: test in Postman before writing code, and do not change what already works.

Tags:

Comments are closed