Developer Changelog

RxRelay API changes

Developer-facing changes to the RxRelay API, webhook events, documentation, and integration tooling.

2026-10-07

Re-order an existing order through the partner API

  • POST/v1/orders/{orderId}/reorder creates a new whole order linked to the original. Approval defaults on; explicitly set submitForApproval: false for normal direct submission. Sandbox requests remain record-only and non-billable. Organization keys select the source clinic in the request body.
  • Current ordering rules are revalidated. Re-orders preserve the original shipping snapshot, allow explicit shipping/prescriber overrides, and default newly authorized refills to zero. New identifiers, pricing, approval, and submission history are created; external identifiers and metadata are not inherited. This is a new prescription, not a pharmacy refill dispense.
  • Examples now show both live submission paths: submitForApproval: true stages for review, followed by approval of the NEW returned orderId; submitForApproval: false requests direct pharmacy dispatch. On the approval endpoint, approve: false rejects the order. A 201 creation response is not confirmation of pharmacy acceptance.
  • Re-orders honor sandbox and demo clinic modes for direct submission, approval, and queued dispatch. Demo origin remains record-only after a clinic returns to live mode; sandbox clinics cannot fall back to production pharmacy connections. Dispatch rechecks current clinic modes and blocks stale production routes when a clinic switches to sandbox.
  • sourceOrderId is additive on order responses, lists, and order webhooks. Re-ordering requires a new idempotency key per intended new order; identical retries return the same new order. Retry mappings are saved with order creation before pharmacy dispatch. Existing POST/v1/orders approval defaults are unchanged.

2026-10-06

Shipping state validation and pharmacy coverage errors

  • Partner address writes continue to require recognized two-letter codes for the 50 U.S. states or DC. Invalid supplied states now return 400 with code invalid_shipping_state. Orders using a saved address with an unrecognized state return 422 with the same code, instead of allowing unknown states through pharmacy coverage checks.
  • Recognized full names on older saved addresses are normalized in the new order's shipping snapshot. A valid state blocked by the selected pharmacy returns 422 with code pharmacy_shipping_state_blocked. Queued dispatch, approval dispatch, and retries recheck restrictions before sending. Correct the address or pharmacy selection rather than retrying these errors unchanged.

2026-10-06

Webhook destination safeguards for clinics and organizations

  • Breaking change: webhook destinations now require public HTTPS URLs. HTTP, localhost, private/reserved addresses, embedded credentials, and fragments are rejected; redirects are not followed. Configure the final receiver URL, or use a public HTTPS tunnel for local testing. Existing unsafe endpoints fail delivery until corrected.
  • Queued deliveries and manual replays now recheck current environment and event subscriptions. Switching to sandbox-only or removing an event also blocks pending and replayed deliveries that no longer match. Synthetic test webhooks remain available on active endpoints without order data. Payload schemas and signing rules are unchanged.

2026-10-06

Organization API key quickstart and endpoint examples

  • Documentation now explains how to discover clinics with GET/v1/clinics and use one organization key across existing patient, catalog, and order endpoints. Each affected request includes an organization-key example with the clinic selector in its required location.
  • Clarified that POST/v1/orders selects its clinic in the body; patient and list endpoints use query parameters; GET/v1/orders/{orderId} and approval derive the clinic from the order. Added troubleshooting for missing selectors, inaccessible clinics, and scope failures. This documents existing behavior; no API contract or error response changed.

2026-10-05

Organization member invitations replace partner clinic creation

  • Read/write organization keys can invite org_member or org_admin through POST/v1/organization/invites when RxRelay enables the separate invitation permission. It defaults off, independently of the retired clinic provisioning setting.
  • New accounts receive a seven-day invitation; existing accounts gain organization access immediately. Identical pending retries do not resend email, and invitations never downgrade an existing admin. Sandbox keys also send invitation emails when permitted.
  • Breaking change: partner POST/v1/clinics now returns 403. Clinic creation, attachment, and organization configuration are managed by RxRelay. Organization keys cannot write clinic memberships; clinic-scoped POST/v1/users remains available for clinic-specific users and prescribers.

