Partner Integration Guide

How your technology stack connects to Beluga's nationwide physician network. You own the patient experience end to end; Beluga handles clinical review, prescribing, and compliance behind a simple API. This guide walks through exactly what you build, what you send, and what you receive at each step.

AuthorizationAuthorization: Bearer {API_KEY} on every request
Stagingapi-staging.belugahealth.com
Productionapi.belugahealth.com
ProtocolHTTPS only. Endpoint paths and keys are shared in onboarding.

What this takes: this is an API integration, built by your developers. Plan for engineering resources on your side to build the intake, submit visits, and receive webhooks. If you don't have a dev team in-house, tell your onboarding contact up front — we'll help you scope the build (and Beluga can host the patient questionnaire as an add-on).

How onboarding works

  1. 1
    Kick off in Slack. Your shared channel with Beluga's onboarding team runs the whole process, from credentials to go-live.
  2. 2
    Build intake, submit a test visit. Implement Steps 1 and 2 below against staging and send a test payload.
  3. 3
    Beluga verifies your integration. We confirm the payload, questionnaire wiring, and webhooks, then enable production.
  4. 4
    Add-ons switch on in sequence. Sync video, pharmacy fulfillment, labs, and AutoRx are enabled as your program needs them.
Implement the steps in order; each capability is confirmed before the next is switched on. That sequencing is what keeps the integration fast and drop-free.

Onboarding phases

1
Admin & Kickoff Admin Ball: You

Meet your onboarding team (contracts, integration, forms & config), review the Partner Onboarding Guide, complete the Integration Form, receive the questionnaire documents, and book your kickoff call.

2
Technical Setup Technical Ball: Beluga

Receive your API & webhook docs, API credentials and environment details for both staging and production, and dashboard access. Integrate Beluga's patient consent and privacy policy into your intake, and review the available visit types.

3
Test Visit Technical Ball: You

Send a staging test visit from your fully built system (not Postman) using the sample visit type and MedID, including a photo to the receivePhotos endpoint. Share the masterId for review.

4
Webhook Setup Technical Ball: Both

Share your webhook endpoint URLs, authentication details, and success/error responses. Beluga configures delivery and confirms each event type before moving on.

5
Sync (Video visits) Add-on Ball: Both

Enable live video: pass the scheduleLink to patients, then test BOOKING_CREATED / RESCHEDULED / CANCELLED (and NO_SHOW) in a sync-enabled state.

6
Pharmacy Add-on Ball: Both

Turn on pharmacy fulfillment and test the order and tracking webhooks with a staging visit. (Refill triggering is enabled here too, where applicable.)

7
Labs Add-on Ball: Both

Enable lab orders for both in-person and at-home methods, and test the lab status webhooks with two staging visits.

8
Intake (Visit-type config) Clinical Ball: Beluga

Beluga builds the clinical questionnaires as the source of truth for your Q&A branching logic — used exactly as provided. The questionnaire documents are shared at kickoff, so this work runs in parallel from day one; this phase locks the final configuration before launch. Prefer not to build the intake UI yourself? Beluga can host the questionnaire as an add-on.

9
Go Live: your first patient Launch Ball: Both

Your visit type goes live in production with your production API key. The milestone that matters: your first patient — a real visit through your own flow. From there your account manager and CS manager take over from onboarding and work with you on growing volume, adding programs, and switching on new capabilities.

This is the end-to-end onboarding sequence. Add-on phases (Sync, Pharmacy, Labs) are switched on only if your program uses them. "Ball" shows whose court each phase starts in — if you're waiting, check it's not yours. The section below details the data interface behind each patient visit.

Your integration journey

1

Build your patient intake

Runs entirely in your product. Identical architecture for every vertical you launch with us.
Core

In plain terms: build the questions and consent screen your patients fill out inside your product.

You build

  • A questionnaire flow with a consent checkbox linking to Beluga's telemedicine consent and privacy practices. The checkbox gates your Next button; you will send consentsSigned: true.
  • Branching logic that ends in the patient's medication choice(s). Each becomes a patientPreference. Your Beluga customer dashboard is the source of truth for medIds: pull your program's catalog from there rather than hardcoding.
  • Demographics: first and last name, date of birth, phone, email, address, city, state, zip, and sex.
  • Dedicated inputs for current medications, allergies, and conditions. These map to dedicated structured fields in the visit payload, never to custom Q&A.
  • Every other question captured as Q1/A1 ... Qn/An. Embed multiple-choice options in the question text ("... POSSIBLE ANSWERS: a; b; c") and join multi-answers with semicolons.

Choose your identity path (per program)

  • You verify IDs: include patientVerified: true and a verificationId with each visit.
  • Patient uploads a photo ID (standard flow): collect a photo ID during intake and upload it in Step 3; our physicians review it.
  • Beluga verifies from demographics: Beluga's ID verification service checks identity from the patient's demographics. When it clears, no photo ID is needed; if it can't confirm, fall back to the photo ID flow above.
