Fires when shipping/tracking details are recorded for a prescription fulfillment — either received from the pharmacy or set manually by a TelegraMD admin. The eventType is shipping_details_set.
Field guarantees
| Field | Guarantee |
|---|---|
eventData.shippingDetails | ✅ Always present (v1) — as an object; its inner fields vary by path (below) |
eventData.shippingDetails.trackingNumber | ⚠️ Conditional — the CTRL-pharmacy path fires when a tracking number or tracking URL arrives, so it can fire with only trackingUrl; the admin-set path passes the submitted details through unvalidated |
eventData.shippingDetails.shippingCompany | ⚠️ Conditional — optional on the CTRL and admin-set paths; pharmacy integrations may send it as null |
eventData.order | ⚠️ Conditional — absent on admin-set and some transformer paths |
| Tracking fields in v2 | ✅ Delivered — tracking_number, tracking_url, shipping_carrier on the SHIPPING allowlist |
Do not treat a missingtrackingNumberas a contract violation. Type every field insideshippingDetailsas optional and handle a delivery that carries only atrackingUrl(or neither, on the admin-set path). Only theshippingDetailsobject itself is guaranteed in v1.
v1 payload (legacy)
The full raw event document. Tracking details live under eventData.shippingDetails; targetEntity is the PrescriptionFulfillment.
{
"_id": "event::41f6eb4e-xxxx-xxxx-xxxx-a38d1b04d547",
"ownerEntity": "pat::aa6b0901-xxxx-xxxx-xxxx-ca0c10a6e1c3",
"ownerEntityModel": "Patient",
"targetEntity": "prfm::6597ad9d-xxxx-xxxx-xxxx-0375e64b14b8",
"targetEntityModel": "PrescriptionFulfillment",
"eventTitle": "Prescription shipping details were received from the pharmacy.",
"eventDescription": "TrackingNumber: 1Z99V3Y213xxxxxxxx / Tracking URL: null",
"eventType": "shipping_details_set",
"eventData": {
"shippingDetails": {
"trackingNumber": "1Z99V3Y213xxxxxxxx",
"shippingCompany": "UPS Next Day Air Saver",
"shipped": true,
"trackingURL": null
},
"order": "order::8c2283fc-xxxx-xxxx-xxxx-399b08e24216"
},
"deleted": false,
"createdAt": { "$date": "2025-10-20T17:24:11.738Z" },
"updatedAt": { "$date": "2025-10-20T17:24:11.738Z" },
"__v": 0
}eventData field | Type | Always? | Notes |
|---|---|---|---|
shippingDetails.trackingNumber | string | ⚠️ | Carrier tracking number — absent when the CTRL path fires on a tracking URL alone, or when admin-set details omit it |
shippingDetails.shippingCompany | string | null | ⚠️ | Carrier / service name — optional on the CTRL and admin-set paths; some integrations send null |
shippingDetails.trackingUrl | string | null | — | Some pharmacy integrations emit trackingURL (capitalized) instead — handle both keys |
shippingDetails.shipped | boolean | — | |
order | string | ⚠️ | Order id; absent on the admin-set path and some pharmacy transformer paths |
v2 payload
Sanitized envelope. Tracking fields are extracted from eventData.shippingDetails (or the target entity) and delivered as top-level fields.
{
"event_type": "shipping_details_set",
"event_id": "event::41f6eb4e-xxxx-xxxx-xxxx-a38d1b04d547",
"api_version": "2026-08-17",
"timestamp": "2026-05-30T14:00:00.000Z",
"affiliate_id": "aff::xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"patient_id": "pat::aa6b0901-xxxx-xxxx-xxxx-ca0c10a6e1c3",
"patient_external_id": "ext-patient-123",
"patient_marketing_consent": false,
"is_returning_patient": true,
"order_id": "order::8c2283fc-xxxx-xxxx-xxxx-399b08e24216",
"prescription_id": "rx::example",
"commerce_status": "processing",
"shipment_status": "in_transit",
"tracking_number": "1Z99V3Y213xxxxxxxx",
"tracking_url": "https://www.ups.com/track?loc=en_US&tracknum=1Z99V3Y213xxxxxxxx",
"shipping_carrier": "UPS Next Day Air Saver"
}| Field | Delivered in v2 | Notes |
|---|---|---|
| Envelope + patient identity | ✅ | Present on every v2 payload |
order_id, commerce_status, prescription_id | ✅ | Resolved from the fulfillment and linked order |
tracking_number, tracking_url, shipping_carrier | ⚠️ | Present when the emitting path supplied them — same conditionality as v1 |
Nested shippingDetails object | ⛔ | Flattened into top-level tracking fields |