2026-10-05

Sandbox approval stays non-dispatching and non-billable

  • Fixed a sandbox isolation bug in POST/v1/orders with submitForApproval: true. Sandbox API orders now stage with Sandbox submissions, and approval records Approved / SandboxReceived without contacting a pharmacy or accruing billable usage, including approval through the app or a live key.
  • POST/v1/orders/{orderId}/approval now rejects sandbox keys attempting to approve or reject non-sandbox-origin orders with 403 and code sandbox_order_required. Approval webhooks for sandbox orders use the sandbox environment. Already-sent orders require separate pharmacy reconciliation and billing review; this change does not recall prescriptions or refund charges.

2026-10-05

Order responses include quantity and refills

  • Full order responses from POST/v1/orders and GET/v1/orders/{orderId}, and webhook events containing full order items (including order.tracking_updated), now include items[].quantity as a string and items[].refills as an integer, read from the saved order line.
  • These additive fields describe the ordered quantity and authorized refills; they do not confirm the amount shipped. Request fields, quantity semantics, pharmacy dispatch, and webhook event names are unchanged.

2026-09-28

Patient phone validation and normalized storage

  • Patient phone writes now accept 10-digit U.S./Canada numbers with common formatting and an optional 1 or +1 country prefix, then save 10 digits such as 3147501409. Area code and exchange must start with 2–9. Invalid numbers, extensions, and other country codes return 400; this is a validation change for POST/PATCH/v1/patients and inline patient creation/upserts in POST/v1/orders.
  • Omitted, null, or blank phone on an existing-patient update preserves the saved number. Orders referencing patientId still ignore demographics; PATCH the patient to change its phone. Historical values are not bulk-rewritten. Retry an ambiguous order with the identical original body and idempotency key; changing phone formatting still changes the request hash.

2026-09-28

Pharmacy-specific medication availability

  • Products disabled platform-wide are excluded from GET/v1/medications across every clinic, including sandbox. New POST/v1/orders requests validate current availability and return 400 (Order routing failed) when no permitted route remains. Refresh cached catalogs and surface the rejection instead of retrying unchanged.
  • Existing orders retain their approval, dispatch, and retry behavior. Medication records and completed idempotent replays are preserved. Re-enabling a product still respects pharmacy availability and clinic formulary restrictions. No request fields or webhook events change.

2026-09-28

Emerald orders require recorded patient allergies

  • Breaking validation change: RxRelay now requires known allergies with a valid list or explicit no_known_allergies for new and unsent Emerald orders, including sandbox and POST/v1/orders. Missing or unknown profiles return 400 with code patient_allergies_required. No partner grace period applies; other pharmacies remain optional.
  • PATCH existing patients before ordering by patientId, or supply allergyProfile when creating/upserting an inline patient. Approval and first dispatch recheck the profile. Never-sent prepared requests refresh their allergy field; already-attempted orders are not resent and completed idempotent replays remain available. This records information for Emerald’s prescription PDF and does not perform allergy screening.

2026-09-28

Patient allergy profiles

  • POST/v1/patients and PATCH/v1/patients/{patientId} accept an optional allergyProfile with unknown, no_known_allergies, or known status and an allergy list. Patient responses include the saved profile. Omitted or null profiles preserve existing data; missing historical information remains unknown.
  • POST/v1/orders accepts allergyProfile on inline patients resolved by external ID or email. When referencing patientId, PATCH the patient first; a non-null inline profile is rejected. Older requests preserve their idempotency hashes. Emerald receives allergies for its generated PDF; Boothwyn receives the allergy array, with vendor acceptance still pending verification. Other adapters and webhook payloads are unchanged.

2026-09-24

Boothwyn patient-specific clinical justification

  • GET/v1/medications now exposes requiresClinicalJustification. Boothwyn GLP-1s, testosterone, and other flagged products require prescriber-provided patient-specific rationale in items[].clinicalJustification on POST/v1/orders, including sandbox orders.
  • The dedicated field is separate from pharmacyNotes and has a 4,000-character RxRelay limit. Missing required text returns 400. Full order responses preserve the approved rationale. Older requests that omit the field retain their idempotency serialization; requirements still apply to new orders. Partner webhook events are unchanged.

