readyDocs Open the appOpen the app

Text reports

The same figures as the text reports in the app. Like the overview, most of them count the account and the sub-accounts under it (Top campaigns and Best hours to send count only the account the key belongs to), and they need reports access. A key user who only sees assigned contacts gets figures over those contacts, except for the two reports that cover the whole account, which answer 403 report_scope_forbidden. Delivery receipts and reply tags can still change a recent period, so read it again if you need it final.

#Texts by hour

Texts sent and delivered in each clock hour of one short window, up to 48 hours. Use it for today or yesterday, where a daily row would be a single point.

Parameters

fromstring · query
Start of the window, an ISO timestamp. Required.
tostring · query
End of the window, exclusive. Default: now. At most 48 hours after from.
Returns
data[]object[]
One row per hour that had texts, oldest first.
data[].hourstring
The hour, as a UTC timestamp such as 2026-10-31T14:00:00Z.
data[].countinteger
Texts sent in that hour.
data[].deliveredinteger
Of those, delivered so far.
Errors
HTTPCodeWhen
400invalid_requestfrom is missing, is not a valid time, or the window is longer than 48 hours.
400invalid_fieldA parameter sent twice, or too long; field names it.
403permission_deniedThe key’s user has no reports access.
503report_unavailableThe report couldn’t be read. Nothing changed; retry. Do not record zeros.

#Daily text volume

Texts sent and delivered per day, oldest first, in the key user’s time zone. This counts every text created that day, MMS and texts that failed included, across the account and its sub-accounts, the same as the Reports page. The daily report counts sms_sent differently: only texts handed to the carrier, without MMS, for one account in the account time zone, so the two can differ. Use the daily report for costs, replies and opt-outs.

Parameters

daysinteger · queryDefault 15
The last N days.
from, tostring · query
A custom window instead of days: dates as YYYY-MM-DD, in the key user’s time zone, or full timestamps.
Returns
data[]object[]
One row per day.
data[].datestring
The day, YYYY-MM-DD.
data[].countinteger
Texts sent that day.
data[].deliveredinteger
Of those, delivered so far.
Errors
HTTPCodeWhen
400invalid_fieldA parameter sent twice, or too long; field names it.
403permission_deniedThe key’s user has no reports access.
503report_unavailableThe report couldn’t be read. Nothing changed; retry. Do not record zeros.

#Top campaigns

The campaigns and drip campaigns that sent the most in the window, largest first. A campaign with no sends in the window is left out. Counts only the account the key belongs to, not its sub-accounts.

Parameters

daysinteger · queryDefault 30
The last N days.
from, tostring · query
A custom window instead of days: dates as YYYY-MM-DD, in the key user’s time zone, or full timestamps.
Returns
data[]object[]
Up to the 5 busiest.
data[].idinteger
The campaign or drip campaign id.
data[].namestring
Its name.
data[].kindstring
blast for a one time campaign, sequence for a drip campaign.
data[].created_atstring
When it was created.
data[].total_sentinteger
Texts sent in the window.
data[].deliveredinteger
Of those, delivered.
data[].failedinteger
Of those, failed.
data[].repliesinteger
Contacts who replied.
data[].delivery_ratenumber or null
Delivered over delivered plus failed, as a percent. null when nothing has resolved yet.
Errors
HTTPCodeWhen
400invalid_fieldA parameter sent twice, or too long; field names it.
403permission_deniedThe key’s user has no reports access.
503report_unavailableThe report couldn’t be read. Nothing changed; retry. Do not record zeros.

#Delivery breakdown

Did the texts arrive: totals, a trend per day, the reasons the failures gave, and the result for each sending number.

Parameters

daysinteger · queryDefault 30
The last N days.
from, tostring · query
A custom window instead of days: dates as YYYY-MM-DD, in the key user’s time zone, or full timestamps.
partstring · queryDefault all
Read less to answer faster: summary (totals and daily), numbers, reasons, detail (numbers and reasons) or all. A part you did not ask for comes back null, except daily, which comes back as an empty list.
Returns
data.daysinteger
The window length used.
data.totalsobject
sent, delivered, failed, pending, delivery_rate and failure_rate (percents).
data.daily[]object[]
One row per day with the same counts.
data.by_reason[]object[]
The most common failure reasons, each with reason and count.
data.reason_totalinteger
Failures that have a reason.
data.by_number[]object[]
Per sending number: phone_number, sent, delivered, failed, delivery_rate.
data.blockedobject
Texts Ready held back before sending, as compliance and undeliverable, each with attempts and recipients. Only there when you ask for summary or all; null when it can’t be read or the key user sees only assigned contacts.
Errors
HTTPCodeWhen
400invalid_fieldA parameter sent twice, or too long; field names it.
403permission_deniedThe key’s user has no reports access.
503FAILURE_REASONS_UNAVAILABLEThe failure reasons could not be read. The answer carries retryable: true.
503report_unavailableThe report couldn’t be read. Nothing changed; retry. Do not record zeros.

