Skip to the page

API reference

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.

GET/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. Keys and scopes

Query parameters

  • daysinteger

    How many days to cover, ending today in your time zone: 7, 30 or 90. Default 30.

    Default 30.

Example

GET/v1/analyticsGet the numbers →
curl "https://usebluebot.com/api/v1/analytics" \
  -H "Authorization: Bearer $BLUEBOT_API_KEY"

Response

200: The numbers.

  • object"analytics"required
  • daysintegerrequired
  • time_zonestringrequired
  • fromtimestamprequired

    The start of the first day covered, local midnight in time_zone.

  • totimestamprequired

    The time the numbers were read.

  • first_text_attimestamp or nullrequired

    When the account’s first text went or came in; null before any.

  • totalsobjectrequired

    Counts over the range.

    Show its 12 fields
    • sentintegerrequired

      Texts that left the Mac (sent, delivered or read), by when they went.

    • receivedintegerrequired

      Texts people sent you, by when they came in.

    • deliveredintegerrequired

      Sent texts that reported delivered or read.

    • readintegerrequired

      Sent texts that reported read.

    • failedintegerrequired

      Texts that failed.

    • unconfirmedintegerrequired

      Texts the Mac couldn’t confirm, by when they were handed to it.

    • canceledintegerrequired

      Texts canceled before they went.

    • expiredintegerrequired

      Texts that waited past their expiry.

    • people_textedintegerrequired

      People you texted one to one.

    • people_repliedintegerrequired

      Of them, people who texted back within reply_window_hours.

    • new_peopleintegerrequired

      People texted for the first time.

    • stopsintegerrequired

      People who asked to stop, by reply or added by you.

  • delivery_ratenumber or nullrequired

    Delivered 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 nullrequired

    People texted one to one who texted back within reply_window_hours of a text. A fraction from 0 to 1; null when there is nothing to count yet.

    0 to 1.

  • reply_window_hoursintegerrequired
  • response_timesobjectrequired
    Show its 4 fields
    • them_median_secondsinteger or nullrequired

      How long people take to answer you: from your text to their next one. In seconds; null when there are no replies to measure.

    • them_countintegerrequired

      Replies measured.

    • you_median_secondsinteger or nullrequired

      How 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
  • servicesobjectrequired

    Texts that left the Mac, by the service they went as. RCS counts as SMS.

    Show its 2 fields
    • imessageintegerrequired
    • smsintegerrequired
  • by_dayarray of objectrequired
    Show its 3 fields
    • daystringrequired

      YYYY-MM-DD in time_zone.

    • sentintegerrequired
    • receivedintegerrequired
  • by_hourarray of array of integersrequired

    Texts in and out by weekday (Monday first) and hour, in time_zone.

    Up to 7 items.

  • by_sourcearray of objectrequired

    Texts that left the Mac by where they came from, most first.

    Show its 2 fields
    • sourcestringrequired

      One of api, zapier, make, n8n, pipedream, cli, mcp, hook, broadcast, sequence, inbox, autopilot, keyword, away, widget, assistant, test, mac.

    • countintegerrequired
  • healthobjectrequired
    Show its 6 fields
    • waitingintegerrequired

      Conversations whose last text is theirs and has no answer from you.

    • follow_up_gapsintegerrequired

      Of those, people who answered a text of yours and have heard nothing for two days.

    • oldest_waiting_attimestamp or nullrequired

      When the longest-waiting of those texts came in.

    • waiting_listarray of WaitingConversationrequired

      Up to 10 conversations waiting on you, follow-up gaps and oldest first.

      Show its 6 fields
      • conversation_idstringrequired

        A conv_ id.

        Starts with conv_.

      • namestringrequired

        The person’s name, the group’s name, or their number when there is no name.

      • handlestring or nullrequired

        Their number or email address; null for a group chat.

      • is_groupbooleanrequired
      • sincetimestamprequired

        When their last text came in.

      • follow_up_gapbooleanrequired

        True when they answered a text of yours and have heard nothing for two days.

    • unconfirmedintegerrequired

      Texts waiting for you to say whether they went.

    • heldintegerrequired

      Queued texts held by a rule, not just waiting their turn.

  • fixesarray of AnalyticsFixrequired

    What to fix next, most important first.

    Show its 6 fields
    • keystringrequired

      One of follow_up_gaps, waiting, unconfirmed, failed, held, mac_checks, mac_offline, delivery, stops, slow_replies.

    • titlestringrequired

      What needs doing, in a sentence.

    • whystringrequired

      Why it matters, in a sentence.

    • countintegerrequired
    • hrefstringrequired

      The dashboard page where it is fixed.

    • severitystringrequired

      One of high, medium, low.

Response200
{
  "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.

CodeStatusWhat it means
unauthorized401The request carried no key, or a key BlueBot doesn’t know: mistyped, revoked, or a test key sent to the live API.
insufficient_scope403The key doesn’t carry the scope the endpoint needs. Each endpoint’s reference names its scope.
rate_limited429Too 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.
internal500Something went wrong on BlueBot’s side. It was reported. Send the request again; with an Idempotency-Key that is always safe.
invalid_request400Something 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.