2026-09-22

Organization clinic access and shared configuration

  • GET/v1/clinics now lists enabled clinics for read-only and read/write organization keys without requiring clinic provisioning permission. Clinic creation still requires provisioning permission and read/write access.
  • Requests supplying both clinicId and externalClinicId must identify the same clinic. Organization membership supports dashboard clinic switching while prescribing permissions remain assigned per clinic.
  • Clinics can inherit an organization medication catalog and webhook destinations or use explicit clinic overrides. Newly provisioned organization clinics inherit these settings; payment methods and agreement acceptance remain clinic-specific.
  • Order and tracking webhook envelopes include clinicId, externalClinicId and organizationId. Organization webhook inheritance replaces local destinations, and queued events are not delivered to a former organization after detachment. Existing event types and signature verification remain unchanged.

2026-09-22

Exact quantities for Emerald tablets and capsules

  • POST/v1/orders now accepts obsidian.dispenseQuantity for Emerald products counted as each. Send quantity: "1" with the exact prescribed unit count, such as 45 tablets from a 30-count SKU. Catalog pack size is not a minimum, increment, or automatic dispense quantity.
  • Days supply covers the full exact dispense. Full order responses include the saved dispenseQuantity. Measured products still use one prescription per pack; requests without the new field retain legacy pack-count behavior and idempotent retries remain compatible.

2026-09-14

Emerald prescriptions through Obsidian

  • Configured clinics can use Emerald's database-backed catalog. GET/v1/medications includes optional obsidian package sizes and clinical defaults; order quantity counts whole packs for these products.
  • POST/v1/orders accepts Emerald days supply per pack and clinical difference statements. Refills must be zero. Full order responses preserve the approved package and clinical details.
  • Emerald shippingMethods reflect configured service codes. Partners use normalized Overnight or 2Day values; RxRelay sends the matching pharmacy code explicitly. Uncertain pharmacy submissions are held for reconciliation to prevent duplicate prescriptions. Emerald lifecycle updates now reconcile existing orders; recoverable pharmacy issues must not trigger replacement prescriptions. Shipment tracking uses the existing order.tracking_updated event with unchanged partner payloads.

2026-08-28

Shipping-aware coding-agent workflows

  • The official integration, review, and API-update skills now explicitly verify that one API order routes to one pharmacy and that delivery choices come from that pharmacy's GET/v1/pharmacies shippingMethods values.
  • The skills preserve compatibility with the legacy Standard two-day alias while distinguishing pharmacy-fixed service, partner-selectable service, and vendor-owned selection so agents do not assume Standard means the same service for every pharmacy.
  • The API documentation maintenance workflow now audits the published coding-agent skills, their prompts, and readiness schema and validator whenever partner-visible API semantics change.

2026-08-28

More reliable LifeFile tracking updates

  • RxRelay now accepts both single-object and batched LifeFile status callbacks, so shipping and tracking updates are processed regardless of which supported callback shape the pharmacy sends.
  • Authenticated callbacks now produce sanitized operational diagnostics for parsed, rejected, and unmatched updates without storing complete pharmacy webhook bodies in application logs.
  • When a callback includes new tracking, RxRelay continues to mark the pharmacy submission shipped and queue the existing order.tracking_updated webhook for configured partner endpoints. No partner request or webhook payload fields changed.

2026-08-28

Discoverable pharmacy shipping methods

  • GET/v1/pharmacies now includes an additive shippingMethods array with the preferred normalized request values available for each pharmacy. Optimal Balance advertises Overnight as its only service, while Pioneer pharmacies advertise 2Day and Overnight.
  • POST/v1/orders continues to accept the legacy Standard value and default without breaking existing integrations. It now also recognizes clearer two-day aliases including 2Day, 2-day, and two day, case-insensitively; responses retain Standard as the legacy normalized name for two-day delivery.
  • The order documentation now states that one API order must route entirely to one pharmacy and explains when a pharmacy-fixed service overrides the requested shipping method.

