MailerSend
WhatsApp API

Items

Retrieve the delivery of your WhatsApp messages to each recipient with the MailerSend API. Get a list of items filtered by recipient, status and date, or a single item with its status timeline.

An item is the delivery of a WhatsApp message to one recipient. A message sent to 3 recipients has 3 items, and each item moves through its statuses independently. See WhatsApp status list.

Required token scopes

Requires a token with one of the whatsapp_read or whatsapp_full scopes.

Data retention

Items are kept for 7 days, the same as the message they belong to. An item older than that is no longer listed, and requesting it returns 404.

Get a list of WhatsApp items

Get a list of the deliveries of your WhatsApp messages with this GET request:

GET https://api.mailersend.com/v1/whatsapp/items

Items are returned newest first.

Request parameters

Query parameterTypeRequiredLimitationsDetails
recipientstringnoThe recipient's phone number in international format, WhatsApp username or BSUID. See Filtering.
whatsapp_message_idstringnoThe ID of the message the items belong to.
status[]string[]noPossible values: queued, sent, delivered, read, failedArray only. Multiple values are combined with OR.
whatsapp_account_idstringnoMust be one of your WhatsApp senders.The MailerSend sender ID the messages were sent from. A deleted sender is accepted. See Sender identifiers.
fromstringnoMax: 32 charactersThe sender's phone number in international format.
template_idstringnoThe ID of the template that was sent.
date_fromint|stringnoTimestamp is assumed to be UTC. Must be lower than date_to. No fractional seconds: 2026-10-14T00:00:00.000Z is rejected.Unix timestamp: 1791936000, ISO 8601 datetime: 2026-10-14T00:00:00Z or datetime: 2026-10-14 00:00:00. Exclusive.
date_toint|stringnoTimestamp is assumed to be UTC. Must be higher than date_from. No fractional seconds: 2026-10-15T00:00:00.000Z is rejected.Unix timestamp: 1792022400, ISO 8601 datetime: 2026-10-15T00:00:00Z or datetime: 2026-10-15 00:00:00. Exclusive.
pageintnoMin: 1, Max: 100To reach older items beyond page 100, narrow date_from and date_to.
limitintnoMin: 1, Max: 100Default: 25

Filtering

date_from and date_to are exclusive: only items created strictly after date_from and strictly before date_to are returned. Both accept a Unix timestamp, an ISO 8601 datetime with Z or an offset such as 2026-10-14T00:00:00+02:00, or a datetime in Y-m-d H:i:s format. A date without a time, such as 2026-10-14, returns a 422 validation error.

recipient accepts a phone number in international format, a WhatsApp username or a BSUID. from accepts a phone number in international format. In phone numbers, spaces, dashes and the leading + are ignored, so +48 600-000-001 and 48600000001 match the same recipient.

status[] must be sent as an array, for example ?status[]=delivered&status[]=read.

An example request that returns the failed deliveries to one recipient over one day:

GET https://api.mailersend.com/v1/whatsapp/items?recipient=48600000002&status[]=failed&date_from=2026-10-14T00:00:00Z&date_to=2026-10-15T00:00:00Z
curl --request GET \
  --url 'https://api.mailersend.com/v1/whatsapp/items?recipient=48600000002&status[]=failed&date_from=2026-10-14T00:00:00Z&date_to=2026-10-15T00:00:00Z&limit=25' \
  --globoff \
  --header 'Authorization: Bearer API_KEY_HERE'
use MailerSend\MailerSend;
use MailerSend\Helpers\Builder\WhatsappItemParams;

$mailersend = new MailerSend(['api_key' => 'key']);

$whatsappItemParams = (new WhatsappItemParams())
    ->setRecipient('48600000002')
    ->setStatus(['failed'])
    ->setDateFrom('2026-10-14T00:00:00Z')
    ->setDateTo('2026-10-15T00:00:00Z')
    ->setPage(1)
    ->setLimit(25);

$whatsappItems = $mailersend->whatsappItem->getAll($whatsappItemParams);

