Skip to main content

How Tagada Rx works

One page, four concepts: the clinical network adapter, the PHI transit rule, the webhook pipeline, and the ship-day rebill engine. Understand these and everything else in this section is just API calls.

1. The clinical network adapter

Tagada does not run doctors. It integrates clinical networks — companies that operate licensed provider groups and pharmacy routing. Every network is wrapped behind one adapter interface, so your integration code never changes when the network does.
The active network is configured per store (clinicalNetworkSlug, default mdi). You can list what’s available to your account with GET /api/v1/rx/networks.

2. PHI: transit, never storage

The single most important design rule:
Tagada never persists PHI. Patient identity (name, DOB, address) and intake answers pass through the API to the clinical network in a single request and are not written to any Tagada table, queue, or log. What Tagada stores is routing data only: rxcase_xxx, the network’s case id and patient id, statuses, timestamps, and non-PHI event metadata.
Practical consequences:
  • Case submission is synchronous — there is no “queue the intake and retry later”, because PHI must not sit in a queue. If the network is down, the storefront shows a retry UI.
  • Message bodies live at the network. The patient portal relays threads directly from the clinical network; Tagada records only that a message.created event happened.
  • Emails are content-free. “You have a new message from your care team” + a portal deep-link. Never the message text.

3. The webhook pipeline

The clinical network notifies Tagada of everything that happens after submission:
Key properties:
  • Signature-verified — HMAC-SHA256 over the raw body, checked against the integration’s webhookSecret before anything is processed.
  • Fast ACK — the receiver verifies, normalizes, enqueues, and returns 200. All database work happens asynchronously with retries.
  • Idempotent — every event carries a synthesized externalEventId; duplicates are dropped at both the queue and the append-only event log.
  • Patient-scoped fallback — message webhooks may arrive without a case id; Tagada resolves the case through the stored network patient id.
Your storefront never consumes these webhooks directly — it polls the public case-lookup endpoint or reads the portal API, both of which reflect the processed state.

4. The ship-day rebill engine

Classic subscription engines charge every N days from signup — which drifts from what the pharmacy actually does. Tagada Rx anchors billing to fulfillment:
1

Pharmacy ships

The shipment.shipped webhook lands. Tagada records the tracking number and stamps lastShipmentShippedAt.
2

Next charge is scheduled

scheduledNextChargeAt = ship day + cycle (default 30 days, configurable per offering).
3

Hourly scan

A cron scans cases whose scheduledNextChargeAt is due and whose status is shipped or delivered — i.e. active subscribers only.
4

Refill fires

The rebill charges the stored payment instrument and requests the refill from the network. On the next shipment, the loop repeats.
Declined, cancelled, and errored cases never rebill. If a clinician declines mid-subscription, the commission accrued in affiliate mode is automatically reversed (see Operating modes).

Product mapping: what makes a product “Rx”

There is no flag on the product itself. A product requires a prescription when it has an active offering mapping:
Each mapping carries the clinical requirements the storefront needs to render the right flow: Storefronts ask at product load: GET /api/public/v1/rx/required-for-product?productId=…{ required, requiresLabs, requiresIdVerification, … }, and only render the intake when required is true.

Next

Operating modes

MoR (affiliate) vs Direct Merchant.

End-to-end tutorial

Build the whole flow in an afternoon.