Skip to content
Get Started

Read Receipts API

Send read receipts to mark conversations as read via the Sendblue API

Send read receipts to mark a conversation as read. This shows the sender that you’ve seen their message.

Read receipts are available on every account — there is nothing to enable. A request only takes effect when all of these hold:

  • Supported line. from_number must be one of your Sendblue lines that supports read receipts. Most lines do. If a line doesn’t, the request returns 422 unsupported_on_this_line — contact support@sendblue.com to move to a supported line.
  • Existing 1:1 conversation. Your line must already have a one-to-one conversation with number (the contact has messaged you, or you have messaged them). There is nothing to mark as read otherwise.
  • Verified contact (Free API plan only). On the Free API plan, the contact must be verified for your account — they are verified automatically the first time they text your line.

Mark a conversation as read by sending a read receipt.

POST https://api.sendblue.com/api/mark-read
ParameterTypeRequiredDescription
numberstringYesThe phone number of the conversation to mark as read (E.164 format)
from_numberstringYesYour Sendblue line number (E.164 format)
Terminal window
curl -X POST 'https://api.sendblue.com/api/mark-read' \
-H 'sb-api-key-id: YOUR_API_KEY' \
-H 'sb-api-secret-key: YOUR_API_SECRET' \
-H 'Content-Type: application/json' \
-d '{
"number": "+14155551234",
"from_number": "+19175551234"
}'
const axios = require('axios');
await axios.post(
'https://api.sendblue.com/api/mark-read',
{
number: '+14155551234',
from_number: '+19175551234'
},
{
headers: {
'sb-api-key-id': 'YOUR_API_KEY',
'sb-api-secret-key': 'YOUR_API_SECRET',
'Content-Type': 'application/json'
}
}
);
import requests
response = requests.post(
'https://api.sendblue.com/api/mark-read',
json={
'number': '+14155551234',
'from_number': '+19175551234'
},
headers={
'sb-api-key-id': 'YOUR_API_KEY',
'sb-api-secret-key': 'YOUR_API_SECRET'
}
)
{
"status": "OK",
"message": "Mark read request sent",
"number": "+14155551234"
}

{
"status": "ERROR",
"message": "You must specify a `number` in the request body."
}
{
"status": "ERROR",
"message": "You must specify a valid `from_number` in the request body."
}

Returned when from_number is not a line on your account.

{
"status": "ERROR",
"message": "The from_number is not registered"
}

Free API plan only. The contact has not texted your line yet.

{
"status": "ERROR",
"message": "Contact has not been verified for this account"
}

The from_number is a line that does not support read receipts.

{
"status": "ERROR",
"message": "unsupported_on_this_line",
"detail": "Read receipts are not supported on this line."
}

The line is temporarily unable to send the read receipt. message is one of:

  • worker_version_unsupported — read receipts are not available on the line yet; retry later.
  • worker_unavailable — the line is not currently connected; retry shortly.
{
"status": "ERROR",
"message": "worker_unavailable",
"detail": "The line is not currently connected."
}

Returned when you exceed the request rate limit for this endpoint.


  1. 1:1 Conversations Only: The endpoint identifies the conversation by the contact’s number, so it only marks one-to-one conversations as read. There is no group_id parameter — read receipts cannot be sent for group conversations.

  2. Any Message Service: The request marks the conversation as read on your line whether it is iMessage, RCS, or SMS. The sender only sees a “Read” status where their messaging service supports it (iMessage, and RCS where the carrier supports it) — SMS has no read status to show.

  3. No Delivery Confirmation: A 200 means your line accepted the request. Read receipts are then sent on a “best effort” basis: there is no callback or webhook, and no confirmation that the receipt was applied or that the recipient’s device showed the read status. If no conversation with the number exists on the line, the request is accepted and has no effect.

  4. Recent Messages: Read receipts work best when sent shortly after receiving a message. Very old conversations may not show the read status.


Plan availability: Auto mark-read is available on the Free API plan and the AI Agent plan. You can enable it from the account settings page in your dashboard, or via the API endpoint below.

When auto mark-read is enabled, Sendblue automatically sends a read receipt on every inbound 1:1 iMessage your line receives. Useful for AI-agent and async-workflow setups where you want the sender to see their message has landed even while your backend is processing the response.

The auto-trigger only runs when all of these are true:

  • The inbound is an iMessage (not SMS or RCS — those don’t carry read receipts)
  • It’s a 1:1 conversation, not a group chat
  • It’s the first part of the inbound (multi-attachment messages don’t fire twice)

If any of those don’t hold, no auto read receipt is sent and the inbound flows through normally.

POST https://api.sendblue.com/accounts/settings/auto-mark-read
ParameterTypeRequiredDescription
auto_mark_readbooleanYestrue to enable, false to disable
Terminal window
curl -X POST 'https://api.sendblue.com/accounts/settings/auto-mark-read' \
-H 'sb-api-key-id: YOUR_API_KEY' \
-H 'sb-api-secret-key: YOUR_API_SECRET' \
-H 'Content-Type: application/json' \
-d '{
"auto_mark_read": true
}'
const axios = require('axios');
await axios.post(
'https://api.sendblue.com/accounts/settings/auto-mark-read',
{ auto_mark_read: true },
{
headers: {
'sb-api-key-id': 'YOUR_API_KEY',
'sb-api-secret-key': 'YOUR_API_SECRET',
'Content-Type': 'application/json'
}
}
);
import requests
response = requests.post(
'https://api.sendblue.com/accounts/settings/auto-mark-read',
json={'auto_mark_read': True},
headers={
'sb-api-key-id': 'YOUR_API_KEY',
'sb-api-secret-key': 'YOUR_API_SECRET'
}
)
{
"status": "OK",
"auto_mark_read": true
}
{
"status": "ERROR",
"message": "auto_mark_read must be a boolean"
}
  1. Setting takes effect on the next inbound. Cached account data invalidates immediately after the toggle write.
  2. Auto and manual coexist. Toggling auto on doesn’t disable the manual POST /api/mark-read endpoint — you can still send explicit receipts when you want.
  3. Same delivery semantics as the manual endpoint: best-effort, supported lines only, no recipient confirmation.