API Integration Guide
A step-by-step walkthrough for connecting to Honeybee's Partner API — from your first prescription to live order tracking.
This guide covers the API Driven (Partner Requested Fills) workflow — the recommended path for partners who want full control over when prescriptions are filled, the ability to reuse a single Rx across multiple refill orders, and flexible shipping and add-on item configuration.
If you're looking for the fastest possible integration with minimal setup, see Automatic Processing — but read this first so you understand the tradeoff.
How it works
Before diving in, here's the full picture. The API-driven workflow decouples prescription receipt from order creation — you get notified when a prescription arrives, and you decide when (and whether) to fill it.
| Step | What happens | Who acts |
|---|---|---|
| Rx received | Prescriber sends e-Rx via your ePrescribing tool | Prescriber |
| Webhook fires | Honeybee sends RX_RECEIVED to your endpoint | Honeybee → You |
| Match patient | Use the patient_id to look up in your system | You |
| Place order | POST /orders when you're ready — after payment, eligibility, etc. | You → Honeybee |
| Fill & ship | Honeybee handles dispensing, packaging, and carrier handoff | Honeybee |
| Updates via webhooks | Order status, shipment tracking, and exceptions flow back to you | Honeybee → You |
:::tip Why API-driven? You're in full control of the trigger. Nothing ships until you say so — collect payment, verify the patient, or run any internal checks first. One prescription can also be referenced across multiple refill orders, whereas Automatic Processing requires a new e-Rx every single time. :::
Before you start
◆ Operations setup
Before you go live, make sure the following are in place:
- Webhook URL configured — a URL where Honeybee can
POSTevents to your systems. Managed in the Developers section of the Partner Dashboard under API & Webhook Settings. - Orders Dashboard access — for monitoring order status without API calls. Available at partners.honeybeehealth.com/orders.
- ePrescribing tool configured — your ePrescribing software should be routing Rx to Honeybee Health.
- Custom item & add-on UI — if you plan to include branded inserts, custom packaging, or promotional items with orders, coordinate with your Honeybee partner rep to get this configured.
◇ Engineering setup
- OAuth 2.0 credentials — obtain your client ID and secret. See Authentication & Authorization.
- API base URL —
https://partners.honeybeehealth.com - Webhook receiver — a publicly accessible HTTPS endpoint that can accept
POSTrequests from Honeybee. - Signature verification — validate every inbound event using the
X-Honeybee-Signatureheader. See Event Signature Validation.
:::info IP allowlisting If your infrastructure restricts inbound traffic, allowlist the following NAT Gateway IPs — these are the addresses webhook events will originate from:
44.229.36.28 · 44.231.152.93 · 44.231.144.152
Note these addresses may change. Check back here for updates. :::
Step 1 — Receive the prescription
When a clinician sends a prescription electronically, Honeybee receives and intakes it — but does not create an order automatically. Instead, Honeybee fires an RX_RECEIVED webhook to your configured endpoint.
◆ What this means for your team
Your team gets notified the moment a prescription arrives. This is your window to complete pre-fill steps before triggering the order:
- Confirm the patient is in your system
- Verify payment is on file
- Check eligibility or coverage
- Run any internal approval logic
Nothing ships until you explicitly trigger it in Step 3.
◇ What arrives on your endpoint
The webhook payload contains a patient_id and prescription details. Note that no PHI is included — patient data is retrieved separately in Step 2.
{
"event_id": "a7a26ff2-e851-45b6-9634-d595f45458b7",
"patient_id": "ay87nt",
"event_type": "RX_RECEIVED",
"medication_requests": [
{
"id": 183601,
"prescription_id": 183601,
"active": true,
"prescriber_name": "Jane Smith",
"receive_date": "2024-03-14T13:17:54.906-07:00",
"drug_name": "ESTRADIOL 1MG TABLET",
"ndc": "67877032105",
"sig_text": "Take 1 tablet by mouth daily.",
"written_qty": 90,
"refills_left": 11,
"expire_date": "2025-03-13T17:00:00.000-07:00",
"drug_schedule": "0"
}
]
}
:::tip Best practice: include email in your ePrescriptions Honeybee uses email as a primary patient identifier. Including it in the ePrescription makes matching significantly faster and more reliable. On the NCPDP standard, this field is:
NewRx.Patient.HumanPatient.CommunicationNumbers.ElectronicMail
If your ePrescribing tool doesn't support this field, you can include the email in the Notes to Pharmacy or Address Line 2 fields — Honeybee will parse it automatically.
:::
Step 2 — Match the patient
Webhook events don't contain PHI. To identify which of your patients the prescription belongs to, use the patient_id from the RX_RECEIVED event.
Method 1 — Preferred: EHR patient ID
Include your EHR's patient ID in the ePrescription's patient segment. Honeybee will return it in every subsequent webhook, making matching instant and exact.
Field location: NewRx.Patient.HumanPatient.Identification.MedicalRecordIdentificationNumberEHR
Many ePrescribing tools (including DoseSpot) do not support this field. If that's the case, use Method 2.
Method 2 — Fallback: patient endpoint
Call GET /patients/{patient_id} with the ID from the webhook to retrieve the patient's data, then match on one or more fields in your system.
Request:
GET /v1/patients/ay87nt
Authorization: Bearer {your_access_token}
Response:
{
"patient_id": "ay87nt",
"first_name": "Honee",
"last_name": "Bea",
"dob": "1990-06-14",
"gender": "F",
"email": "honee.bea@example.com",
"phone": "310-555-0192",
"patient_safety": {
"health_conditions": [],
"medications": [],
"allergies": []
}
}
Matching priority:
| Match field | Reliability | Notes |
|---|---|---|
email | ✅ Highest | Use alone if available |
first_name + last_name + dob | ⚠️ Medium | May match multiple patients in large populations |
first_name + last_name only | ❌ Low | Not recommended |
See Matching Event Data to Patients for the full guide.
Step 3 — Place the order
Once you've matched the patient and completed any pre-fill steps, trigger the fill by calling POST /orders. This is when Honeybee creates the order and begins the dispensing process.
◆ What you control
| You decide | Honeybee handles |
|---|---|
| ⚡ When to trigger the fill | 💊 Clinical dispensing & verification |
| 🚚 Shipping speed & carrier method | 🏷️ Labeling & packaging |
| 📦 Custom add-on items per order | 📬 Carrier coordination & handoff |
| ♻️ Whether to use refills from an existing Rx | 📡 Ongoing status webhooks |
◇ Request
POST /v1/orders
Authorization: Bearer {your_access_token}
Content-Type: application/json
{
"patient": {
"patient_id": "ay87nt",
"patient_safety": {
"medications": [],
"health_conditions": [],
"allergies": []
}
},
"items": [{ "prescription_id": 183601 }],
"shipping": {
"method_id": 1
},
"address": {
"first_name": "Honee",
"last_name": "Bea",
"phone": "3105550192",
"street1": "123 Main St",
"city": "Austin",
"state": "TX",
"zip": "78701"
}
}
:::caution Field shapes matter
The order body requires three top-level objects: patient, items, and shipping (address is also top-level). Note shipping.method_id is an integer, not a method name string — fetch valid IDs from GET /shipping_methods. Prescriptions go in the items array as { "prescription_id": ... }; add-on items use a sku entry in the same array (see Over-the-Counter Items and Quantities and Package Sizes).
:::
See the Create New Order reference for the full request and response shape, including new-patient creation, identity documents for controlled substances, and the complete 422 error-code table.
Step 4 — Refill management
One of the most important advantages of the API-driven workflow is how it handles refills. Understanding this distinction will affect how you architect your integration.
◇ API-driven: reusable prescriptions
With the API-driven workflow, a single prescription can power multiple order calls. As long as refills_left > 0 and the prescription hasn't expired, you can reference the same prescription_id to create a new fill.
// Refill order — same prescription_id, new POST /orders call
{
"patient": {
"patient_id": "ay87nt",
"patient_safety": {
"medications": [],
"health_conditions": [],
"allergies": []
}
},
"items": [{ "prescription_id": 183601 }],
"shipping": {
"method_id": 1
},
"address": {
"first_name": "Honee",
"last_name": "Bea",
"phone": "3105550192",
"street1": "123 Main St",
"city": "Austin",
"state": "TX",
"zip": "78701"
}
}
You can track remaining refills in the refills_left field returned in RX_RECEIVED and RX_UPDATED events. Build refill reminders, automated triggers, or patient-facing prompts around this field.
◆ Automatic processing: Rx-per-order model
With Automatic Processing, each order requires a new e-Prescription from the prescriber. There is no way to trigger a refill programmatically — the only options are:
- The prescriber sends a new e-Rx, which Honeybee automatically converts into an order
- Your team manually places a refill order through the Orders Dashboard
:::info Refill management summary
| API-Driven | Automatic Processing | |
|---|---|---|
| Trigger refill programmatically | ✅ POST /orders with existing prescription_id | ❌ Not available |
| Trigger refill via new e-Rx | ✅ Supported | ✅ Supported |
| Trigger refill via dashboard | ✅ Supported | ✅ Supported |
Track refills_left in webhooks | ✅ Available in all events | ✅ Available in all events |
:::
Step 5 — Track the order lifecycle
After you place an order, Honeybee sends webhooks at every meaningful state change. Here's what to expect.
Order status flow
RX_UPDATED — Order status changed
Fires whenever an order moves to a new status. Use this to update your internal records and surface status to patients.
{
"event_id": "a7a26ff2-e851-45b6-9634-d595f45458b7",
"patient_id": "ay87nt",
"event_type": "RX_UPDATED",
"medication_requests": [
{
"id": 183601,
"drug_name": "ESTRADIOL 1MG TABLET",
"ndc": "62135040012",
"refills_left": 10,
"medication_dispenses": [
{
"order_number": "XQ05O2A",
"order_status": "Filling",
"order_date": "2024-03-14T13:17:54.906-07:00",
"product_name": "Estradiol",
"strength": "1 mg",
"form": "Tablet",
"shipment": null
}
]
}
]
}
Key fields: order_number · order_status · drug_name · ndc · refills_left
SHIPMENT_UPDATED — Package in transit
Fires when the carrier scans the package. Includes everything you need to surface tracking directly to patients.
{
"event_id": "a7a26ff2-e851-45b6-9634-d595f45458b7",
"patient_id": "ay87nt",
"event_type": "SHIPMENT_UPDATED",
"medication_requests": [
{
"medication_dispenses": [
{
"order_number": "XQ05O2A",
"order_status": "Shipped",
"shipment": {
"shipment_date": "2024-03-14T16:28:56.487-07:00",
"tracking_url": "https://www.fedex.com/fedextrack/?trknbr=774899172137",
"tracking_no": "774899172137",
"carrier": "FedEx",
"method": "FedEx Priority Overnight",
"latest_shipment_update": {
"event_code": "IT",
"description": "In Transit",
"occurred_at": "2024-03-15T09:28:57.000-07:00"
},
"shipment_updates": [
{
"event_code": "IT",
"description": "In Transit",
"occurred_at": "2024-03-15T09:28:57.000-07:00"
},
{
"event_code": "PU",
"description": "Picked Up",
"occurred_at": "2024-03-15T07:23:59.000-07:00"
}
]
}
}
]
}
]
}
Key fields: tracking_url · tracking_no · carrier · method · shipment_updates[]
ORDER_EXCEPTION — Action required
Fires when an order is placed On Hold. Something needs to be corrected before filling can continue.
{
"event_id": "a7a26ff2-e851-45b6-9634-d595f45458b7",
"patient_id": "ay87nt",
"event_type": "ORDER_EXCEPTION",
"exception": {
"id": 67,
"order_number": "9D84N",
"name": "State Invalid",
"message": "State needs to be updated on the order",
"order_actions": [
{
"event_key": "verified_by_partner",
"action": "API Update - Update your order via our API with the proper services to address the errors listed in the hold reason and validate that you have finished using the Partner Request Order Action API"
},
{
"event_key": "cancel_by_partner",
"action": "API Cancel - Cancel your order via our API"
}
]
}
}
Key fields: exception.name · exception.message · order_actions[].event_key
Step 6 — Handle exceptions
When an ORDER_EXCEPTION fires, the order is on hold and no action will be taken until you respond.
◆ What your team should know
Common exception types and what they usually mean:
| Exception | Likely cause | Action |
|---|---|---|
State Invalid | Shipping state doesn't match licensure | Update address or cancel |
Address Error | Undeliverable address | Correct via API — see Address Validation Errors |
Prescription Expired | Rx past expiration date | New Rx required — cancel and resubmit |
Payment Issue | Billing info missing or failed | Resolve payment, then validate |
◇ Responding via API
Respond on the Submit New Partner Order Action Request endpoint. The request body takes a single required event field.
# Option A — Fix and continue
POST /v1/orders/{order_number}/partner_order_action_requests
Authorization: Bearer {your_access_token}
Content-Type: application/json
{
"event": "VERIFIED_BY_PARTNER"
}
# Option B — Cancel
POST /v1/orders/{order_number}/partner_order_action_requests
{
"event": "CANCEL_BY_PARTNER"
}
Supported events: VERIFIED_BY_PARTNER, CANCEL_BY_PARTNER, PUT_ON_HOLD_BY_PARTNER, and REQUEST_REFUND_BY_PARTNER (the last also requires a reason_id — see Get Refund Reasons).
:::note Mapping the webhook to the API
The ORDER_EXCEPTION payload lists available actions as lowercase event_key values (e.g. verified_by_partner). When you call the API, send the corresponding uppercase value in the event field (VERIFIED_BY_PARTNER).
:::
Workflow comparison
Use this table to decide which integration path is right for your use case.
| Feature | API On-Demand ★ | Automatic Processing |
|---|---|---|
| Control over when orders are created | ✅ | ❌ |
| Reusable Rx across multiple orders (refills) | ✅ | ❌ |
| Programmatic refill triggering | ✅ | ❌ |
| Multiple shipping options without manual adjustment | ✅ | ❌ |
| Custom add-on items & branded materials per order | ✅ | ❌ * |
| Webhook updates (order, shipment, exceptions) | ✅ | ✅ |
| Orders Dashboard access | ✅ | ✅ |
| Automatic order creation on Rx receipt | ❌ ** | ✅ |
| Minimal setup / fastest to integrate | ❌ | ✅ |
* Automatic processing supports one static add-on item per order. For dynamic or multiple items, use the API-driven workflow.
** You can configure your API to fire an order on each RX_RECEIVED webhook — replicating automatic order creation while keeping all API-driven features.
Testing in sandbox
Before going live, validate your full integration in the Honeybee sandbox environment, which mirrors production exactly.
:::info Sandbox resource server
| Host | https://partners.sandbox.honeybeehealth.com |
| Auth | Sandbox-specific credentials only — see Sandbox Authentication |
| ::: |
◆ For your team
The sandbox lets you walk through the full order lifecycle — prescriptions, webhooks, statuses, and exceptions — without affecting real patients or prescribers. Use it to:
- Train your team on exception handling before go-live
- Validate webhook handling end-to-end
- Test edge cases like address errors and prescription expiry
- Generate test prescriptions using the Test Prescription feature (see below)
Test Prescription feature
The Test Prescription feature lets you generate and submit simulated prescriptions directly from the Partner Dashboard — no real patient or prescriber data required. It runs through the same pipeline as production, so what works in sandbox will work in production.
Editable fields
Patient information
| Field | Input type | Notes |
|---|---|---|
| First name | Free text | — |
| Last name | Free text | — |
| Date of birth | Date picker | — |
| Free text | Must be valid email format | |
| Phone number | Free text | Must be valid phone format |
| EHR ID | Free text | Unique medical record ID — auto-generated if not provided |
Prescriber information
| Field | Input type | Notes |
|---|---|---|
| Prescriber order number | Free text | Must be unique per request — auto-generated if not provided |
Medication information
| Field | Input type | Notes |
|---|---|---|
| Medication name & NDC | Search/select | Sourced from GET /products formulary catalog |
| Number of refills | Integer | Defaults to 0 if not specified |
| Sig text (patient directions) | Free text | Dosage instructions for the patient |
Submission flow
- Complete the patient, prescriber, and medication fields in the Test Rx form.
- The system validates all identifiers and required inputs.
- On submit:
- A unique Prescriber Order Number is generated/validated if not provided
- A unique EHR ID is generated per patient if not provided
- The prescription is sent through the same pipeline as production
- An
RX_RECEIVEDwebhook fires to your configured endpoint — from here, follow the normal integration flow starting at Step 2. - Use the Reset button to clear all fields for a new test entry.
Use a consistent naming convention for your test patients (e.g. Honee Bea, Honee Bea 2) so sandbox data is easy to identify and filter in the Orders Dashboard.
What's next
Once you've walked through this guide and validated in sandbox, you're ready to go live.
| Resource | Description |
|---|---|
| Authentication & Authorization | Set up OAuth 2.0 and get your access tokens |
| API Requests | How to structure requests, headers, and error handling |
| Webhook Events | Full event type reference with sample payloads |
| Data Model & Glossary | How prescriptions, orders, and shipments relate, and what each identifier means |
| Matching Event Data to Patients | Deep dive on patient matching strategies |
| Order Statuses | Canonical list of order_status values and the lifecycle |
| Event Signature Validation | How to verify Honeybee sent the webhook |
| Error Codes | Consolidated reference for HTTP and numeric error codes |
| Address Validation Errors | Handling and resolving shipping address exceptions |
| API Reference | Full endpoint reference with request/response shapes |
Questions? Reach out to your Honeybee partner success manager.