More examples

import 'dotenv/config';
import { MailerSend } from "mailersend";

const mailerSend = new MailerSend({
  apiKey: process.env.API_KEY,
});

mailerSend.whatsapp.item.list({
  recipient: "48600000002",
  status: ["failed"],
  date_from: 1791936000,
  date_to: 1792022400,
  limit: 25,
  page: 1,
})
  .then((response) => console.log(response.body))
  .catch((error) => console.log(error.body));

More examples

from mailersend import MailerSendClient, WhatsAppItemsBuilder
from mailersend.models.whatsapp_items import WhatsAppItemStatus

ms = MailerSendClient()

request = (WhatsAppItemsBuilder()
          .recipient("48600000002")
          .status([WhatsAppItemStatus.FAILED])
          .date_from("2026-10-14T00:00:00Z")
          .date_to("2026-10-15T00:00:00Z")
          .page(1)
          .limit(25)
          .build_list_request())

response = ms.whatsapp_items.list_whatsapp_items(request)

More examples

package main

import (
	"context"
	"log"
	"time"

	"github.com/mailersend/mailersend-go"
)

var APIKey = "Api Key Here"

func main() {
	// Create an instance of the mailersend client
	ms := mailersend.NewMailersend(APIKey)

	ctx := context.Background()
	ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
	defer cancel()

	options := &mailersend.ListWhatsAppItemOptions{
		Recipient: "48600000002",
		Status:    []string{"failed"},
		DateFrom:  1791936000,
		DateTo:    1792022400,
		Page:      1,
		Limit:     25,
	}

	_, _, err := ms.WhatsAppItem.List(ctx, options)
	if err != nil {
		log.Fatal(err)
	}
}

More examples

import com.mailersend.sdk.MailerSend;
import com.mailersend.sdk.exceptions.MailerSendException;
import com.mailersend.sdk.whatsapp.items.WhatsAppItem;
import com.mailersend.sdk.whatsapp.items.WhatsAppItemList;

public void getWhatsAppItems() {

    MailerSend ms = new MailerSend();
    ms.setToken("mailersend token");

    try {

        WhatsAppItemList list = ms.whatsapp().items()
            .recipient("48600000002")
            .addStatusFilter("failed")
            .dateFrom(1791936000)
            .dateTo(1792022400)
            .page(1)
            .limit(25)
            .getItems();

        for (WhatsAppItem item : list.items) {
            System.out.println(item.id);
            System.out.println(item.status);
            System.out.println(item.errorCode);
        }

    } catch (MailerSendException e) {

        e.printStackTrace();
    }
}

More examples

require "mailersend-ruby"

# Intialize the WhatsApp Items class
ms_whatsapp_items = Mailersend::WhatsAppItems.new

# Add parameters
ms_whatsapp_items.list(
  recipient: '48600000002',
  status: %w[failed],
  date_from: 1791936000,
  date_to: 1792022400,
  page: 1,
  limit: 25
)

More examples

Responses

Valid

