Get line health
/channels/{channel}/healthMessaging health for one dedicated or inbound Blooio line: its live safety state plus reply, delivery, and risk metrics over the trailing days. Built for polling.
Freshness. safety is read live on every request, so a new safety action shows on the next poll. The metrics (replies, delivery, risk, daily) are recomputed at most every 5 minutes and may be served up to 30 minutes old while a recompute runs in the background. Read computed_at (equal to window.end) rather than assuming freshness. Polling more often than every 5 minutes returns the same metrics; polling by the ch_ channel id is cheapest, because a phone number or alias is resolved first.
First-reply rate. replies.first_reply_rate is the share of conversations this line started that got a written reply (reactions don't count). At the default days=7 it is the same number the safety system's one-way check uses: with more than 10 new conversations a day, a rate below 0.4 slows the line, and it pauses new conversations after 48 hours in that pattern or once the rate falls below 0.2.
Risk reply rate. risk.factors.reply_rate uses a different definition: a conversation counts as replied once it has 3 or more inbound messages, whoever started it.
Delivery comparison. The safety system compares the last 72 hours of delivery against a 7-day baseline. days=3 approximates the recent sample, and subtracting its counts from days=7 approximates the baseline.
Days. Day-bucketed values (replies.new_conversations, replies.first_replies, daily) use UTC days. Shared and trial lines return 403 health_unsupported_for_line_type; non-Blooio channels return 403 health_unsupported_for_channel_type.
Path parameters
channelRequiredstringThe channel reference — the same three forms from accepts: a phone number (URL-encode + as %2B), a channel alias, or the exact channel id (ch_...).
Headers
AuthorizationRequiredstringYour API key, sent as a bearer token: Authorization: Bearer <api_key>. Editing this stays in sync with the API key box on the right.
Query parameters
daysoptionalintegerTrailing window in days, 1 to 30. Anything else returns 400 invalid_window.
Returns
dataRequiredChannelHealthOne Blooio line's live safety state plus its metrics over the trailing window. Rates are fractions from 0 to 1, rounded to 3 decimals. Timestamps are epoch milliseconds.
dataRequiredChannelHealthOne Blooio line's live safety state plus its metrics over the trailing window. Rates are fractions from 0 to 1, rounded to 3 decimals. Timestamps are epoch milliseconds.
channel_idRequiredstringChannel id (ch_...).
addressRequiredstringThe line's phone number (E.164).
windowRequiredobjectThe window the metrics cover.
windowRequiredobjectThe window the metrics cover.
startRequiredintegerEpoch milliseconds.
endRequiredintegerEpoch milliseconds. Equals computed_at.
daysRequiredintegercomputed_atRequiredintegerWhen the metrics were computed (epoch milliseconds). At most about 5 minutes old for frequent pollers, never more than 30.
has_activityRequiredbooleanFalse when the line sent and received nothing in the window. risk.score and risk.level are null then, because a silent line scores the same as a healthy one.
safetyRequiredobjectLive safety state, read on every request (never cached). The same values the safety.state_changed webhook carries.
safetyRequiredobjectLive safety state, read on every request (never cached). The same values the safety.state_changed webhook carries.
tierRequiredstringWarm-up tier.
"new""warming""established"actionRequiredstringCurrent safety action on outbound sends.
"none""queue""slow""pause_new""reply_only""review"reasonsRequiredobjectWhy the current action applies, keyed by trigger. Empty when action is none.
limits_disabledRequiredbooleanTrue when safety limits are switched off for this line.
evaluated_atRequiredinteger | nullWhen the safety system last evaluated the line (epoch milliseconds). Null for a line it has never evaluated, which reports tier: new and action: none.
repliesRequiredobject
repliesRequiredobjectnew_conversationsRequiredintegerConversations this line started (UTC days in the window). Group chats are excluded.
first_repliesRequiredintegerOf those, how many got a written reply.
first_reply_rateRequirednumber | nullfirst_replies / new_conversations. At days=7 this equals the safety system's 7-day reply rate. Null with no new conversations.
unanswered_conversationsRequiredintegerConversations this line started in the window that used the full 3-message allowance before a reply and got no reply.
unanswered_rateRequirednumber | nullShare of the conversations this line started in the window that are unanswered after 3 messages. Null when it started none.
deliveryRequiredobjectOutbound delivery counts and rates, measured the way the safety system measures them.
deliveryRequiredobjectOutbound delivery counts and rates, measured the way the safety system measures them.
resolvedRequiredintegerSends whose protocol a device resolved (excludes pending and unknown).
imessageRequiredintegerResolved sends that went over iMessage.
reachedRequiredintegerSends that reached a device.
failedRequiredintegerSends that reached a device and then failed.
failure_rateRequirednumber | nullfailed / reached. Null below 20 resolved sends.
riskRequiredobject
riskRequiredobjectscoreRequiredinteger | nullRisk score; null when has_activity is false.
levelRequiredstring | nulllow below 30, medium below 60, else high. Null when has_activity is false.
"low""medium""high"nullfactorsRequiredobjectThe factors behind score. Keys: outbound_conversations_per_day, inbound_conversations_per_day, inbound_started_share, contacts, reply_rate, inbound_messages_per_conversation, inbound_message_share, peak_new_conversations_per_hour, peak_messages_per_hour, message_similarity. Shares and rates are fractions.
dailyRequiredobject[]One entry per UTC day with activity, oldest first. Quiet days are omitted.
dailyRequiredobject[]One entry per UTC day with activity, oldest first. Quiet days are omitted.
Array of object
dateRequiredstringsentRequiredintegerreceivedRequiredintegernew_conversationsRequiredintegerfirst_repliesRequiredintegerResponse codes
Sends a live request with your values and shows the real response below. Your key is stored only in this browser.
curl -X GET https://api.blooio.com/v4/channels/string/health?days=7 \{ "data": { "channel_id": "ch_a1b2c3d4", "address": "123 Main St", "window": { "start": 0, "end": 0, "days": 1 }, "computed_at": 0, "has_activity": true, "safety": { "tier": "new", "action": "none", "reasons": {}, "limits_disabled": false, "evaluated_at": 0 }, "replies": { "new_conversations": 0, "first_replies": 0, "first_reply_rate": 0, "unanswered_conversations": 0, "unanswered_rate": 0 }, "delivery": { "resolved": 0, "imessage": 0, "reached": 0, "failed": 0, "imessage_share": 0, "failure_rate": 0 }, "risk": { "score": 0, "level": "low", "factors": {} }, "daily": [ { "date": "2025-01-15", "sent": 0, "received": 0, "new_conversations": 0, "first_replies": 0 } ] }}