2026-08-19

Prescription and shipping details in order responses

  • Order item responses now include directions, allowing integrations to retrieve the stored prescription sig with GET/v1/orders/{orderId} when a pharmacy requests clarification.
  • The additive field also appears in POST/v1/orders and POST/v1/orders/{orderId}/approval responses, plus standard order and order.tracking_updated webhook item payloads. No existing fields changed or were removed.
  • Order responses, list summaries, and standard order and tracking webhooks now include shippingMethod, the effective normalized service stored after routing (Standard or Overnight). It may differ from the requested value when the pharmacy owns service selection: LifeFile is always Overnight, while Boothwyn's vendor-native service is configured separately and represented as Standard.

2026-08-12

Kaduceus and Boothwyn pharmacy notes

  • POST/v1/orders now accepts optional items[].pharmacyNotes for Kaduceus/Pioneer and Boothwyn medications. RxRelay snapshots the note on the prescription line; Boothwyn receives it per prescription, while Pioneer receives it through the order-level notes field.
  • Each note is limited to 500 characters. For Kaduceus submissions with multiple prescription lines, distinct nonblank notes are combined in item order and must also total 500 characters or fewer. Notes supplied for another pharmacy return 400 Bad Request rather than being silently discarded.
  • Full order responses and order webhook item payloads now echo pharmacyNotes. This is an additive request and response change; no existing fields changed or were removed.

2026-08-11

Agent-assisted integration, reviews, and API updates

  • The API documentation now provides official coding-agent skills for implementing a new RxRelay integration, reviewing an existing one, or updating it against the latest OpenAPI contract and changelog.
  • All workflows retrieve the current public contract rather than relying on model memory, enforce safe sandbox/live credential handling, run relevant tests, and refresh human-readable and machine-readable RxRelay readiness reports.
  • Review and update workflows begin read-only, report relevant releases and integration gaps, and request permission on a concrete file-by-file plan before editing. All skills prohibit putting secrets in chat and prohibit live order mutations.
  • New integrations, reviews, and API updates focus on the concrete work required for valid, safe order submission. Optional performance and production hardening are reported separately; broader production certification runs only when explicitly requested.
  • The integration skill now asks partners to choose Full, Standard, or Minimal scope. Full and Standard cover the broader clinic workflow across medications/products, pharmacies, prescribers, patients, addresses, orders, and status synchronization; organization-scoped features remain deferred by default.
  • Rerunning a documentation prompt refreshes the installed skill from its canonical URL, and every RxRelay skill checks the current published procedure before acting so an older installed copy cannot silently use stale instructions.
  • Skill install and reference URLs use the canonical www.rxrelay.ai host so direct-download installers do not depend on following the apex-domain redirect.

2026-08-07

Tracking on full order responses

  • GET/v1/orders/{orderId} now returns trackingNumber and updatedAt at the top level, matching the order summaries returned by GET/v1/orders and GET/v1/patients/{patientId}/orders.
  • trackingNumber is null until tracking is received. updatedAt uses the same lifecycle activity calculation as the list response, so clients can compare the summary and detail representations reliably.
  • The shared full-order shape returned by POST/v1/orders and POST/v1/orders/{orderId}/approval, and included in standard order webhook payloads, gains the same additive fields. No existing fields changed or were removed.

2026-08-06

Required quantity for Boothwyn metoprolol

  • Boothwyn SKU 13776 (Metoprolol Succinate 25mg ER) must be ordered with quantity 6 on POST/v1/orders. Any other quantity returns 400 Bad Request before the order is created.
  • The RxRelay order and bulk-entry screens now default this product to quantity 6. The Boothwyn dispatch path enforces the rule again so queued orders and retries cannot bypass it.
  • GET/v1/medications now includes nullable requiredQuantity. Partners should use a non-null value as the exact items[].quantity for that product. This is an additive response change; no existing fields changed or were removed.

