Skip to main content

States

To send an order, set state: SUBMITTED. Photon checks first, and if anything is missing it rejects the send with a change in changes:
  • every prescription on the order is signed
  • every prescription belongs to the order’s patient
  • the patient has a phone number that can receive texts

Example

If the patient has several draft orders and you didn’t send an id, you get AmbiguousOrderMatch. Each candidate carries its prescriptions and pharmacy, so you can show the prescriber what’s on each. Resend with the id of the one you mean.

Screening

An order screens its prescriptions together. screeningAlerts on the order includes the interactions between them, which each prescription’s own screening doesn’t cover. When you add or remove prescriptions and two of them interact, every add and remove change comes back APPLIED with ADVISORY severity and a short reason. The details are in screeningAlerts. Interactions never block the order.

Fields

Pharmacies

You don’t need to choose a pharmacy. With none set, the patient chooses one from the link Photon texts them. To choose for them, send pharmacy: { pharmacy: … } with a PharmacyReferenceInput: The fields combine to narrow the results. Only an id sets the pharmacy directly. Any other search comes back as an AMBIGUOUS change for you to pick from, even with one match (CONFIRMATION_REQUIRED). Several matches come back with up to 20 options. Each option’s entity is the Pharmacy, with pricing offers where available. Resend with the chosen pharmacy’s id. To unassign a pharmacy, send pharmacy: { none: true }.

Listing pharmacies for an order

To show pharmacies before you choose one, read the order through the orders query and select availablePharmacies. It returns the same choices as an ambiguous pharmacy, a page at a time, each priced against the order’s prescriptions, including discount-card prices:
pharmacy takes the same reference as the order mutation. Leave it out for the sponsored pharmacies that have offers for this order. Unless you search by id, the first page also includes sponsored pharmacies the search didn’t match, which don’t count toward limit. page.limit defaults to 20 and is capped at 100. nextOffset is null on the last page. availablePharmacies is null in the order mutation’s response. Only orders fills it in. Each Pharmacy also has its phone, logo, weekly hours and, relative to a time you pass or now, isOpen and nextEvents.

Moving a sent order

To move a SUBMITTED order to a different pharmacy, send the new pharmacy with a reason:
reason.type is one of CLOSER_LOCATION, PHARMACY_CLOSED, OUT_OF_STOCK, FILL_TIME_TOO_SLOW, INSURANCE_NOT_ACCEPTED, PRICE_TOO_HIGH, WRONG_PHARMACY_SELECTED or OTHER. OTHER needs a note. A reason is accepted only on a SUBMITTED order that already has a pharmacy, and only with pharmacy.

Fulfillment

Once an order is sent to a pharmacy, fulfillment.state says how far the pharmacy has gotten. fulfillment is null until then, so it’s always null on a draft. state is null until the pharmacy reports one. Pick-up orders move through READY to PICKED_UP. Mail orders move through FILLING and SHIPPED to DELIVERED. To hear about each step as it happens, use webhooks.

Exceptions

Once an order is sent, exceptions lists problems that need attention, such as PHARMACY_UNREACHABLE, PHARMACY_NEEDS_INSURANCE_INFO or DOCTOR_NOT_LICENSED_IN_STATE. A draft never has exceptions. See Reference for every type.
Last modified on October 29, 2026