Skip to main content

GET /sms/conversations/{line}/{number}/messages/{id}

Read the page containing a message

Scopemessages:read
Role permissionPhone numbers — line must be one of theirs
CostFree

"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

NameTypeRequiredExampleDescription
linestringyes12125550188One of your account's numbers — the line the thread is on. Digits.
numberstringyes13475550123The other party's number. Digits.
idintegeryes90218841The message id, from a thread read or an AccountSMS webhook.

Query parameters

NameTypeRequiredExampleDescription
limitintegernoPage 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.

FieldTypeDescription
linestring
numberstring
messagesobject[]
messages[].idinteger
messages[].directionin | outin = 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[].fromstring
messages[].tostring
messages[].textstringThe body. Empty is legal and normal for an MMS that carries only an image.
messages[].mediastring[]Attachment URLs. Publicly readable — the URL is the only thing protecting the file. Treat them as secrets and do not log them.
messages[].sentAtstring (RFC 3339)
messages[].readbooleanWhether YOU have read it.
messages[].readByinteger[]Every user who has read it, matching id in GET /users.
messages[].sentByintegerThe user who sent it. Absent when an integration sent it rather than a person.
messages[].deliveryobjectThe 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.statusstringThe carrier's own word for the outcome, passed through unmapped so the detail that makes a failure diagnosable survives.
messages[].delivery.errorstringThe carrier's failure detail. Empty on success.
messages[].delivery.atstring (RFC 3339)
messages[].groupParticipantsstring[]
messages[].scheduledbooleanQueued for future delivery — in the thread, but not sent yet.
messages[].scheduledAtstring (RFC 3339)
messages[].blockedbooleanNot delivered because the other party is on this line's blocked-sender list. The message exists and was charged for.
messages[].blockReasonstring
markedReadbooleanWhether this request also marked the messages read. Only ever true when you passed markRead=true.

Errors

StatusMeaning
400invalid_request — a missing or malformed field, an unknown enum value, or an unknown field in the body. Nothing was charged.
401unauthenticated — no credential, or one that is invalid, revoked or expired. The WWW-Authenticate header names the scope the endpoint wanted.
403Two different failures share this status, and the type tells them apart:
404not_found — no such object, or it is not this account's. The two are deliberately indistinguishable.
500internal_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"

Try it in the playground →