Skip to content

Receipt history

After a message is sent, WhatsApp returns delivery and read confirmations. The receipt history records these confirmations: delivered (delivered to the device) and read (read by the recipient), in ascending chronological order.

List receipts

To list a message’s receipt history, make a GET request with the message_id returned when you sent it.

Endpoint: GET /v1/messages/{message_id}/receipts for the main number. For extra numbers, use GET /v1/numbers/{ref}/messages/{message_id}/receipts, where {ref} is the number’s current alias or the number’s id (num_…, the message’s number_id).

Required scope: messages:read

Path parameters:

ParameterTypeDescription
refstring(extra number route only) Alias of the number the message belongs to (main or the alias of an extra number) or its id (num_…).
message_idstringPublic message identifier (msg_{hex32})
turbo-notify.sh
curl -X GET \
https://api.turbonotify.com/v1/messages/msg_0198d3c5a1b24d3e9f01a2b3c4d5e6f7/receipts \
-H "Authorization: Bearer YOUR_KEY"

Response examples

With full history (direct message)

HTTP status: 200
{
  "message_id": "msg_0198d3c5a1b24d3e9f01a2b3c4d5e6f7",
  "receipts": [
    {
      "from": {
        "contact_id": "ct_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4",
        "name": "Ana Souza",
        "number": "5511988887777"
      },
      "status": "delivered",
      "at": "2025-07-16T10:00:05Z"
    },
    {
      "from": {
        "contact_id": "ct_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4",
        "name": "Ana Souza",
        "number": "5511988887777"
      },
      "status": "read",
      "at": "2025-07-16T10:01:12Z"
    }
  ]
}

In a group (multiple recipients)

The contact_id field appears only for participants who are already registered contacts in Turbo Notify. The name field (the WhatsApp display name) is independent: it can appear even without a contact_id. In the example below, Ana Souza is already a registered contact; Carlos Lima has a display name but is not a registered contact yet.

HTTP status: 200
{
  "message_id": "msg_0198d3c5a1b24d3e9f01a2b3c4d5e6f7",
  "receipts": [
    {
      "from": {
        "contact_id": "ct_b1c2d3e4f5a6b1c2d3e4f5a6b1c2d3e4",
        "name": "Ana Souza",
        "number": "5511988887777"
      },
      "status": "delivered",
      "at": "2025-07-16T10:00:05Z"
    },
    {
      "from": {
        "name": "Carlos Lima",
        "number": "5511977776666"
      },
      "status": "delivered",
      "at": "2025-07-16T10:00:08Z"
    },
    {
      "from": {
        "contact_id": "ct_b1c2d3e4f5a6b1c2d3e4f5a6b1c2d3e4",
        "name": "Ana Souza",
        "number": "5511988887777"
      },
      "status": "read",
      "at": "2025-07-16T10:01:12Z"
    }
  ]
}

No receipts yet

HTTP status: 200
{
  "message_id": "msg_0198d3c5a1b24d3e9f01a2b3c4d5e6f7",
  "receipts": []
}

Response structure

FieldTypeDescription
message_idstringPublic message identifier.
receiptsarrayList of status changes, in ascending chronological order.
receipts[].fromobjectWho confirmed the receipt. Omitted when WhatsApp gives no information about who confirmed it.
receipts[].from.contact_idstringPublic contact identifier (ct_{hex32}). Omitted when not available.
receipts[].from.namestringWhatsApp display name (personal data, under your organization’s responsibility). Omitted when not available.
receipts[].from.numberstringE.164 number without + of who confirmed the receipt. Omitted when WhatsApp does not reveal the number of who confirmed it.
receipts[].statusstringStatus reached in this change (delivered or read).
receipts[].atstringISO 8601 date and time when the status was recorded.

Status table

StatusDescription
deliveredConfirmation from WhatsApp that the message was delivered to the device.
readConfirmation from WhatsApp that the recipient read the message.

Note: Only confirmations sent by WhatsApp (delivered and read) are recorded as receipts. The sent status (sent to WhatsApp) can be checked with GET /v1/numbers/{ref}/messages/{id}/status.

Requires the Business plan or higher

The detailed receipt history (GET .../messages/{id}/receipts) requires the read_receipts feature, available from the Business plan up. Organizations on the Free and Lone Wolf plans receive:

HTTP status: 402
{
  "error": "feature_not_available"
}

This restriction applies to both routes (the nested /v1/numbers/{ref}/messages/{id}/receipts and the short /v1/messages/{id}/receipts route of the main number). The restriction does not affect the overall message status: GET .../messages/{id}/status stays available on every plan, including Free and Lone Wolf. Only the detailed history, change by change, requires the Business plan or higher.

See Quota and usage for the limits and restrictions of each plan.

Possible errors

StatusError codeDescription
402feature_not_availableOrganization on the Free or Lone Wolf plan: the receipt history requires the Business plan or higher.
401not_authenticatedThe API key is invalid or missing.
403insufficient_scopeThe API key does not have the messages:read scope.
404not_foundThe message was not found, belongs to another organization, or belongs to a number other than the one in the URL (on the shortcut route without {ref}, the main number): all of these cases return the same response, with no distinction.
404number_not_found(only on the route with {ref}) The alias or id in the URL does not match any registered number.
400invalid_number_id(only on the route with {ref}) The value in the URL starts with num_ but is not a valid number id.
500internal_errorUnexpected internal server error.