Message Stats

Aggregated messaging statistics for an organization — overall totals, per-user breakdowns, yearly trends, and daily conversation counts.

All endpoints require authentication via the X-API-Key header. See Authentication.

All stats are broken down by platform: email, stacked-sms, stacked-mms, personal-sms, web-chat, and a total aggregate. Each platform reports in (inbound) and out (outbound) counts.


Get org message stats

GET /stats/messages

Overall message stats for the organization within a date range.

Query parameters

ParameterTypeDefaultNotes
startDatestring30 days agoUnix timestamp in milliseconds.
endDatestringnowUnix timestamp in milliseconds.

Example request

curl "https://<host>/api/stats/messages?startDate=1713000000000&endDate=1716000000000" \
  -H "X-API-Key: your-api-key"

Response

{
  "success": true,
  "message": "Success",
  "data": {
    "email": { "in": 100, "out": 50 },
    "stacked-sms": { "in": 200, "out": 150 },
    "stacked-mms": { "in": 10, "out": 5 },
    "personal-sms": { "in": 50, "out": 40 },
    "web-chat": { "in": 30, "out": 25 },
    "total": { "in": 390, "out": 270 }
  }
}

Errors

StatusMessageCause
400Validation errorstartDate >= endDate, or invalid date format.

Get org stats by year

GET /stats/messages/by-year

Monthly message stats for a calendar year.

Query parameters

ParameterTypeDefaultNotes
yearstring—Four-digit year (e.g. 2026). Must be between 2020 and 9999.

Example request

curl "https://<host>/api/stats/messages/by-year?year=2026" \
  -H "X-API-Key: your-api-key"

Response

{
  "success": true,
  "message": "Success",
  "data": [
    {
      "month": 1,
      "stats": {
        "email": { "in": 50, "out": 30 },
        "stacked-sms": { "in": 100, "out": 80 },
        "stacked-mms": { "in": 5, "out": 2 },
        "personal-sms": { "in": 20, "out": 15 },
        "web-chat": { "in": 15, "out": 10 },
        "total": { "in": 190, "out": 137 }
      }
    }
  ]
}

Returns an array of 12 objects, one per month (1–12).

Errors

StatusMessageCause
400Validation errorInvalid year (not 2020–9999).

Get all users' message stats

GET /stats/messages/users

Per-user message stats for all users in the organization.

Query parameters

ParameterTypeDefaultNotes
startDatestring30 days agoUnix timestamp in milliseconds.
endDatestringnowUnix timestamp in milliseconds.

Example request

curl "https://<host>/api/stats/messages/users" \
  -H "X-API-Key: your-api-key"

Response

{
  "success": true,
  "message": "Success",
  "data": [
    {
      "userId": "665a...",
      "firstName": "John",
      "lastName": "Doe",
      "profileImg": "",
      "stats": {
        "email": { "in": 0, "out": 10 },
        "stacked-sms": { "in": 5, "out": 20 },
        "stacked-mms": { "in": 0, "out": 1 },
        "personal-sms": { "in": 2, "out": 5 },
        "web-chat": { "in": 1, "out": 3 },
        "total": { "in": 8, "out": 39 }
      }
    }
  ]
}

Get my message stats

GET /stats/messages/my-stats

Message stats for the currently authenticated user.

Query parameters

ParameterTypeDefaultNotes
startDatestring30 days agoUnix timestamp in milliseconds.
endDatestringnowUnix timestamp in milliseconds.

Example request

curl "https://<host>/api/stats/messages/my-stats" \
  -H "X-API-Key: your-api-key"

Response

Same shape as Get org message stats — platform-level in/out counts for the authenticated user only.


Get daily conversation counts

GET /stats/messages/daily-conversations

Unique daily conversation counts per user. Counts unique (date, user, contact) combinations across direct messages and bulk message recipients.

Query parameters

ParameterTypeDefaultNotes
startDatestring30 days agoUnix timestamp in milliseconds.
endDatestringnowUnix timestamp in milliseconds.

Example request

curl "https://<host>/api/stats/messages/daily-conversations" \
  -H "X-API-Key: your-api-key"

Response

{
  "success": true,
  "message": "Success",
  "data": [
    {
      "userId": "665a...",
      "firstName": "John",
      "lastName": "Doe",
      "profileImg": "",
      "conversationsCount": 150
    }
  ]
}

Response envelope

All endpoints use the standard envelope:

{
  "error": false,
  "success": true,
  "message": "...",
  "code": 200,
  "data": "..."
}

Error responses:

{
  "error": true,
  "success": false,
  "message": "...",
  "code": 400,
  "data": null
}

data is null for a general failure, such as a database error or an upstream timeout. When the request is rejected because of a specific field, data carries the field(s) at fault instead:

{
  "error": true,
  "success": false,
  "message": "phone: Phone parse failed: The string supplied did not seem to be a phone number (input: <masked>)",
  "code": 400,
  "data": {
    "issues": [
      {
        "path": "phone",
        "message": "Phone parse failed: The string supplied did not seem to be a phone number (input: <masked>)"
      }
    ]
  }
}

Each issue carries a path (the dotted path into the request body) and a message. A label is added when the path is not self-describing, which today means custom fields only, for example "path": "fields.68b0a1f39c2e4d0012ab77e5", "label": "Class Year". issues is an array, but treat it as holding at most one entry: validation stops at the first failure.

On this page