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/itemsItems are returned newest first.
Request parameters
| Query parameter | Type | Required | Limitations | Details |
|---|---|---|---|---|
recipient | string | no | The recipient's phone number in international format, WhatsApp username or BSUID. See Filtering. | |
whatsapp_message_id | string | no | The ID of the message the items belong to. | |
status[] | string[] | no | Possible values: queued, sent, delivered, read, failed | Array only. Multiple values are combined with OR. |
whatsapp_account_id | string | no | Must be one of your WhatsApp senders. | The MailerSend sender ID the messages were sent from. A deleted sender is accepted. See Sender identifiers. |
from | string | no | Max: 32 characters | The sender's phone number in international format. |
template_id | string | no | The ID of the template that was sent. | |
date_from | int|string | no | Timestamp 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_to | int|string | no | Timestamp 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. |
page | int | no | Min: 1, Max: 100 | To reach older items beyond page 100, narrow date_from and date_to. |
limit | int | no | Min: 1, Max: 100 | Default: 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:00Zcurl --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);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));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)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)
}
}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();
}
}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
)Responses
Valid
| Response key | Type | Details |
|---|---|---|
data[].id | string | ID of the item. The same value is sent as data.whatsapp_item_id in webhooks. |
data[].whatsapp_message_id | string | ID of the message the item belongs to. Pass it to GET /v1/whatsapp/messages/{message_id}. |
data[].whatsapp_account_id | string|null | The MailerSend sender ID of the phone number the message was sent from. See Sender identifiers. |
data[].from | string|null | The 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[].to | string | The recipient's phone number or BSUID. |
data[].status | string | The current status: queued, sent, delivered, read or failed. See WhatsApp status list. |
data[].template_id | string|null | The ID of the template that was sent. |
data[].template_name | string|null | The name of the template that was sent. null when the delivery failed before the template was loaded. |
data[].error_code | int|null | The WhatsApp Cloud API error code when the delivery failed, otherwise null. See Meta's error code reference. |
data[].error_message | string|null | The error message returned by WhatsApp when the delivery failed, otherwise null. |
data[].created_at | string | When the item was created, in ISO 8601 format. |
links.first | string | Full URL of the first page, with all your query parameters preserved. |
links.last | null | Always null. |
links.prev | string|null | Full URL of the previous page. null on the first page. |
links.next | string|null | Full URL of the next page. null on the last page. |
meta.current_page | int | The effective page. |
meta.current_page_url | string | Full URL of the current page. |
meta.from | int|null | Index of the first row on this page within the result set. null when the page is empty. |
meta.path | string | The URL of the endpoint, without query parameters. |
meta.per_page | int | The effective limit. |
meta.to | int|null | Index 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 EntityReturned 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 parameter | Type | Required | Limitations | Details |
|---|---|---|---|---|
item_id | string | yes | The 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');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));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)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)
}
}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();
}
}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')Responses
Valid
The response contains the same fields as an item of the list, plus recipient and activity.
| Response key | Type | Details |
|---|---|---|
data.recipient | object | The recipient the message was delivered to. See Recipients. |
data.recipient.id | string | ID of the recipient. Pass it to GET /v1/whatsapp/recipients/{recipient_id}. |
data.recipient.phone_number | string|null | The recipient's phone number, when known. |
data.recipient.username | string|null | The recipient's WhatsApp username, when known. |
data.recipient.status | string | active, invalid, suppressed or blocked. |
data.recipient.created_at | string | When the recipient was created, in ISO 8601 format. |
data.activity | object[] | 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.*.type | string | The status that was recorded: queued, sent, delivered, read or failed. |
data.activity.*.created_at | string | When 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 ForbiddenThe token is missing the whatsapp_read or whatsapp_full scope.
Response Code: 404 Not FoundReturned when the item does not exist, belongs to another account, or is older than the 7-day retention period.
Messages
Retrieve the WhatsApp messages you sent with the MailerSend API. Get a list of messages filtered by sender, template and date, or a single message with the delivery of every recipient.
Activities
Retrieve the status events of your WhatsApp messages with the MailerSend API. Get a list of activities filtered by message, item, recipient, type and date.