GET /sms/conversations/{line}/{number}/messages/{id}
Read the page containing a message
| Scope | messages:read |
| Role permission | Phone numbers — line must be one of theirs |
| Cost | Free |
"Open this thread at this message." You hold a message id from a webhook,
a search result or a notification and do not know its position — this
returns the surrounding page directly instead of making you walk the
thread with limit/offset until you find it.
Path parameters
| Name | Type | Required | Example | Description |
|---|---|---|---|---|
line | string | yes | 12125550188 | One of your account's numbers — the line the thread is on. Digits. |
number | string | yes | 13475550123 | The other party's number. Digits. |
id | integer | yes | 90218841 | The message id, from a thread read or an AccountSMS webhook. |
Query parameters
| Name | Type | Required | Example | Description |
|---|---|---|---|---|
limit | integer | no | — | Page size. An out-of-range value is a 400 rather than a silent clamp — a client asking for 5000 and receiving 200 with no explanation concludes the account only has 200 messages. |
Responses
200
The page of the conversation containing that message.
| Field | Type | Description |
|---|---|---|
line | string | |
number | string | |
messages | object[] | |
messages[].id | integer | |
messages[].direction | in | out | in = they texted you, out = you texted them. Spelled this way rather than the carrier's MO/MT, which reads backwards to everyone the first time. |
messages[].from | string | |
messages[].to | string | |
messages[].text | string | The body. Empty is legal and normal for an MMS that carries only an image. |
messages[].media | string[] | Attachment URLs. Publicly readable — the URL is the only thing protecting the file. Treat them as secrets and do not log them. |
messages[].sentAt | string (RFC 3339) | |
messages[].read | boolean | Whether YOU have read it. |
messages[].readBy | integer[] | Every user who has read it, matching id in GET /users. |
messages[].sentBy | integer | The user who sent it. Absent when an integration sent it rather than a person. |
messages[].delivery | object | The carrier's receipt. Absent means the carrier has not reported yet — normal for a message sent seconds ago, and permanent for an inbound one. Absent is NOT "failed"; a client that treats it that way shows a false failure on every fresh send. |
messages[].delivery.status | string | The carrier's own word for the outcome, passed through unmapped so the detail that makes a failure diagnosable survives. |
messages[].delivery.error | string | The carrier's failure detail. Empty on success. |
messages[].delivery.at | string (RFC 3339) | |
messages[].groupParticipants | string[] | |
messages[].scheduled | boolean | Queued for future delivery — in the thread, but not sent yet. |
messages[].scheduledAt | string (RFC 3339) | |
messages[].blocked | boolean | Not delivered because the other party is on this line's blocked-sender list. The message exists and was charged for. |
messages[].blockReason | string | |
markedRead | boolean | Whether this request also marked the messages read. Only ever true when you passed markRead=true. |
Errors
| Status | Meaning |
|---|---|
400 | invalid_request — a missing or malformed field, an unknown enum value, or an unknown field in the body. Nothing was charged. |
401 | unauthenticated — no credential, or one that is invalid, revoked or expired. The WWW-Authenticate header names the scope the endpoint wanted. |
403 | Two different failures share this status, and the type tells them apart: |
404 | not_found — no such object, or it is not this account's. The two are deliberately indistinguishable. |
500 | internal_error — something failed on our side. For a send, nothing was charged, guaranteed, which is what makes a retry safe. |
See Errors for the full catalog and what to do about each.
Example
curl -X GET 'https://api.account.telebroad.com/api/public/v1/sms/conversations/12125550188/13475550123/messages/90218841' \
-H "Authorization: Bearer $TB_KEY"