Nothing hits Beluga's API in this step. The payload structure below is identical across programs, so you build this once. Prefer not to build intake at all? Beluga can host the questionnaire for you as an add-on — ask your onboarding team.
2

Submit the visit

One POST creates the visit and queues it for a physician licensed in the patient's state.
Core

In plain terms: send the completed intake to Beluga; a licensed physician in the patient's state picks it up from there.

You send

  • formObj: consentsSigned + demographics + patientPreference[] + the structured meds / allergies / conditions fields + your Q&A pairs.
  • Root metadata: masterId (a unique ID you generate per visit), pharmacyId, company, visitType, plus patientVerified and verificationId if you verify identity.
  • Rule: never send empty, null, or undefined fields.

Submitting lab results? A dedicated endpoint

  • For programs where you run the testing (test-to-treat and similar), visit creation goes through a separate lab-results endpoint so structured results ride along with the visit and the physician can review and treat in one pass.
  • Lab submissions add a test-to-treat indicator plus your structured results; the exact payload shape is defined in the shared API docs.
  • Have the report as a document instead? Create the visit through the regular visit endpoint (not the lab-results endpoint) and attach the report as a PDF using the upload in Step 3.

You receive

  • A success body confirming the visit was created. Persist your masterId: every later call, response, and webhook joins through it. (Returned fields vary by endpoint and are listed in the shared API docs.)
  • In states that require a live video visit, the response includes a scheduleLink for booking — surface it as described in Step 4.
  • Specific error responses are detailed in the shared API docs.
How to read responses: any request that reaches Beluga's system returns HTTP 200. The actual outcome lives in the response body (status, error, info fields), so parse the body rather than relying on the HTTP code. An HTTP 400 with an empty body means an authorization problem only: check your Bearer key and environment.
3

Upload photos & PDFs

Photo IDs when Beluga can't verify identity from demographics, plus any supporting images or documents.
If applicable

In plain terms: send us any photos or documents the visit needs — an ID, a progress photo, a lab report.

You send

  • Images: accepted formats are JPEG, PNG, GIF, BMP, TIFF, WebP, HEIC, and HEIF. Compress to 1000px wide (or under 3MB), base64-encode without the MIME prefix, and set each item's mime to match the format: POST {visitId, images: [{mime, data}]}.
  • PDFs: POST {visitId, image: {mime: "application/pdf", data}}, one per request. Also the route for lab reports you hold as documents.
  • Either the visitId or the masterId from the visit response works as the key.

You receive

  • Success body: "Successfully received images / image".
  • Body errors: "Visit does not exist" (unknown ID) or "Error accepting image(s)".
  • Same rule as Step 2: HTTP 200 means the request reached us; the body carries the result. HTTP 400 with no body is an authorization issue.
A photo ID isn't always required. When Beluga's demographics-based ID verification service clears the patient, you can skip the ID upload — send one only when Beluga requests manual verification. Supporting images and PDFs (e.g. lab reports) still use these endpoints whenever you have them.
4

Video visit booking

Most states allow chat-based care. Where live video is required, the visit response includes a booking link.
Add-on

In plain terms: in some states the patient books a live video call with the physician instead of chat-only care.

You build

  • The scheduleLink comes from the visit response: submit the visit (Step 2) first, and in live-video states the response includes the link.
  • Surface the full scheduleLink, query parameters included: they identify the visit.
  • The same scheduleLink is used to both schedule and reschedule the live video consultation within that visit.
  • An iframe keeps the flow seamless.
  • Keep the link reachable for the life of the visit; patients may exit and return later.

Webhooks you receive

  • BOOKING_CREATED with docName, scheduledDate (ISO 8601), location — here location is the live video consultation URL.
  • BOOKING_RESCHEDULED (same fields), BOOKING_CANCELLED, NO_SHOW.
5

Chat & support messaging

The physician reviews the intake and may ask clarifying questions before deciding.
Core

In plain terms: the physician can message your patient with questions, and the patient replies through you.

You send

  • Patient replies: POST {firstName, lastName, content, isMedia, masterId}. For images, send base64 as content with isMedia: true.
  • Your CS team to Beluga admin: POST {content, masterId}.

Webhooks you receive

  • DOCTOR_CHAT with content: display it to the patient in your chat UI — or deliver it by SMS if you don't have a chat UI.
  • CS_MESSAGE with content: route it to your support team.
6

The clinical outcome

The physician prescribes or refers, writes the note, messages the patient, and resolves the visit.
Core

In plain terms: the physician decides — prescription or referral — and you're notified the moment it happens.

You send

  • Optional: cancel a visit from your side before the physician resolves it — POST {masterId}. Returns canceled, or resolved if the physician already acted.

Webhooks you receive

  • RX_WRITTEN: the prescription has been written. Payload details are in your webhook docs.
  • CONSULT_CONCLUDED: fires on resolution with visitOutcome: "prescribed" | "referred". This is your signal the visit is complete.
  • CONSULT_CANCELED: the patient canceled the consultation before a physician engaged.
7

Fulfillment tracking