Response keyTypeDetails
data[].idstringID of the item. The same value is sent as data.whatsapp_item_id in webhooks.
data[].whatsapp_message_idstringID of the message the item belongs to. Pass it to GET /v1/whatsapp/messages/{message_id}.
data[].whatsapp_account_idstring|nullThe MailerSend sender ID of the phone number the message was sent from. See Sender identifiers.
data[].fromstring|nullThe sender's phone number, or its WhatsApp username when the message was sent from the username or the sender has no phone number, such as one connected with a Meta virtual number. null when the sender has neither.
data[].tostringThe recipient's phone number or BSUID.
data[].statusstringThe current status: queued, sent, delivered, read or failed. See WhatsApp status list.
data[].template_idstring|nullThe ID of the template that was sent.
data[].template_namestring|nullThe name of the template that was sent. null when the delivery failed before the template was loaded.
data[].error_codeint|nullThe WhatsApp Cloud API error code when the delivery failed, otherwise null. See Meta's error code reference.
data[].error_messagestring|nullThe error message returned by WhatsApp when the delivery failed, otherwise null.
data[].created_atstringWhen the item was created, in ISO 8601 format.
links.firststringFull URL of the first page, with all your query parameters preserved.
links.lastnullAlways null.
links.prevstring|nullFull URL of the previous page. null on the first page.
links.nextstring|nullFull URL of the next page. null on the last page.
meta.current_pageintThe effective page.
meta.current_page_urlstringFull URL of the current page.
meta.fromint|nullIndex of the first row on this page within the result set. null when the page is empty.
meta.pathstringThe URL of the endpoint, without query parameters.
meta.per_pageintThe effective limit.
meta.toint|nullIndex of the last row on this page within the result set. null when the page is empty.
Response Code: 200 OK
Response Headers:
	content-type: application/json
{
  "data": [
    {
      "id": "67f91abe2202f3705540234b",
      "whatsapp_message_id": "67f91abd69f79df391e9d78d",
      "whatsapp_account_id": "3enl6x27wmrxrl2v",
      "from": "15550001234",
      "to": "48600000002",
      "status": "failed",
      "template_id": "23zxk54v6gjy6v7m",
      "template_name": "Order confirmation",
      "error_code": 131026,
      "error_message": "Message undeliverable",
      "created_at": "2026-10-14T12:25:33.000000Z"
    }
  ],
  "links": {
    "first": "https:\/\/api.mailersend.com\/v1\/whatsapp\/items?recipient=48600000002&status%5B0%5D=failed&date_from=2026-10-14T00%3A00%3A00Z&date_to=2026-10-15T00%3A00%3A00Z&limit=25&page=1",
    "last": null,
    "prev": null,
    "next": null
  },
  "meta": {
    "current_page": 1,
    "current_page_url": "https:\/\/api.mailersend.com\/v1\/whatsapp\/items?recipient=48600000002&status%5B0%5D=failed&date_from=2026-10-14T00%3A00%3A00Z&date_to=2026-10-15T00%3A00%3A00Z&limit=25&page=1",
    "from": 1,
    "path": "https:\/\/api.mailersend.com\/v1\/whatsapp\/items",
    "per_page": 25,
    "to": 1
  }
}

Paginating through the results

The list uses simple pagination. The response carries no total and no last_page, and links.last is always null. Follow the URL in links.next, which keeps the filters you sent, until it is null.

Error

Response Code: 403 Forbidden
{
  "message": "The custom API token you're using doesn't have the required permissions. #MS40301"
}

The token is missing the whatsapp_read or whatsapp_full scope.

Response Code: 422 Unprocessable Entity

Returned when a parameter is invalid — including a whatsapp_account_id that does not belong to your account, an unknown value in status[], a from that is not a phone number or is longer than 32 characters, a date_from or date_to without a time, a date_to that is not after date_from, or a page or limit out of range.

See - Validation errors

Get a WhatsApp item

Get a single item, together with its recipient and every status it moved through, with this GET request:

GET https://api.mailersend.com/v1/whatsapp/items/{item_id}

Request parameters

URL parameterTypeRequiredLimitationsDetails
item_idstringyesThe id of an item, as returned by GET /v1/whatsapp/items or GET /v1/whatsapp/messages/{message_id}, or sent as data.whatsapp_item_id in webhooks.
curl --request GET \
  --url https://api.mailersend.com/v1/whatsapp/items/67f91abe2202f3705540234a \
  --header 'Authorization: Bearer API_KEY_HERE'
use MailerSend\MailerSend;

$mailersend = new MailerSend(['api_key' => 'key']);

$whatsappItem = $mailersend->whatsappItem->find('item_id');

More examples

import 'dotenv/config';
import { MailerSend } from "mailersend";

const mailerSend = new MailerSend({
  apiKey: process.env.API_KEY,
});

mailerSend.whatsapp.item.single("item_id")
  .then((response) => console.log(response.body))
  .catch((error) => console.log(error.body));