2026-08-05

Tracking and update timestamps in order lists

  • Order summaries returned by GET/v1/orders and GET/v1/patients/{patientId}/orders now include trackingNumber and updatedAt.
  • trackingNumber is the latest tracking number for the order's pharmacy submission. It is null until tracking is received, then lets integrations display tracking without fetching every order individually.
  • updatedAt is the latest partner-visible order activity. It advances for submission attempts, approval or cancellation, and vendor status or tracking events; it equals createdAt until the order changes.
  • This is an additive response change — no existing fields changed or were removed. The hosted OpenAPI endpoint reflects the new fields when the updated API is deployed.

2026-08-01

Prescriber approval queue visibility

  • Orders can now be staged inside the RxRelay app for a prescriber to approve before anything reaches a pharmacy. Orders created through this API are unaffected — they continue to dispatch immediately and are never queued.
  • Order responses gained an approval object — status (Pending, Approved, or Rejected), submittedForApprovalAt, reviewedAt, and note. It appears on GET/v1/orders/{orderId}, POST/v1/orders, and the summaries returned by GET/v1/orders and GET/v1/patients/{patientId}/orders. It is null for every order that did not go through the queue.
  • Aggregate order status can now be PendingApproval, meaning the order is waiting on a prescriber and has not been sent to a pharmacy. If you branch on status, treat it as not-yet-dispatched rather than an error. It is also accepted as a status filter on GET/v1/orders.
  • Three webhook events were added: order.pending_approval, order.approved, and order.rejected. order.approved is distinct from order.sent — approved is the human decision, sent is the pharmacy hand-off that follows it. They use the same envelope and data.order nesting as existing order events.
  • Existing webhook destinations are unchanged: each endpoint stores its own event subscription list, so no destination begins receiving these events until it explicitly subscribes.
  • Creating an order now returns 400 when the resolved prescriber has no NPI on file. Every pharmacy payload requires one, so these orders previously failed later at dispatch instead of being rejected up front.
  • Aside from the new status value, this is an additive change — no existing fields changed or were removed.
  • Two-step ordering is now available through the API as well: send submitForApproval on POST/v1/orders to hold an order, then release it with POST/v1/orders/{orderId}/approval. approverUserId is required and must be a prescriber, owner, or clinic admin in that clinic; look ids and roles up with GET/v1/users. stagedByUserId is optional and attributes who prepared the order.
  • Both are opt-in. Orders created without submitForApproval behave exactly as before.

2026-07-29

Prescriber returned on orders

  • Order responses now include prescriber, the prescriber the order was written under — userId, firstName, lastName, and npi. Previously the prescriber could be set on an order but never read back, so a webhook receiver had no way to attribute an order without tracking it itself.
  • prescriber appears on GET/v1/orders/{orderId} and POST/v1/orders, on the summaries returned by GET/v1/orders and GET/v1/patients/{patientId}/orders, and in the order.* and order.tracking_updated webhook payloads.
  • The object is null when an order has no prescriber on record, and npi within it is nullable. prescriber.userId matches the userId returned by GET/v1/prescribers.
  • This is an additive change — no existing fields changed or were removed.
  • The hosted OpenAPI endpoint reflects these changes when the updated API is deployed.

2026-07-14

Patient email and phone required

  • Creating a patient now requires email and phone in addition to firstName, lastName, and dateOfBirth. This applies to POST/v1/patients and to inline patient creation on POST/v1/orders — a request missing either returns 400 Bad Request.
  • Email and phone are required to prescribe: the fulfilling pharmacy rejects a submission without them, so an order that would otherwise be created and then fail downstream is now rejected up front.
  • POST/v1/orders returns 400 Bad Request when an order routes to a pharmacy that requires the patient's email and the patient has none on file. Creating a patient with these fields resolves it.
  • A missing shipping address on POST/v1/orders now returns 400 Bad Request instead of a server error.
  • The hosted OpenAPI endpoint reflects these changes when the updated API is deployed.

2026-07-11

