Changelog
This page tracks meaningful changes to the partner-facing API surface, webhook contract, and integration guides. Contact partners@stealth.health for an email digest of changes.
We follow a "no breaking changes without a major version bump and a 90-day deprecation notice" policy. Additive changes (new fields, new events, new endpoints) ship in minor releases.
2026-08 — 0.2.6
Added
customer+shippingblocks on store-order payloads. Thestore_order.payment_completewebhook event and theGET /partner/store/orders/:transaction_idpolling response now carry acustomerobject (first_name,last_name,email,phone) and ashippingobject (address,address2,city,state,zip,country) so partners can fulfil customer-paid orders without a manual address handoff.shippingis the address supplied at order creation when one was sent, otherwise the address the customer entered on the hosted checkout; it isnullwhen neither exists (typically while the order is stillpayment_pending). Additive — existing payload fields are unchanged.
2026-07 — 0.2.5
Added
authorize_onlypayment mode (pre-auth, capture on clinical approval).POST /partner/appointmentsnow acceptspayment.mode: "authorize_only"— Embedded Checkout with manual capture. Completing the embedded session places an authorization hold on the customer's card (funds reserved, not charged; appointmentpayment_statusbecomesauthorized). Stealth captures the hold when the reviewing physician approves (transaction.succeededwithcapture_of_authorization: true) and voids it when the patient is clinically ineligible (transaction.authorization_released, paired withreferral.denied/prescription.rejected) — an ineligible patient is never charged. Request shape matchesembedded_checkout(return_url,amount_cents,product_name). Per-partner opt-in (AUTHORIZE_ONLY_NOT_ENABLED, 403, without it); sandbox is open to every clinical-tier partner. Card-network authorization windows apply (typically 7 days) — see Clinical Tier § 5.4.transaction.authorization_releasedwebhook event — emitted when anauthorize_onlyhold is voided after a clinical denial. This is a release of held funds, not a refund. See Clinical Tier § 13.2.- Wearables Data API (clinical tier). Three new read-only, patient-scoped endpoints expose the wearables data patients generate by connecting devices (Oura, Fitbit, Garmin, WHOOP, Apple Health, Dexcom, and the rest of the Junction Sense catalog) in the (white-label) patient portal:
GET /partner/patients/:id/wearables/connections(device connection status per provider),GET /partner/patients/:id/wearables/summaries(per-day rollups — sleep, activity, body, workouts, heart rate, blood pressure, glucose; windows up to 90 days), andGET /partner/patients/:id/wearables/timeseries(intraday samples for one metric — CGM curves, HR traces; windows up to 31 days, paginated up to 5,000 samples/page). Production access requires the wearables BAA addendum (WEARABLES_ACCESS_REQUIRED, 403, without it — emailpartners@stealth.health); sandbox is open to every clinical-tier partner. Every read is PHI-audited. New error codesWEARABLES_ACCESS_REQUIRED,WEARABLE_DATE_INVALID,WEARABLE_METRIC_INVALID. See Clinical Tier § 12B. wearable.connection.*webhook events —wearable.connection.created,wearable.connection.revoked, andwearable.connection.errorfire when a patient you own connects, disconnects, or breaks auth with a wearable provider (requiresfeatures.wearables). Payloads carryprovider_slug+statusonly — no measurements; poll the summaries endpoint for data. No data-drop events are emitted (a CGM would generate hundreds per patient per day). See Clinical Tier § 12B.4.- Referral Tier § 6 cross-reference. The referral-tier API reference now points readers to the clinical guide for the PHI-bearing endpoint families (patients, lab orders & requisitions, documents, partner-submitted intake/prescriptions, payment modes), which are not available to referral-tier keys.
2026-06 — 0.2.4
Added
- Embedded Checkout payment mode for partner-submitted intake.
POST /partner/appointmentsnow acceptspayment.mode: "embedded_checkout", returning a Stripe Embedded Checkoutclient_secret(+session_id) instead of a hostedpayment_url. Partners render the payment form inside their own page and Stripe collects the full billing + shipping address natively. On completion, Stealth reconciles the collected address back onto the appointment (patientAddress,shippingAddress,patientCountry,patientJurisdiction) — HIPAA-audited asappointment.partner_checkout.address_applied— so the clinician sees a complete destination before review. New request fieldspayment.return_url(required https),payment.amount_cents,payment.product_name; new errorsRETURN_URL_REQUIRED,PAYMENT_AMOUNT_INVALID,CHECKOUT_AMOUNT_UNRESOLVED. See Clinical Tier § 5.4. - Embeddable messaging module (
@wearestealthhealth/messaging-embed). A drop-in React component and vanilla-JS UMD/CDN bundle that frames the secure patient messaging surface inside a partner app with a one-click SSO handoff. New endpointPOST /partner/patients/:id/sessionsmints a short-lived, single-use opaque embed token (the partner never receives a platform credential); the iframe exchanges it server-side for a session credential. Ships apostMessageevent API (messaging:ready,messaging:unread-count,messaging:tos-required,messaging:tos-accepted,messaging:error), in-iframe theming, ToS pre-display gating, and a mobile-fallback deep link. See Clinical Tier § 9.3. - Per-partner embed origin allowlist (
embed_allowed_origins). The patient app now emitsContent-Security-Policy: frame-ancestors 'self' <partner origins>on/embed/*, built from the union of every partner's configured origins. Manage your preprod + prod origins (bare hosts and*.partner.comwildcards accepted) via your account manager / the reporting portal's white-label Partner API step.
Changed
- Zero-downtime webhook-secret rotation. Rotating a partner's
webhook_secretnow opens a 7-day dual-verify window: deliveries are signed with both the new secret (X-Stealth-Signature) and the old secret (X-Stealth-Signature-Previous). Accept a delivery if either header validates against the secret you hold, deploy the new secret at your leisure, and the previous-signature header simply stops appearing after the window. See Clinical Tier § 17.2.
Fixed
embedded_checkoutresponse now returns thepublishable_keyneeded to mount Stripe. ThePOST /partner/appointmentsembedded_checkout201 previously returned onlyclient_secret+session_id, leaving partners with no way to initialize Stripe.js (Stealth is the merchant of record, so partners have no publishable key of their own) — mounting<EmbeddedCheckout>failed with a "publishable key is not configured" error. The response now includespayment.publishable_key(Stealth's account-scoped key, selected server-side by mode + currency/region) andpayment.stripe_account. Initialize withloadStripe(payment.publishable_key)— the key is account-scoped, so no separatestripeAccountoption is needed. Always read it from the response rather than hard-coding. See Clinical Tier § 5.4.- Idempotent replays of
embedded_checkoutsubmissions no longer fall back to the hosted response. Re-submitting aPOST /partner/appointmentsrequest with a previously usedpartner_referenceandpayment.mode: "embedded_checkout"previously returned the original appointment with a hostedpayment_urlblock. Replays now correctly returnpayment.mode: "embedded_checkout"and mint a fresh Checkout Session (Stripe client secrets are single-session), so expect a newclient_secret+session_idon each replay — don't cache the old one.
2026-05 — 0.2.3
Added
- Stealth-doctor sign path now fires
appointment.prescription_signed. Previously this event only emitted from the legacy JotForm pipeline and the partner-submitted-Rx flow. As of0.2.3, the doctor-portal queue handler (submitDoctorPrescription) and the standalone Rx flow (submitStandalonePrescription) also emit it whenever a partner-owned appointment is signed. Clinical-tier partners receive the documented slim shape (appointment_id,prescription.rx_id,prescription.medications[]); referral-tier partners continue to receivereferral.approvedonly. See Clinical Tier § 13.2.1 for the canonical payload. prescription.rejectedextended to the Stealth-doctor reject path. Until now this event was reserved for the partner-submitted-Rx async re-validation path. As of0.2.3, it also fires fromrejectAppointmentwhenever a Stealth physician declines to sign for a partner-owned appointment. The companionreferral.deniedevent still fires at the same instant — partners on the clinical tier should expect both. The newerror_codeenum (MEDICAL_CONTRAINDICATION,INCOMPLETE_INFORMATION,NOT_A_CANDIDATE) is documented in Clinical Tier § 13.2.2.
Notes for existing handlers
- The wire payloads match the schemas already documented in
0.2; this release is the implementation catching up to the spec. Partners who builtappointment.prescription_signed/prescription.rejectedhandlers per the docs do not need to change anything — they will start receiving events that previously did not fire. - Backfill is not provided. If you need a backfill for partner-owned appointments signed or rejected before
0.2.3, contactpartners@stealth.health— we can replay from the audit log on a per-partner basis.
2026-05 — 0.2.2
Added
- Clinical Tier — § 12 API Reference — Lab Orders & Requisitions. Four new clinical-tier endpoints expose the lab orders placed for partner-owned patients:
GET /partner/patients/:patient_id/lab-orders— list lab orders with status / collection-method filters.GET /partner/lab-orders/:lab_order_id— full order detail, including event timeline and any booked Patient Service Center appointment.GET /partner/lab-orders/:lab_order_id/requisition— signed-URL (default) or inline-PDF download of the lab requisition. 15-minute TTL on signed URLs; 90-day retention on the underlying PDF.GET /partner/lab-orders/:lab_order_id/results— structured biomarker results once the lab releases them (partialorfinal), withmissing_results[]for samples the lab couldn't process.
- Six new webhook events in the lab-order family:
lab_order.created,lab_order.requisition_ready,lab_order.sample_collected,lab_order.results_updated,lab_order.completed,lab_order.cancelled,lab_order.exception. Biomarker values are intentionally omitted from webhook payloads — partners re-fetch via the results endpoint. See Clinical Tier § 13.2 Additional Clinical Events and the Glossary event catalog. messageThread.updatedwebhook in the messaging family. Fires when a clinician or patient posts a message in a thread linked to a partner-owned appointment. Body is not included in the payload — partners pokeGET /partner/patients/:patient_id/messages?updated_after=...to pull the new content. See Clinical Tier § 9.1.- Clinical Tier — § 9.2 Partner-submit policy & patient-authored messages. New subsection documenting that messaging is read-only for partners and explaining the three supported patterns for patient-authored replies (SSO into the patient portal, iframe-embed with CSP allowlist, polling + read-only mirror).
- Lab Order Object and Lab Order Results Object added to § 14 Data Models (§ 14.8, § 14.9).
- New ID prefixes registered in the Glossary:
lab_(lab order),psc_apt_(Patient Service Center appointment). - Lab-orders-specific error codes added to § 15 Error Handling:
LAB_ORDER_NOT_FOUND,REQUISITION_NOT_READY,REQUISITION_EXPIRED,RESULTS_NOT_AVAILABLE,LAB_ORDER_ACCESS_REQUIRED.
Changed
- Lab orders / requisitions / biomarker results added as a new data class in the Clinical Tier § 3.3 "Where PHI Crosses the Wire" table.
- Section numbers in the Clinical Tier guide shifted by one to make room for § 12. Old § 12 Webhook Events → § 13; old § 13 Data Models → § 14; old § 14 Error Handling → § 15; old § 15 Rate Limits → § 16; old § 16 Best Practices → § 17 (with sub-sections 16.1–16.6 renumbered to 17.1–17.6). All in-document anchor refs and the cross-references in Glossary have been updated.
- Clinical Tier § 9.1 now documents the supported query parameters (
status,appointment_id,updated_after,limit,cursor) and thePATIENT_NOT_FOUND/CLINICAL_ACCESS_REQUIRED/QUERY_ERRORerror catalog. Endpoint behavior is unchanged.
Access requirements
- Production access to the lab-orders endpoints is gated on a per-partner BAA addendum acknowledging the additional PHI surface (panel selection + biomarker values). Sandbox is open to every clinical-tier partner. Email
partners@stealth.healthto enable in production. Requests without the addendum returnLAB_ORDER_ACCESS_REQUIRED.
2026-05 — 0.2.1
Added
- Questionnaire Embed Integration Guide added to the docs site. Covers the Vanilla JS drop-in script, the React/npm package (
@wearestealthhealth/questionnaire-embed), thepostMessageevent protocol, CSP allowlist, white-labelwl=param, version pinning, and the full questionnaire-ID → enroll-page → US-medication catalog. The embed is a delivery mechanism that pairs with any integration tier. - Referral Tier § 6.8
GET /partner/events— read-only endpoint to retrieve webhook events from the dead-letter queue (and any other delivery state) for replay and reconciliation. Filterable byevent_type,referral_id,partner_reference,delivery_status, and time range. 30-day retention. Backfills the previously-broken §6.8 reference in §7.5.
Fixed
- Broken intra-doc anchor in Prescriber-Partner § 6.1 that pointed to
#74-get-partnerproducts(Products endpoint actually lives at § 9.3).
2026-04 — 0.2
Added
- Clinical Tier — Partner-submitted prescriptions. Clinical-tier partners can now register their own licensed prescribers and submit prescriptions written by them via two new endpoints:
POST /partner/prescribers,GET /partner/prescribers,GET /partner/prescribers/{id},DELETE /partner/prescribers/{id}— manage the partner-prescriber registry.POST /partner/prescriptions— submit a prescription tied to a registered prescriber. Patient resolution accepts an existingpatient_id, an existingreferral_id, or an inline patient profile.- Two new webhook events:
prescription.receivedandprescription.rejected. - Controlled-substance handling: schedule II–V Rx requires a valid
dea_numberfor US prescribers; CDSA Schedule I–V Rx requires a Canadian provincial license. Partial details in Clinical Tier § 11.2.
- Clinical Tier — HIPAA & compliance section expanded with Stealth Health's technical controls (TLS 1.2+, AES-256 at rest, key handling, webhook integrity, sub-processor list) and a new § 17 Partner Implementation Best Practices (originally added as § 16; renumbered in 0.2.2).
- Partner documentation site (this site) launched at docs.stealth.health.
Changed
- All Google Cloud regional references updated to
us-east5(Columbus, Ohio).
Webhook events added
prescription.receivedprescription.rejected
2026-03 — 0.1 (Initial draft)
Added
- Referral Tier — initial spec covering enrollment URL minting, lifecycle webhooks, transactions, and shipment tracking. PHI-free.
- Clinical Tier — initial spec covering patient profiles, intake responses, appointments, prescriptions, transactions, and clinical-tier webhook events under a BAA.
- Prescriber-Partner Tier — initial spec for partners that own the patient intake and consume Stealth Health physician review and signing as a service.
- Authentication:
X-Partner-ID+X-Api-Key, HMAC-SHA256 signed webhooks (X-Stealth-Signature). - Standardized error code catalog and per-tier rate limits (300 req/min prod / 60 req/min sandbox).
How versioning works
- Major (
1.0,2.0) — breaking changes to request/response shapes, removed fields, or removed endpoints. Communicated 90 days in advance via email + this changelog. Old version stays available until the deprecation window closes. - Minor (
0.2,0.3) — additive changes. New fields are non-breaking; clients are expected to ignore unknown fields and unknown webhook event types. - Patch / docs — wording, example, or diagram updates with no behavioral change. Not separately versioned.
The Content-Type of all API responses includes the version, e.g. application/vnd.stealth.health.v1+json. The current version sent on the wire is documented in each tier guide.