More examples

from mailersend import MailerSendClient, WhatsAppItemsBuilder

ms = MailerSendClient()

request = (WhatsAppItemsBuilder()
          .whatsapp_item_id("item-id")
          .build_get_request())

response = ms.whatsapp_items.get_whatsapp_item(request)

More examples

package main

import (
	"context"
	"log"
	"time"

	"github.com/mailersend/mailersend-go"
)

var APIKey = "Api Key Here"

func main() {
	// Create an instance of the mailersend client
	ms := mailersend.NewMailersend(APIKey)

	ctx := context.Background()
	ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
	defer cancel()

	_, _, err := ms.WhatsAppItem.Get(ctx, "item-id")
	if err != nil {
		log.Fatal(err)
	}
}

More examples

import com.mailersend.sdk.MailerSend;
import com.mailersend.sdk.exceptions.MailerSendException;
import com.mailersend.sdk.whatsapp.items.WhatsAppItem;

public void getWhatsAppItem() {

    MailerSend ms = new MailerSend();
    ms.setToken("mailersend token");

    try {

        WhatsAppItem item = ms.whatsapp().items().getItem("item id");

        System.out.println(item.id);
        System.out.println(item.status);

    } catch (MailerSendException e) {

        e.printStackTrace();
    }
}

More examples

require "mailersend-ruby"

# Intialize the WhatsApp Items class
ms_whatsapp_items = Mailersend::WhatsAppItems.new

# Add parameters
ms_whatsapp_items.get(whatsapp_item_id: 'your-whatsapp-item-id')

More examples

Responses

Valid

The response contains the same fields as an item of the list, plus recipient and activity.

Response keyTypeDetails
data.recipientobjectThe recipient the message was delivered to. See Recipients.
data.recipient.idstringID of the recipient. Pass it to GET /v1/whatsapp/recipients/{recipient_id}.
data.recipient.phone_numberstring|nullThe recipient's phone number, when known.
data.recipient.usernamestring|nullThe recipient's WhatsApp username, when known.
data.recipient.statusstringactive, invalid, suppressed or blocked.
data.recipient.created_atstringWhen the recipient was created, in ISO 8601 format.
data.activityobject[]Every status the item moved through, ordered by status (queued, sent, delivered, read, failed) and then by created_at, so statuses recorded within the same second still come out in that order.
data.activity.*.typestringThe status that was recorded: queued, sent, delivered, read or failed.
data.activity.*.created_atstringWhen the status was recorded, in ISO 8601 format.
Response Code: 200 OK
Response Headers:
	content-type: application/json
{
  "data": {
    "id": "67f91abe2202f3705540234a",
    "whatsapp_message_id": "67f91abd69f79df391e9d78d",
    "whatsapp_account_id": "3enl6x27wmrxrl2v",
    "from": "15550001234",
    "to": "48600000001",
    "status": "read",
    "template_id": "23zxk54v6gjy6v7m",
    "template_name": "Order confirmation",
    "error_code": null,
    "error_message": null,
    "created_at": "2026-10-14T12:25:33.000000Z",
    "recipient": {
      "id": "67f91abe2202f37055402301",
      "phone_number": "48600000001",
      "username": null,
      "status": "active",
      "created_at": "2026-09-02T08:14:51.000000Z"
    },
    "activity": [
      {
        "type": "queued",
        "created_at": "2026-10-14T12:25:33.000000Z"
      },
      {
        "type": "sent",
        "created_at": "2026-10-14T12:25:34.000000Z"
      },
      {
        "type": "delivered",
        "created_at": "2026-10-14T12:25:36.000000Z"
      },
      {
        "type": "read",
        "created_at": "2026-10-14T12:31:02.000000Z"
      }
    ]
  }
}

Error

Response Code: 403 Forbidden

The token is missing the whatsapp_read or whatsapp_full scope.

Response Code: 404 Not Found

Returned when the item does not exist, belongs to another account, or is older than the 7-day retention period.

On this page