Curated pharmacy medication names

  • GET/v1/medications now uses a human-curated product label for Kaduceus and LifeFile products when an exact downstream-product override is configured, with the pharmacy's raw name as fallback.
  • Curated labels are display-only. Ordering and pharmacy dispatch continue to use the original medication id and downstream product identifier.
  • The RxRelay medication pickers treat a curated name as a complete label while continuing to render structured vial size separately.

2026-07-11

Optimal Balance package sizes and active catalog status

  • GET/v1/medications now populates vialSize for mapped Optimal Balance injections and creams when LifeFile includes a trailing package volume in its catalog strength.
  • Optimal Balance medication maps now support active/inactive status. Inactive products are excluded from catalogs and new orders while remaining available to already-created orders for dispatch and retry safety.
  • The hosted OpenAPI endpoint reflects the updated LifeFile administration contract when the updated API is deployed.

2026-07-10

Medication vial sizes

  • GET/v1/medications now returns vialSize, the fulfilling pharmacy's vial volume for injectable products when supplied by its catalog.
  • vialSize is nullable because availability varies by pharmacy and product. Existing request and ordering behavior is unchanged.
  • The hosted OpenAPI endpoint reflects this change when the updated API is deployed.

2026-07-09

Per-pharmacy medication catalogs

  • GET/v1/pharmacies lists the distinct pharmacies your clinic can dispense from, each with a stable, opaque id and display name.
  • GET/v1/medications now accepts an optional pharmacyId query parameter — pass an id from GET/v1/pharmacies to retrieve just that pharmacy's formulary. Omit it for the clinic's full unified catalog, exactly as before.
  • A malformed pharmacyId returns 400; a well-formed id your clinic isn't entitled to returns an empty array. No existing response fields changed.
  • The hosted OpenAPI endpoint reflects these changes when the updated API is deployed.

2026-07-08

Register prescribers and users via the API

  • POST/v1/users creates or updates a user in your clinic and assigns clinic roles — register prescribers programmatically instead of the onboarding spreadsheet. The clinic comes from your API key, so no clinic reference is needed.
  • A prescriber must include an npi; once registered it can be referenced on orders by prescriberNpi. The call is idempotent per email — an existing email links to that user and merges roles.
  • GET/v1/users lists your clinic's users with roles and NPI, so you can check whether a prescriber is already registered before ordering.
  • GET/v1/clinic returns your clinic's own record — including its RxRelay clinic id and sandbox flag — for clinic-scoped keys.
  • Organizations gain GET/v1/clinics/{clinicRef}/users to list a clinic's users. On the org user endpoints, {clinicRef} is now the RxRelay clinic id (a UUID); the externalClinicId alias is no longer accepted there.
  • platform_admin can no longer be assigned through the API; assignable roles are prescriber, clinic_admin, staff, and owner.
  • The hosted OpenAPI endpoint reflects these changes when the updated API is deployed.

2026-07-08

Structured medication ingredients

  • GET/v1/medications now returns an ingredients array for each medication — the structured per-active composition (name, concentration, unit) when the fulfilling pharmacy provides it.
  • The array is empty when no structured data is available; strength stays the flat summary. For a multi-active blend, ingredients describes what a single strength value cannot.
  • ingredients is informational for display and selection — ordering is unchanged and still references a medication by id.
  • The hosted OpenAPI endpoint reflects these changes when the updated API is deployed.

2026-06-29

Generic order metadata

  • POST/v1/orders now accepts optional metadata: a generic key/value object for display and audit context.
  • Metadata is stored with the order, returned by order read/list APIs, shown on the RxRelay order detail page, and included in order webhooks.
  • Metadata is not used for auth, routing, billing, or fulfillment logic. Values must be string, number, boolean, or null; nested objects and arrays are rejected.
  • Limits are 20 keys, 64 characters per key, and 512 characters per value.
  • The hosted OpenAPI endpoint reflects these changes when the updated API is deployed.

2026-06-27

