> ## Documentation Index
> Fetch the complete documentation index at: https://photonhealth.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Environments

> Neutron is the sandbox and Photon is production. Build against Neutron.

Photon has two environments. They run the same API but keep separate data, accounts and credentials.

<CardGroup cols={2}>
  <Card>
    <img noZoom src="https://photonhealth.com/logo/neutron-logo.svg" alt="Neutron" className="env-mark env-mark-light" />

    <img noZoom src="https://photonhealth.com/logo/neutron-logo-light.svg" alt="Neutron" className="env-mark env-mark-dark" />

    <p className="font-semibold text-base text-gray-800 dark:text-white" style={{ margin: "0 0 4px" }}>Neutron</p>
    The sandbox, at `*.neutron.health`. Build and test here.
  </Card>

  <Card>
    <img noZoom src="https://photonhealth.com/logo/photon-logo.svg" alt="Photon" className="env-mark env-mark-light" />

    <img noZoom src="https://photonhealth.com/logo/photon-logo-light.svg" alt="Photon" className="env-mark env-mark-dark" />

    <p className="font-semibold text-base text-gray-800 dark:text-white" style={{ margin: "0 0 4px" }}>Photon</p>
    Production, at `*.photon.health`. Real patients and pharmacies.
  </Card>
</CardGroup>