#Reply heatmap

How many replies arrived in each hour of each weekday. It counts replies, not a reply rate, because a reply can come long after the text that earned it.

Parameters

daysinteger · queryDefault 30
The last N days.
from, tostring · query
A custom window instead of days: dates as YYYY-MM-DD, in the key user’s time zone, or full timestamps.
tzstring · queryDefault: the key user’s time zone
An IANA name such as America/New_York. An unknown name is ignored.
Returns
data[]object[]
One row for each weekday and hour that had replies.
data[].dowinteger
Day of the week, 0 for Sunday to 6 for Saturday.
data[].hourinteger
Hour of the day, 0 to 23.
data[].ninteger
Replies in that slot.
timezonestring
The time zone the slots are counted in.
Errors
HTTPCodeWhen
400invalid_fieldA parameter sent twice, or too long; field names it.
403permission_deniedThe key’s user has no reports access.
503report_unavailableThe report couldn’t be read. Nothing changed; retry. Do not record zeros.

#Best hours to send

Texts sent and replies for each hour of the day, to show when people answer. The window is the last N times 24 hours, not whole days. Counts only the account the key belongs to, not its sub-accounts.

Parameters

daysinteger · queryDefault 30Max 365
The last N days.
tzstring · queryDefault: the key user’s time zone
An IANA name such as America/New_York. An unknown name is ignored.
Returns
data[]object[]
Always 24 rows, hour 0 to 23.
data[].hourinteger
Hour of the day.
data[].sentinteger
Texts sent in that hour.
data[].repliesinteger
Replies received in that hour.
data[].cohort_sentinteger
Texts sent to a known contact, the base for the next field.
data[].sent_with_replyinteger
Of those, texts whose contact replied within 7 days.
bestobject or null
The best sending window the report found. null when there is not enough data.
timezonestring
The time zone the hours are counted in.
Errors
HTTPCodeWhen
400invalid_fieldA parameter sent twice, or too long; field names it.
403permission_deniedThe key’s user has no reports access.
403report_scope_forbiddenThe key’s user only sees contacts assigned to them. This report covers the whole account.
503report_unavailableThe report couldn’t be read. Nothing changed; retry. Do not record zeros.

#Deliverability

Why texts fail. The last 24 hours, 7 days and 30 days, failures by group, the most common errors with advice, the result per sending number and per carrier, and the latest failures. The figures are refreshed about every 5 minutes.

Parameters

numbers_onlystring · queryDefault false
Send true to get only per_phone, faster.
Returns
summaryobject
Keyed 24h, 7d and 30d, each with total, delivered, failed, pending, delivery_rate and failure_rate.
failures_by_group[]object[]
status_group and count. status_group is the carrier’s group for the failure: UNDELIVERABLE (the phone could not take it), EXPIRED (the carrier gave up before it was delivered), REJECTED (the carrier refused it) or UNKNOWN (no receipt said why).
top_errors[]object[]
error_name, error_code, status_group, count, guidance and explanation.
per_phone[]object[]
from_number, total, delivered, failed, delivery_rate.
by_carrier[]object[]
carrier, total, delivered, failed, pending, delivery_rate, failure_rate. Carriers with fewer than 10 texts are left out.
recent_failures[]object[]
The latest failed texts, each with the reason in plain words.
Errors
HTTPCodeWhen
400invalid_fieldA parameter sent twice, or too long; field names it.
403permission_deniedThe key’s user has no reports access.
403report_scope_forbiddenThe key’s user only sees contacts assigned to them. This report covers the whole account.
403report_scope_forbiddenThe key’s user is a team member limited to some of the account’s numbers. This report covers every number on the account.
503report_unavailableThe report couldn’t be read. Nothing changed; retry. Do not record zeros.