Skip to main content

Sandbox

The sandbox lets you build and test the entire integration without touching production data. It is not a separate host: you send requests to the same base URL with a vr_test_ key.

What a test key does

  • Nothing real is created. No patients, no intakes, no orders are written to production tables.
  • No card is ever charged. Payment is simulated.
  • Validation is identical to live. Same required fields, same request and response shapes, same error codes, same idempotency behavior.
  • Responses are synthetic. Objects come back with sandbox identifiers and a "sandbox": true marker.

Synthetic identifiers

In live traffic these ids are UUIDs. Sandbox ids are the only non-UUID identifiers the API returns.
When referencing a sandbox patient from an intake or order, pass either the external_patient_id you supplied or the returned sandbox_pat_… id. Both resolve.

Simulated lifecycle

Sandbox objects advance on a timer, a few seconds apart, and each transition enqueues the same webhook event your live integration will receive — marked sandbox: true in the payload.
Webhooks only arrive if the clinic has a webhook endpoint configured and subscribed to those events. Endpoints are configured by a VitaRelay admin in the dashboard, not through the API. See Webhooks Overview.

Run the full loop in sandbox

1

Get a test key

Ask your VitaRelay representative for a vr_test_ key with patients:write, intakes:write, and orders:write. See API Keys.
2

Create a patient

Returns 201 with data.id = sandbox_pat_… and data.sandbox = true.
3

Submit an intake

A few seconds later, an intake.reviewed event is delivered to your configured endpoint.
4

Place an order

Returns 201 with data.id = sandbox_ord_…. No charge is attempted.
5

Watch the order events arrive

Your endpoint receives order.paid, then order.shipped, then order.delivered, each signed exactly like a live event and each carrying sandbox: true.

Idempotency in sandbox

Idempotency works the same way as in live. Replaying a request with the same external_patient_id, external_intake_id, or external_order_id and the same body returns the original sandbox object with 200 instead of 201. Reusing an external id with a different body returns 409 duplicate_request.

Errors in sandbox

Error codes and statuses are identical to live — including validation_failed, product_not_found, insufficient_scope, and rate_limited. See Errors.
Sandbox and live never intersect. A vr_test_ key cannot read or modify production records, and objects created in the sandbox are invisible to vr_live_ keys.