Skip to main content
The Customers API lets a CRM such as GoHighLevel work with the providers your pharmacy serves, without opening the app.

Send a converted provider

POST /customers creates the provider (and its portal invite) and returns the VitaRelay id to store in your CRM.

Get events

Webhooks for order shipped, delivered and cancelled, customer reorder due and lapsed, and partner dormant.

Export your providers

GET /customers returns every provider with its last order and where it is in its order cycle.

Authentication

Create a key under Settings → API keys with customers:read and/or customers:write. Send it as Authorization: Bearer vr_live_.... A key belongs to your pharmacy, and your pharmacy must have customers enabled.
  • Test keys (vr_test_...) can read. Their writes are acknowledged with "sandbox": true and change nothing, so you can wire up your CRM safely first.
  • Keys are rate limited per key; 429 rate_limited includes a Retry-After header.

1. CRM to VitaRelay: a provider converted

The response (201 created, 200 updated) carries data.id, the VitaRelay id to store in your CRM, and the provider’s signup state.

2. VitaRelay to CRM: webhooks

The signing secret is returned once. Verify each request with the X-Webhook-Signature header (sha256= plus the hex HMAC-SHA256 of the exact body, keyed with the secret), and deduplicate on X-Webhook-Delivery. Order events carry the order and a customer object (id, external_id, name, email), so you can find the contact in your CRM. Lifecycle events carry the customer (or partner), the last order and the days since it. Each lifecycle event fires once per last order; a new order restarts the clock. The windows default to 30, 60 and 90 days since the last order. Change them with PUT /customers/settings (reorder_due_days, lapsed_days, dormant_days). Customers already past a window when you connect do not fire events; read their lifecycle_status from GET /customers.

Test it

Send yourself an event with POST /customers/webhooks/ping and {"id": "<endpoint id>"}: a ping arrives at your URL, signed like the real ones.

3. Export your providers

GET /customers lists them (filter with external_id or email; page with limit and cursor). GET /customers/{id} returns one.

Errors