Listening for Failed Responses and Order Exceptions
Why catching and routing our error messages matters (and how to do it right!)
Why this matters
When something goes wrong with an order (a bad address, an invalid package size, etc) Honeybee doesn't just fail silently. We send back a clear, specific reason. That message is designed to be actionable: it tells you exactly what broke and, in most cases, exactly what to do about it.
What we tend to find is that the messages themselves are rarely the issue, it's more that they don't always make it to the right place. A response might come back clearly, but if nothing on your end is listening for it, or it's landing somewhere no one checks day-to-day, it's easy for an order to sit stalled without anyone realizing. That can mean a longer wait for the patient, and a support conversation on both sides trying to retrace something we'd already flagged.
The short version: if you build one thing well in this integration, build reliable failure-listening. It pays for itself immediately.
Two places failures show up
There are two distinct moments where Honeybee tells you something went wrong, and your system should be listening at both.
1. Immediate API errors (synchronous)
If you make an API call that's malformed or invalid on its face (like requesting a package size that doesn't exist for that product) we reject it right in the response to your request. You know instantly, in the same request/response cycle.
Example: invalid package size
{
"errors": [
{
"code": 42247,
"message": "Invalid Item Package Size",
"error_detail": [
{
"field": "items[0].package_size",
"message": "There is no package size for the amount: 1 requested"
}
]
}
]
}
This tells you three things at once: what failed (package_size), why (no matching package size exists), and where in your payload to look (items[0]). Nothing about this needs a support ticket. Your system should be able to catch this, log it, and flag it back to whoever owns that order.
The numeric code (42247 above) identifies the specific error. See Error Codes for the full list of codes and what each one means.
2. Order exceptions (asynchronous, via webhook)
Some issues aren't known until after we've already accepted the order, for example, an address that fails validation during processing. In these cases, the order goes On Hold, and we send an ORDER_EXCEPTION webhook explaining exactly why.
Example: address issue
{
"event_id": "a7a26ff2-e851-45b6-9634-d595f45458b7",
"patient_id": "ay87nt",
"event_type": "ORDER_EXCEPTION",
"exception": {
"id": 67,
"order_number": "9D84N",
"name": "Address - Shipping Address Failed Validation",
"message": "The shipping address has been flagged as invalid. Please update the shipping address via API or your partner dashboard.",
"order_actions": [
{
"event_key": "verified_by_partner",
"action": "API Update/Confirm - Verify your order data is up to date. Then resolve the hold via the Partner Request Order Action API"
},
{
"event_key": "cancel_by_partner",
"action": "API Cancel - Cancel your order via our Cancel Order API"
}
]
}
}
Every ORDER_EXCEPTION webhook follows this shape: a plain-language name and message telling you why the order is stuck, plus an order_actions array telling you exactly what you're allowed to do to resolve it (update and re-verify, or cancel). You never have to guess.
What to do with this information
Getting the message is only half the job. It needs to land somewhere your team will actually see it and act on it. A few patterns we recommend:
- Subscribe to ORDER_EXCEPTION webhooks. If you haven't already, this is configured in the "Developers" section of the Partner Dashboard, under "API & Webhook Settings."
- Don't just log it, surface it. A webhook that lands in a log file nobody reads is functionally the same as no webhook at all. Pipe the
name,message, andorder_actionsinto wherever your team actually works, like your internal order queue, a Slack channel, your own partner-facing UI. - Surface the fix, not just the failure. Since
order_actionstells you what's allowed, your UI can show your team a real next step ("Update address" / "Cancel order") instead of just a red error badge. - Treat synchronous API errors the same way. If a POST /orders call comes back with an
errorsarray, don't let that get swallowed by a generic "something went wrong" message in your own system. Pass the specific field and message through. - Check the Developer tab, but don't rely on it alone. You can always view exceptions and errors manually in the "Developers" tab of the Partner Dashboard. This should be your fallback for spot-checking, not your primary detection method. If your team only finds out about a stuck order by checking a dashboard manually, orders will slip through.
Common failure types you'll encounter
| Failure type | When it happens | How you'll hear about it |
|---|---|---|
| Invalid package size | You request a package size that doesn't exist for that product | Immediate API error on your POST /orders call |
| Missing/invalid NDC | Required NDC wasn't included or doesn't match | Immediate API error on your POST /orders call |
| Address invalid | Shipping address fails validation during processing | ORDER_EXCEPTION webhook, order goes On Hold |
| Written quantity exceeded | Requested amount exceeds what the Rx authorizes | Immediate API error, or exception depending on timing |
| Other clinical/compliance holds | State-specific or product-specific restrictions | ORDER_EXCEPTION webhook, order goes On Hold |
The bottom line
Every failure we send back is written to be diagnosed and fixed without needing to contact support. The message tells you what broke, and the order_actions (where applicable) tell you how to fix it. Your job is just to make sure that information gets from our webhook or API response into the hands of the person on your team who can act on it quickly, and without someone having to go looking for it.
If you're not sure your system is catching these today, a good first test: intentionally trigger a package size error or an address exception in Sandbox, and see whether anyone on your team notices without checking the dashboard.
One note on testing these in Sandbox: the POST /simulate endpoint only supports the RX_RECEIVED event. To trigger a package size error or an address exception, make a normal POST /orders request against the Sandbox host with the bad input, rather than looking for a simulate option.