| | **Neutron** (sandbox) | **Photon** (production) |
| - | - | - |
| Use it for | Building and testing | Real patients and real prescriptions |
| Prescriptions | Never sent to a real pharmacy | Sent to pharmacies |
| Patients | Fake ones only | Real |
| API credentials | Free with every sandbox account | [Launch and above](/docs/use-cases#plans-at-a-glance) |
| Prescribe app | [rx.neutron.health](https://rx.neutron.health) | [rx.new](https://rx.new) (private preview) |
| [Dashboard](/docs/admin) | [app.neutron.health/settings](https://app.neutron.health/settings) | [app.photon.health/settings](https://app.photon.health/settings) |

<Tip>
  Build everything against Neutron. Every link and example in these docs points there unless it says otherwise.
</Tip>

## URLs

Every URL follows from the environment's name, so switching environments means changing one word. The one exception is the Prescribe app, which is `rx.new` in production.

The production Prescribe app and production MCP are in private preview. To get access, ask your Photon contact.

| Service | Neutron | Photon |
| - | - | - |
| GraphQL | `https://network.neutron.health/graphql` | `https://network.photon.health/graphql` ⚠️ |
| [MCP](/docs/network/mcp) | `https://ai.neutron.health` | `https://ai.photon.health` (private preview) |
| Prescribe app | `https://rx.neutron.health` | `https://rx.new` (private preview) |
| Sign-in (Auth0) | `auth.neutron.health` | `auth.photon.health` |
| Token audience | `https://api.neutron.health` | `https://api.photon.health` |

<Warning>
  ⚠️ **Not live yet.** `network.photon.health/graphql` returns a 403 for POST requests. MCP will move to `network.<env>.health/mcp`, which isn't live yet.
</Warning>

## What's different in Neutron

Neutron runs the same API, schema, permissions and workflow rules as production, so code that works in Neutron works in Photon. What differs is everything that touches the real world:

| | Neutron | Photon |
| - | - | - |
| Patient texts | **Sent**, to the phone number on the patient. Use a number you control. | Sent |
| Pharmacies | Nothing is transmitted. Orders stay `SUBMITTED` and are never placed or filled. | Sent to the chosen pharmacy, then filled |
| Webhooks | No `order:placed`, `order:fulfillment` or `order:completed`, because orders never reach a pharmacy | Every event |
| Prices | Real when a pharmacy returns one, but many options have none | Real |
| Screening | The same as production | |
| MCP `rx_send` | Creates test orders only | Sends real orders |
| Patients | Use fake patients only | Real patients |
| Accounts, teams, catalog, templates | Separate. Nothing carries over. | Separate |
| Credentials and webhook subscriptions | Separate. Set them up again for production. | Separate |

Rehearse everything up to the send in Neutron: sign-in, drafting, screening, signing, sending, the patient's text, and handling `changes` and errors. You can't rehearse fulfillment there yet. Build your webhook handlers from the [example events](/docs/network/webhooks/events), then confirm them with a small production pilot.

## Which host and credential

For each job, call this host with this credential. In production, change `neutron` to `photon`, and use `rx.new` for the Prescribe app.

| Job | Host | Credential | Plan |
| - | - | - | - |
| Prescribe | `rx.neutron.health` | The prescriber's sign-in | Indie |
| Open the app on a patient or order ([deep link](/docs/prescribe/app/deep-links)) | `rx.neutron.health/order/…` | The prescriber's sign-in | Indie |
| Draft in Claude or ChatGPT ([MCP](/docs/network/mcp/connect)) | `ai.neutron.health` | The prescriber's sign-in, over OAuth | Indie |
| Manage credentials, team, catalog and templates ([dashboard](/docs/admin)) | `app.neutron.health/settings` | An Administrator's or Developer's sign-in | Indie |
| Embed with the [iframe](/docs/prescribe/embed/iframe) | `rx.neutron.health/order/embed` | The prescriber's sign-in, with your Application `client_id` in a URL built by `frame()` | Launch |
| Embed with [React](/docs/prescribe/embed/react) or the [JavaScript client](/docs/prescribe/embed/javascript) | `environment="neutron"` | Application `client_id` | Launch |
| Get a [machine token](/docs/authentication#machine-tokens) | `auth.neutron.health/oauth/token` | Backend `client_id` and `client_secret` | Launch |
| Sync patients, draft prescriptions and orders ([GraphQL](/docs/network/graphql)) | `network.neutron.health/graphql` | Machine token | Launch |
| Send a signed order from your backend | `network.neutron.health/graphql` | Machine token. A prescriber must have signed every prescription. | Launch |
| Draft from another MCP client, such as a scribe, for a prescriber | `ai.neutron.health` | The prescriber's sign-in, from a client allowlisted on your Application credential | Launch |
| Draft from your own agent ([MCP](/docs/integrations/agent-drafted-orders)) | `ai.neutron.health` | Machine token. It can't sign. | Launch |
| Receive order updates ([webhooks](/docs/network/webhooks)) | Your own HTTPS endpoint | The shared secret you set | Launch |

The plan is the smallest one that includes the job. In the sandbox, every account can do all of them. See [Use cases](/docs/use-cases#plans-at-a-glance).

## In code

Prescribe and the JavaScript client take the environment's name:

<CodeGroup>
  ```tsx React theme={"dark"}
  <PhotonProvider clientId="YOUR_CLIENT_ID" environment="neutron">
  ```

  ```ts JavaScript theme={"dark"}
  const ph = photon({ environment: "neutron", auth: { clientId: "YOUR_CLIENT_ID" } });
  ```
</CodeGroup>

<Warning>
  `PhotonProvider` defaults to production (`photon`). Set `environment="neutron"` while you build.
</Warning>

For GraphQL or MCP, use the URLs above.

## Going live

1. Choose a plan. API credentials need [Launch or above](/docs/use-cases#plans-at-a-glance). [Start a production account](https://photonhealth.com/pricing), or email [sales@photon.health](mailto:sales@photon.health) to talk through your use case. The production Prescribe app and MCP are in private preview, so ask your Photon contact for access.
2. Get production credentials from [app.photon.health](https://app.photon.health/settings/developers). Sandbox credentials don't work in production.
3. Invite your prescribers to the production organization, with their NPI, phone, fax and address. Nothing carries over from Neutron. See [Team](/docs/admin/team).
4. Change the environment from `neutron` to `photon`: the `environment` prop, or the hostnames for GraphQL and MCP.
5. Add your production domain to your Application credential's allowed URLs. Using the iframe? Add `https://rx.new` too.
6. Set up your [webhooks](/docs/network/webhooks) in production too.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.