Event Types
VitaRelay emits the core order and intake events below. Every order/intake.reviewed
payload includes event (the type) and occurred_at (ISO 8601 timestamp); the newer
intake.submitted event uses the versioned envelope shown in its section. Storefront
integrations also receive the full order lifecycle (order.cancelled, order.fulfilled,
order.payment_failed) and subscription lifecycle events. Deliveries generated by the sandbox
also include "sandbox": true.
In live,
order_id, patient_id, and escript_id are UUIDs and
order_number is the real order number. In sandbox, ids look like
sandbox_ord_…, sandbox_pat_…, and sandbox_int_….Order events
Every order event (order.paid, order.shipped, order.delivered, order.cancelled, and the rest) also
carries the patient and the order’s lines, so you can tell what was bought and by whom without a second call:
patient_id: the VitaRelay patient id (the idPOST /patientsreturned; the same id everysubscription.*event carries). Save it next to your own user record when you create the patient.items: one entry per order line:item_kind(productorcustom),item_id,name,quantity, andproduct_idfor products. For a product,item_idandproduct_idare the catalog product id (the valuePOST /ordersaccepts asproduct_id). For a clinic service (custom),item_idis the service’s id, the id listed undercustom_productsinGET /shop.
order.invoiced
Fires when an order that is billed on an invoice (rather than charged to a card) is added to an invoice. It carriesinvoice_id, invoice_number, issued_on and due_on alongside the usual order fields. The order is not paid yet: order.paid follows when the invoice payment is recorded, with paid_via: "invoice".
order.paid
Fires when the order is paid — either the clinic’s card-on-file charge succeeds or, for apatient_checkout order, the patient’s payment via POST /orders/{id}/pay succeeds.
order.shipped
Fires when the order ships and tracking is attached.order.delivered
Fires when the carrier reports delivery.order.exception
Fires when the carrier reports a delivery problem (failed attempt, return to sender, address issue, and similar).Intake events
Subscription events
Subscription webhooks use the versioned envelope and may include:subscription.created,
subscription.updated, subscription.paused, subscription.resumed,
subscription.canceled, subscription.renewed, subscription.payment_failed, and
subscription.rx_hold. shop.item.updated fires when subscription settings change.
Every subscription event’s data includes: subscription_id, patient_id, item_kind,
item_id, quantity, cadence, status, paused_reason, next_charge_at. Event-specific
extras: reason (paused), skipped_next (updated), order_id + charged_cents (renewed),
order_id + held_item_count (rx_hold), and for subscription.payment_failed: order_id,
attempt, max_attempts, next_retry_at, final.
subscription.payment_failed fires on every failed attempt (retries after 2 and 3 more
days). The third failure sets final: true, next_retry_at: null, and also emits
subscription.paused with reason: "payment_failed".
subscription.renewed, subscription.payment_failed, and subscription.rx_hold are never emitted while patient billing is in dry-run mode (no real charge happens). Created/updated/paused/resumed/canceled events emit normally in dry-run.
intake.reviewed
Intake reviewed / prescription signed. Fires the moment a prescriber signs the escript — this is the “Rx cleared” signal you should key fulfillment off of.If you placed the order before the prescription existed (the order is
submitted), signing is
followed by a check that the signed product and quantity match your order. Only then does the
order become processing and go to the pharmacy. A mismatch holds the order for VitaRelay review,
so for those orders follow the order’s status, not just this event. See
Intakes and prescriber review.intake.submitted
Fires the moment an intake is submitted — by the patient on their hosted intake link, or by your app throughPOST /intakes or the referral intake/submit. When the intake completes an
order’s waiting intake, the order moves to prescriber review and the prescription request is
sent to the doctor network. Use the event to know the intake is in. PHI-free: it carries ids, category, and status only —
never the patient’s answers. This event uses the versioned envelope
(type + event + api_version + created_at + data).
Sandbox deliveries
Events generated by the simulated sandbox lifecycle are identical in shape but carry"sandbox": true and sandbox ids:

