Channelsv4

Get line health

GET/channels/{channel}/health

Messaging 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

channelRequiredstring

The 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

AuthorizationRequiredstring

Your API key, sent as a bearer token: Authorization: Bearer <api_key>. Editing this stays in sync with the API key box on the right.

Bearer

Query parameters

daysoptionalinteger

Trailing window in days, 1 to 30. Anything else returns 400 invalid_window.

Returns

dataRequiredChannelHealth

One 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_idRequiredstring

Channel id (ch_...).

addressRequiredstring

The line's phone number (E.164).

windowRequiredobject

The window the metrics cover.

startRequiredinteger

Epoch milliseconds.

endRequiredinteger

Epoch milliseconds. Equals computed_at.

daysRequiredinteger
computed_atRequiredinteger

When the metrics were computed (epoch milliseconds). At most about 5 minutes old for frequent pollers, never more than 30.

has_activityRequiredboolean

False 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.

safetyRequiredobject

Live safety state, read on every request (never cached). The same values the safety.state_changed webhook carries.

tierRequiredstring

Warm-up tier.

"new""warming""established"
actionRequiredstring

Current safety action on outbound sends.

"none""queue""slow""pause_new""reply_only""review"
reasonsRequiredobject

Why the current action applies, keyed by trigger. Empty when action is none.

limits_disabledRequiredboolean

True when safety limits are switched off for this line.

evaluated_atRequiredinteger | null

When 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
new_conversationsRequiredinteger

Conversations this line started (UTC days in the window). Group chats are excluded.

first_repliesRequiredinteger

Of those, how many got a written reply.

first_reply_rateRequirednumber | null

first_replies / new_conversations. At days=7 this equals the safety system's 7-day reply rate. Null with no new conversations.

unanswered_conversationsRequiredinteger

Conversations this line started in the window that used the full 3-message allowance before a reply and got no reply.

unanswered_rateRequirednumber | null

Share of the conversations this line started in the window that are unanswered after 3 messages. Null when it started none.

deliveryRequiredobject

Outbound delivery counts and rates, measured the way the safety system measures them.

resolvedRequiredinteger

Sends whose protocol a device resolved (excludes pending and unknown).

imessageRequiredinteger

Resolved sends that went over iMessage.

reachedRequiredinteger

Sends that reached a device.

failedRequiredinteger

Sends that reached a device and then failed.

imessage_shareRequirednumber | null

imessage / resolved. Null below 20 resolved sends, too few to act on.

failure_rateRequirednumber | null

failed / reached. Null below 20 resolved sends.

riskRequiredobject
scoreRequiredinteger | null

Risk score; null when has_activity is false.

levelRequiredstring | null

low below 30, medium below 60, else high. Null when has_activity is false.

"low""medium""high"null
factorsRequiredobject

The 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.

Array of object

dateRequiredstring
sentRequiredinteger
receivedRequiredinteger
new_conversationsRequiredinteger
first_repliesRequiredinteger

Response codes

200Line health
400The request was malformed — check the path, query parameters, and body.
401Your API key is missing or invalid. Pass it as a bearer token.
403Your API key isn't allowed to access this channel (blocked key or plan limit).
404No channel was found with the provided `channel`.

Sends a live request with your values and shows the real response below. Your key is stored only in this browser.

Request
curl -X GET https://api.blooio.com/v4/channels/string/health?days=7 \
Response objectexample
{  "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      }    ]  }}