Expanded medication response

  • GET/v1/medications now returns strength, form, pharmacyName, and pharmacySku for each medication, in addition to id and name.
  • pharmacySku is the fulfilling pharmacy's own product identifier (the downstream SKU) for that medication — useful for reconciling RxRelay's catalog against a pharmacy's price list.
  • All four fields are populated when the fulfilling pharmacy provides them and are null otherwise.
  • The hosted OpenAPI endpoint reflects these changes when the updated API is deployed.

2026-06-27

Patient and order management endpoints

  • Added GET/v1/patients to list and search patients by name, email, phone, date of birth, or externalPatientId, with limit/offset pagination and a total count.
  • Added GET/v1/patients/{patientId} to fetch a single patient and its active addresses.
  • Added POST/v1/patients to create or resolve a patient outside of an order (by externalPatientId or email), with an optional default address.
  • Added PATCH/v1/patients/{patientId} to update patient demographics. Remapping externalPatientId to a patient already mapped elsewhere returns 409 Conflict.
  • Added GET/v1/orders to list and search orders by status, patient, externalOrderId, and date range, plus GET/v1/patients/{patientId}/orders for a single patient's orders. Both are paginated, newest first.
  • Added GET/v1/patients/{patientId}/addresses/{addressId}, DELETE on the same path to deactivate an address (promoting a new default if needed), and POST.../default to set an existing address as the default.
  • Reads work with any valid key; writes (POST/PATCH/DELETE) require a read_write key. Organization keys scope these via clinicId or externalClinicId.
  • The hosted OpenAPI endpoint reflects these changes when the updated API is deployed.

2026-06-23

Patient address IDs for partner orders

  • POST/v1/orders now accepts exactly one of shippingAddressId or shippingAddress. Existing shippingAddress behavior is preserved.
  • When a full shippingAddress exactly matches an existing patient address, RxRelay reuses that address instead of creating a duplicate.
  • Added GET/v1/patients/{patientId}/addresses and POST/v1/patients/{patientId}/addresses so partners can retrieve, upsert, store, and reuse RxRelay address IDs.
  • Patient address cards in the RxRelay app now show a copyable Address ID.
  • The hosted OpenAPI endpoint reflects these changes when the updated API is deployed.

2026-06-23

Webhook delivery decoupled from order submission

  • Outbound partner webhooks are now delivered asynchronously through the RxRelay worker instead of being attempted on the POST/v1/orders request path.
  • POST/v1/orders response bodies and webhook payloads are unchanged; partners should continue treating webhooks as asynchronous status events.
  • Webhook delivery remains single-attempt by default. Failed deliveries are recorded in the webhook event log and can be manually replayed from Settings / API.
  • The hosted OpenAPI endpoint continues to document POST/v1/orders as returning 201 Created.

2026-06-19

Organizations: order on behalf of clinics and provision via API

  • Added organization-scoped API keys. An organization owns many clinics and is issued one key instead of one key per clinic.
  • POST/v1/orders now accepts clinicId or externalClinicId. Organization keys must name the target clinic on each order; clinic-scoped keys are unchanged.
  • GET/v1/medications and GET/v1/prescribers accept a clinicId or externalClinicId query parameter to scope results for organization keys.
  • Added GET/v1/clinics to list the clinics under an organization.
  • Added POST/v1/clinics and POST/v1/clinics/{clinicRef}/users to provision clinics and their users — available to organization keys once RxRelay enables provisioning. Clinic creation is idempotent on externalClinicId.

2026-06-12

Required shipping address on orders

  • POST/v1/orders now requires a shippingAddress object (address1, address2, city, state, zip). Orders without a valid shipping address are rejected with 400.
  • The supplied address is saved as the patient's default address and sent to the fulfilling pharmacy.

2026-06-06

Developer platform foundation

  • Added clinic-scoped RxRelay API documentation under RxRelay Developers.
  • Added public OpenAPI endpoint at https://api.rxrelay.ai/openapi/v1.json.
  • Added request IDs, documented rate limits, idempotency behavior, and Problem Details errors.
  • Added webhook delivery event log with manual replay for failed deliveries.
  • Added order.tracking_updated webhook event for upstream tracking updates.