Order and shipping events stream to your webhook endpoint so you can power status pages and notifications.
Add-on

In plain terms: track the prescription or lab kit from order to the patient's door, event by event.

Pharmacy orders (Beluga pharmacy partners)

  • Order status: PHARMACY_ORDER_IN_FULFILLMENTPHARMACY_ORDER_SHIPPED (with carrier, tracking) → PHARMACY_ORDER_DELIVERED.
  • Package tracking: PACKAGE_IN_TRANSIT, PACKAGE_OUT_FOR_DELIVERY, PACKAGE_DELIVERED, PACKAGE_DELIVERY_FAILED with trackerStatus, trackerId, trackingUrl, tracking, carrier, deliveredDate.
  • Depending on the pharmacy, you may receive all or only some of these webhooks. Any event we receive from the pharmacy is always forwarded through one of these standard webhooks.
  • orderId + masterId tie every event back to the visit.

Lab orders

  • At-home kits: LAB_ORDER_SHIPPED_TO_PATIENT (with carrier, tracking) → LAB_ORDER_DELIVERED_TO_PATIENTLAB_ORDER_SHIPPED_TO_LABLAB_ORDER_RECEIVED_BY_LAB.
  • In-person draws: LAB_ORDER_REQUISITION_CREATED delivers the requisition as a base64 PDF (labReqPdf) for the patient to bring to the draw site.
  • Both paths finish with LAB_ORDER_RESULTS (with bookingLink). Results also populate labResults[] on the GET visit endpoint. Running your own testing instead? Submit results through the lab-results endpoint in Step 2.
External pharmacies (manufacturer-direct and similar) end at RX_WRITTEN: no downstream tracking events are available for those orders.
8

Ongoing operations

Read, update, and automate after launch. All synchronous request / response.
Ongoing

In plain terms: everything you can look up, update, or automate after a visit is underway.

Read any time

  • GET /visit/externalFetch/{masterId}: visitStatus, resolvedStatus + timestamps, labResults[], the full formObj + intakeResults, rxHistory[], and AutoRx fields (currentDose, nextDose, checkinResult).
  • GET /patient/externalFetch/{phone}: demographics plus every masterId on file for the patient.
  • Pharmacy search: POST {name, city, state, zip} returns the first 100 matches.

Manage

  • Update visit / resend rx: VISIT_DATA_UPDATED before the physician resolves, NEW_RX_SENT after. Window is 20 days from the original rx; retries are capped.
  • Patient name update: allowed until the name and photo ID are approved.

AutoRx program (weight-loss)

  • Titration rx with exactly one preference returns NEW_RX_SENT. Windows: 15-60 days after a 1-month rx, 60-120 after a 3-month rx (staging compresses to 1 minute-4 days for testing).
  • weightlossCheckin visit carries titration (Increase / Decrease / Stay the same), BMI (must exceed 20), and titrationLevel 1-3 for 3-month authorizations.
  • A check-in is required once a visit is resolved more than 90 days (taken 60+ days after resolution); 180 days is a hard stop, then a new visit is needed. A "Yes" on safety questions returns success plus "Patient needs to submit a followup visit".
  • Refill trigger (Beluga pharmacy): POST {medId, masterId} returns NEW_RX_SENT + orderId; 14-day spacing; must match the original rx exactly.

Reference

  • masterId: generated by you, unique per visit. The join key on every later API call, response, and webhook. Store it at creation and the whole lifecycle links up.
  • visitId: returned when Beluga verifies identity. Preferred key for image/PDF uploads (masterId is also accepted there).
  • phone: 10 digits, unique per patient. Lookup key for patient data and cross-visit history.
  • company + visitType: route each submission to the right program configuration and clinical protocol.
  • pharmacyId: sent in the request metadata; routes the visit to the correct pharmacy so fulfillment lands in the right place.
  • medId: identifies each medication option; your Beluga customer dashboard is the source of truth for your program's medIds.
  • orderId: appears on pharmacy and lab events so fulfillment status ties back to the visit.
  • active: in the physician queue awaiting review.
  • pending: waiting on something before review, such as ID photos or a video booking.
  • admin: with Beluga's admin/support team.
  • holding: temporarily parked outside the active queue.
  • resolved: physician concluded the visit (prescribed or referred). resolvedStatus moves open → closed, with resolvedTimestamp once closed.
  • canceled: ended before clinical resolution.
  • Read the body, not the HTTP code: any request that reaches Beluga returns HTTP 200, with the outcome in the response body (status, error, info). An HTTP 400 with an empty body signals an authorization problem only: check your Bearer key and environment.
  • Everything else lives in the docs: specific error responses, rx-update and AutoRx status codes, and per-company webhook payloads are documented in your shared API and webhook docs — those are the single source of truth.
Questions during the build? Post in your shared Slack channel and Beluga's onboarding team will guide you step by step. This guide describes the data interface only: clinical review, prescribing, and the physician EMR are handled entirely inside Beluga. Payloads reflect Beluga's skeleton API, webhook, and GET documentation shared in your channel.