Patient Shop Subscriptions
UseGET /shop to read the same storefront configuration shown in VitaRelay. Every product, custom item, and package returns:
Cost and pharmacy fields are never returned.
Create
Create subscriptions withPOST /subscriptions and the subscriptions:write scope. Send the patient, item kind, storefront item id, quantity, cadence, saved payment method, and a saved address for shippable items.
Buy through POST /orders
Each order line may carrypurchase (one_time default, or subscription), cadence, and quantity. Lines use either product_id (catalog product, unchanged behaviour) or item_kind + item_id. Subscription lines require a top-level payment_method_id (patient saved card) and use ship_to_address_id or the patient’s preferred address.
{ "data": { "id": null, "order_id": null, "status": "subscribed", "subscription_ids": ["…", "…"] } }. When one-time lines are included, order_id is the order created for them and subscription_ids is returned alongside it.
Endpoint examples
GET /subscriptions?patient_id=…&status=active → 200
POST /subscriptions → 201
When the item bills its first cycle at signup (first_order_immediate), the first charge is made during this call, using the patient’s saved card. Otherwise it is scheduled for next_charge_at.
First charge succeeded:
first_charge.status is one of charged, declined (card refused), failed (the order could not be created; nothing was charged), not_charged (billing is switched off for the account), or scheduled (not due yet; no order is returned). decline_reason is a short, patient-safe message from the card network, or null.
GET /subscriptions/{id} → 200
PATCH /subscriptions/{id} with { "cadence": "quarterly" } → 200, same shape as GET.
POST /subscriptions/{id}/pause, /resume, /cancel → 200 { "ok": true }
POST /subscriptions/{id}/skip-next → 200 { "ok": true, "next_charge_at": "2026-11-25T04:06:14Z" }
Manage
UseGET /subscriptions, GET /subscriptions/{id}, PATCH /subscriptions/{id}, and the pause, resume, cancel, and skip-next actions. Cross-organization resources return 404.
Organizations operating under another white-label brand cannot mutate storefronts or subscriptions. Those writes return 403 with white_label_restricted.
Events
Every subscription event’sdata contains subscription_id, patient_id, item_kind, item_id, quantity, cadence, status, paused_reason, and next_charge_at. subscription.payment_failed fires on every failed attempt with attempt, max_attempts (3), next_retry_at, and final; the third failure also emits subscription.paused with reason: "payment_failed".
Subscribe to subscription.created, subscription.updated, subscription.paused, subscription.resumed, subscription.canceled, subscription.renewed, subscription.payment_failed, and subscription.rx_hold. Dry-run billing does not emit renewal or payment events.
Saving a card for auto-renew (embedded checkout)
When paying an order withPOST /v1/orders/{id}/pay, add "save_card": true alongside opaque_data. If the charge is approved, VitaRelay saves the card to the patient’s wallet (it becomes their default card if they don’t have one), and future subscription renewals charge it automatically. The response includes saved_payment_method_id (null if nothing was saved, including sandbox/dry-run orders). Only send save_card after the patient has agreed to have their card kept on file.
