Skip to content

Mark as read

Marking messages as read tells WhatsApp that your application has read a chat’s history, which shows the “blue ticks” to whoever sent the messages.

Automatic marking

Turbo Notify already marks a chat’s (or group’s) unread messages as read automatically before sending, replying to, reacting to, editing or deleting a message in that same chat, and also when you start typing (stopping typing reads nothing). This mirrors how a real WhatsApp app behaves: the number shows as online, the messages are read, and only then does the action happen.

The number goes back offline on its own a few minutes after the last interaction (this is the presence shown in WhatsApp: the number’s connection and status do not change). Opening the conversation this way is automatic, uses no quota of its own (the send, reply or reaction counts as before) and produces no webhook event.

Use the endpoint below only when you want to mark a chat as read without taking any other action on WhatsApp (the number also shows as online before reading), for example to keep your own application’s inbox in sync with WhatsApp.

An AI agent connected through the MCP server does the same with the mark_as_read tool (scope messages:send, same plan requirement), useful for triage or for handing the conversation to a person without replying.

Mark a chat as read

mark-as-read.sh
curl -X POST \
https://api.turbonotify.com/v1/messages/read \
-H "Authorization: Bearer YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": {"number": "+5511988887777"}
}'

Turbo Notify responds with an asynchronous acceptance:

HTTP status: 202
{
  "operation_id": "op_read_9f3c2a1d47e8",
  "status": {
    "state": "pending",
    "at": "2025-07-16T10:00:00Z"
  }
}

The asynchronous acceptance only confirms that the request was queued. The unread messages are looked up when the request is processed; if there are none, nothing is marked as read (the number still shows as online) and no error is raised.

Available recipients

The to field accepts exactly one of the three forms below, just like the send message route:

FormExampleWhen to use
number{"number": "+5511988887777"}A known E.164 number
group_id{"group_id": "grp_…"}A WhatsApp group
contact_id{"contact_id": "ct_…"}The contact’s ID in Turbo Notify (the phone number is looked up for you)

Mark a group as read

To mark the messages of a WhatsApp group as read, use to.group_id with the group’s identifier instead of to.number. Since a group can have several people with unread messages, Turbo Notify groups the marking by sender within the group.

mark-as-read-group.sh
curl -X POST \
https://api.turbonotify.com/v1/numbers/NUMBER_ALIAS/messages/read \
-H "Authorization: Bearer YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": {"group_id": "grp_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4"}
}'

The group_id is the group’s identifier in the grp_{hex32} format, returned by the list groups endpoint.

Mark as read by contact_id

Use to.contact_id to mark as read the messages of a contact in your Turbo Notify contacts without giving the phone number directly. The phone number is taken from the contact’s record.

mark-as-read-contact.sh
curl -X POST \
https://api.turbonotify.com/v1/numbers/NUMBER_ALIAS/messages/read \
-H "Authorization: Bearer YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": {"contact_id": "ct_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4"}
}'

Mark as read from an extra number

In the nested form, the number that marks the messages as read is always the number in the path. To mark messages as read from a registered, active extra number, use that form with the number’s alias in place of {ref}:

mark-as-read.sh
curl -X POST \
https://api.turbonotify.com/v1/numbers/vendas-sp/messages/read \
-H "Authorization: Bearer YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": {"number": "+5511988887777"}
}'

The two forms handle the acting number differently:

  • Nested (POST /v1/numbers/{ref}/messages/read): the number that marks the messages is always the alias in the path.
  • Flat (POST /v1/messages/read): always marks from the main number (main).

To mark messages as read from an extra number, you must use the nested form, with the extra number’s alias in the URL path.

If the alias in the path is not registered, or the number is not active, the request is rejected.

Learn more about extra numbers.

Webhook events

Marking as read has no completion confirmation: the 202 Accepted only confirms the asynchronous acceptance, and no webhook event is delivered for these requests.

Possible errors

StatusError codeDescription
400contact_not_foundThe contact_id given in to does not belong to this organization.
400contacts_not_enabledMarking by contact_id is unavailable right now. Try again later; if it persists, contact support.
400groups_not_enabledGroup features are unavailable right now. Try again later; if it persists, contact support.
400invalid_recipientThe recipient given in to could not be resolved to a sendable address. Giving none, or more than one, of number, group_id and contact_id returns 422 validation_error.
402feature_not_availableThe feature is not available on your plan.
401not_authenticatedThe API key is invalid or missing.
403insufficient_scopeThe API key does not have the messages:send scope (the response includes required_scope).
404number_not_foundThe {ref} in the path does not match any number on the account (on the flat route: the account has no main number yet).
400invalid_number_idThe value in the URL starts with num_ but is not a valid number id.
404group_not_foundThe group_id given in to was not found.
409number_not_connectedThe number is not connected to WhatsApp. Reconnect the number and try again.
422sender_not_foundThe alias or number given does not match any sender on the account.
422validation_errorThe request body is malformed or failed validation. The response includes details.errors with the list of invalid fields.
500internal_errorUnexpected internal server error.