Get the numbers
Counts for the last 7, 30 or 90 days, ending now and read in your time zone: texts in and out by day and by hour, delivery and reply rates, how long people take to answer you and how long you take to answer them, iMessage against SMS, where texts came from, and the conversations waiting on you with what to fix next.
/v1/analytics
Counts for the last 7, 30 or 90 days, ending now and read in your time zone: texts in and out by day and by hour, delivery and reply rates, how long people take to answer you and how long you take to answer them, iMessage against SMS, where texts came from, and the conversations waiting on you with what to fix next. The numbers on the dashboard’s Analytics page.
delivery_rate is texts that reported delivered or read, out of texts that left the Mac or failed; canceled, expired, waiting and unconfirmed texts aren’t counted, and a regular text that never reports delivery counts as sent. reply_rate is people you texted one to one who texted back within reply_window_hours. Response times are medians over one-to-one conversations, counting a reply only within seven days.
Needs a key with the messages:read scope.
Query parameters
daysintegerHow many days to cover, ending today in your time zone: 7, 30 or 90. Default 30.
Default
30.
Example
/v1/analyticscurl "https://usebluebot.com/api/v1/analytics" \
-H "Authorization: Bearer $BLUEBOT_API_KEY"Response
200: The numbers.
object"analytics"requireddaysintegerrequiredtime_zonestringrequiredfromtimestamprequiredThe start of the first day covered, local midnight in
time_zone.totimestamprequiredThe time the numbers were read.
first_text_attimestamp or nullrequiredWhen the account’s first text went or came in; null before any.
totalsobjectrequiredCounts over the range.
Show its 12 fieldsHide its fields
sentintegerrequiredTexts that left the Mac (sent, delivered or read), by when they went.
receivedintegerrequiredTexts people sent you, by when they came in.
deliveredintegerrequiredSent texts that reported delivered or read.
readintegerrequiredSent texts that reported read.
failedintegerrequiredTexts that failed.
unconfirmedintegerrequiredTexts the Mac couldn’t confirm, by when they were handed to it.
canceledintegerrequiredTexts canceled before they went.
expiredintegerrequiredTexts that waited past their expiry.
people_textedintegerrequiredPeople you texted one to one.
people_repliedintegerrequiredOf them, people who texted back within
reply_window_hours.new_peopleintegerrequiredPeople texted for the first time.
stopsintegerrequiredPeople who asked to stop, by reply or added by you.
delivery_ratenumber or nullrequiredDelivered or read, out of texts that left the Mac or failed. Canceled, expired, waiting and unconfirmed texts aren’t counted. A fraction from 0 to 1; null when there is nothing to count yet.
0 to 1.
reply_ratenumber or nullrequiredPeople texted one to one who texted back within
reply_window_hoursof a text. A fraction from 0 to 1; null when there is nothing to count yet.0 to 1.
reply_window_hoursintegerrequiredresponse_timesobjectrequiredShow its 4 fieldsHide its fields
them_median_secondsinteger or nullrequiredHow long people take to answer you: from your text to their next one. In seconds; null when there are no replies to measure.
them_countintegerrequiredReplies measured.
you_median_secondsinteger or nullrequiredHow long you take to answer them: from their text to your next one. Away messages and keyword replies aren’t counted. In seconds; null when there are no replies to measure.
you_countintegerrequired
servicesobjectrequiredTexts that left the Mac, by the service they went as. RCS counts as SMS.
Show its 2 fieldsHide its fields
imessageintegerrequiredsmsintegerrequired
by_dayarray of objectrequiredShow its 3 fieldsHide its fields
daystringrequiredYYYY-MM-DD in
time_zone.sentintegerrequiredreceivedintegerrequired
by_hourarray of array of integersrequiredTexts in and out by weekday (Monday first) and hour, in
time_zone.Up to 7 items.
by_sourcearray of objectrequiredTexts that left the Mac by where they came from, most first.
Show its 2 fieldsHide its fields
sourcestringrequiredOne of
api,zapier,make,n8n,pipedream,cli,mcp,hook,broadcast,sequence,inbox,autopilot,keyword,away,widget,assistant,test,mac.countintegerrequired
healthobjectrequiredShow its 6 fieldsHide its fields
waitingintegerrequiredConversations whose last text is theirs and has no answer from you.
follow_up_gapsintegerrequiredOf those, people who answered a text of yours and have heard nothing for two days.
oldest_waiting_attimestamp or nullrequiredWhen the longest-waiting of those texts came in.
waiting_listarray of WaitingConversationrequiredUp to 10 conversations waiting on you, follow-up gaps and oldest first.
Show its 6 fieldsHide its fields
conversation_idstringrequiredA conv_ id.
Starts with
conv_.namestringrequiredThe person’s name, the group’s name, or their number when there is no name.
handlestring or nullrequiredTheir number or email address; null for a group chat.
is_groupbooleanrequiredsincetimestamprequiredWhen their last text came in.
follow_up_gapbooleanrequiredTrue when they answered a text of yours and have heard nothing for two days.
unconfirmedintegerrequiredTexts waiting for you to say whether they went.
heldintegerrequiredQueued texts held by a rule, not just waiting their turn.
fixesarray of AnalyticsFixrequiredWhat to fix next, most important first.
Show its 6 fieldsHide its fields
keystringrequiredOne of
follow_up_gaps,waiting,unconfirmed,failed,held,mac_checks,mac_offline,delivery,stops,slow_replies.titlestringrequiredWhat needs doing, in a sentence.
whystringrequiredWhy it matters, in a sentence.
countintegerrequiredhrefstringrequiredThe dashboard page where it is fixed.
severitystringrequiredOne of
high,medium,low.
{
"object": "analytics",
"days": 7,
"time_zone": "America/Chicago",
"from": "2026-11-07T06:00:00.000Z",
"to": "2026-11-13T19:41:00.000Z",
"first_text_at": "2026-09-02T16:20:00.000Z",
"totals": {
"sent": 182,
"received": 96,
"delivered": 171,
"read": 120,
"failed": 3,
"unconfirmed": 0,
"canceled": 4,
"expired": 1,
"people_texted": 64,
"people_replied": 41,
"new_people": 22,
"stops": 1
},
"delivery_rate": 0.9243,
"reply_rate": 0.6406,
"reply_window_hours": 72,
"response_times": {
"them_median_seconds": 1260,
"them_count": 58,
"you_median_seconds": 540,
"you_count": 37
},
"services": {
"imessage": 151,
"sms": 31
},
"by_day": [
{
"day": "2026-11-07",
"sent": 20,
"received": 9
}
],
"by_hour": [
[
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
],
[
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
],
[
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
],
[
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
],
[
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
],
[
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
],
[
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
],
"by_source": [
{
"source": "zapier",
"count": 104
},
{
"source": "inbox",
"count": 61
},
{
"source": "sequence",
"count": 17
}
],
"health": {
"waiting": 3,
"follow_up_gaps": 1,
"oldest_waiting_at": "2026-11-10T15:02:00.000Z",
"waiting_list": [
{
"conversation_id": "conv_1Hq2LxW9cVbN3mKpRtYs0a",
"name": "Marcus Lee",
"handle": "+15555550123",
"is_group": false,
"since": "2026-11-10T15:02:00.000Z",
"follow_up_gap": true
}
],
"unconfirmed": 0,
"held": 2
},
"fixes": [
{
"key": "follow_up_gaps",
"title": "1 person answered you and hasn’t heard back in two days.",
"why": "A reply that waits days often goes cold.",
"count": 1,
"href": "/app/inbox?filter=waiting",
"severity": "high"
}
]
}Errors
Every refusal has the same envelope and a page of its own. These are the ones this operation can give.
| Code | Status | What it means |
|---|---|---|
| 401 | The request carried no key, or a key BlueBot doesn’t know: mistyped, revoked, or a test key sent to the live API. | |
| 403 | The key doesn’t carry the scope the endpoint needs. Each endpoint’s reference names its scope. | |
| 429 | Too many requests. A key may make 120 requests a minute. The RateLimit header says how many are left, and Retry-After how long to wait. | |
| 500 | Something went wrong on BlueBot’s side. It was reported. Send the request again; with an Idempotency-Key that is always safe. | |
| 400 | Something in the request doesn’t fit: a missing or malformed field, a bad id, or a combination the endpoint refuses. details names each field. |
Try it
Call this operation from the page with your own key. The key stays in this tab and is forgotten when you leave.