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.
A WhatsApp message is the resource created by a single POST /v1/whatsapp/send request. One message can have up to 10 recipients, and the delivery to each recipient is tracked separately as an item.
Messages, items and activities
- Messages return one row per
POST/v1/whatsapp/send request. - Items return one row per recipient of a message, with its current status.
- Activities return one row per status event, so a single item appears once as
queued, once assent, once asdelivered, and so on.
Required token scopes
Requires a token with one of the whatsapp_read or whatsapp_full scopes.
Data retention
Sent WhatsApp messages are kept for 7 days. A message older than that is no longer listed, and requesting it returns 404.
Get a list of WhatsApp messages
Get a list of the WhatsApp messages sent from your account with this GET request:
GET https://api.mailersend.com/v1/whatsapp/messagesMessages are returned newest first. The list does not include items; use GET /v1/whatsapp/messages/{message_id} or GET /v1/whatsapp/items for the delivery to each recipient.
Request parameters
| Query parameter | Type | Required | Limitations | Details |
|---|---|---|---|---|
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. See Filtering. |
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 messages 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 messages 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.
from accepts a phone number in international format. Spaces, dashes and the leading + are ignored, so +1 555-000-1234 and 15550001234 match the same sender.
An example request that returns the messages one sender sent with one template over one day:
GET https://api.mailersend.com/v1/whatsapp/messages?whatsapp_account_id=3enl6x27wmrxrl2v&template_id=23zxk54v6gjy6v7m&date_from=2026-10-14T00:00:00Z&date_to=2026-10-15T00:00:00Z&limit=50curl --request GET \
--url 'https://api.mailersend.com/v1/whatsapp/messages?whatsapp_account_id=3enl6x27wmrxrl2v&template_id=23zxk54v6gjy6v7m&date_from=2026-10-14T00:00:00Z&date_to=2026-10-15T00:00:00Z&limit=25' \
--header 'Authorization: Bearer API_KEY_HERE'use MailerSend\MailerSend;
use MailerSend\Helpers\Builder\WhatsappMessageParams;
$mailersend = new MailerSend(['api_key' => 'key']);
$whatsappMessageParams = (new WhatsappMessageParams())
->setWhatsappAccountId('whatsapp_account_id')
->setFrom('15550001234')
->setTemplateId('template_id')
->setDateFrom('2026-10-14T00:00:00Z')
->setDateTo('2026-10-15T00:00:00Z')
->setPage(1)
->setLimit(25);
$whatsappMessages = $mailersend->whatsappMessage->getAll($whatsappMessageParams);import 'dotenv/config';
import { MailerSend } from "mailersend";
const mailerSend = new MailerSend({
apiKey: process.env.API_KEY,
});
mailerSend.whatsapp.message.list({
whatsapp_account_id: "whatsapp_account_id",
from: "15550001234",
template_id: "template_id",
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, WhatsAppMessagesBuilder
ms = MailerSendClient()
request = (WhatsAppMessagesBuilder()
.whatsapp_account_id("whatsapp-account-id")
.from_number("15550001234")
.template_id("template-id")
.date_from("2026-10-14T00:00:00Z")
.date_to("2026-10-15T00:00:00Z")
.page(1)
.limit(25)
.build_list_request())
response = ms.whatsapp_messages.list_whatsapp_messages(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.ListWhatsAppMessageOptions{
WhatsAppAccountID: "whatsapp-account-id",
From: "15550001234",
TemplateID: "template-id",
DateFrom: 1791936000,
DateTo: 1792022400,
Page: 1,
Limit: 25,
}
_, _, err := ms.WhatsAppMessage.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.messages.WhatsAppMessage;
import com.mailersend.sdk.whatsapp.messages.WhatsAppMessageList;
public void getWhatsAppMessages() {
MailerSend ms = new MailerSend();
ms.setToken("mailersend token");
try {
WhatsAppMessageList list = ms.whatsapp().messages()
.whatsappAccountId("whatsapp account id")
.from("15550001234")
.templateId("template id")
.dateFrom(1791936000)
.dateTo(1792022400)
.page(1)
.limit(25)
.getMessages();
for (WhatsAppMessage message : list.messages) {
System.out.println(message.id);
System.out.println(message.templateId);
}
} catch (MailerSendException e) {
e.printStackTrace();
}
}require "mailersend-ruby"
# Intialize the WhatsApp Messages class
ms_whatsapp_messages = Mailersend::WhatsAppMessages.new
# Add parameters
ms_whatsapp_messages.list(
whatsapp_account_id: 'your-whatsapp-account-id',
from: '15550001234',
template_id: 'your-template-id',
date_from: 1791936000,
date_to: 1792022400,
page: 1,
limit: 25
)Responses
Valid
| Response key | Type | Details |
|---|---|---|
data[].id | string | ID of the message. The same value is returned by POST /v1/whatsapp/send in the response body and the X-Message-Id header, and sent as data.whatsapp_message_id in webhooks. |
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 recipients of the message. |
data[].whatsapp_account_id | string|null | The MailerSend sender ID of the phone number the message was sent from. See Sender identifiers. |
data[].template_id | string|null | The ID of the template that was sent. |
data[].created_at | string | When the message 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": "67f91abd69f79df391e9d78d",
"from": "15550001234",
"to": [
"48600000001",
"48600000002"
],
"whatsapp_account_id": "3enl6x27wmrxrl2v",
"template_id": "23zxk54v6gjy6v7m",
"created_at": "2026-10-14T12:25:33.000000Z"
},
{
"id": "67f91a0c69f79df391e9d6a1",
"from": null,
"to": [
"US.13491208655302741918"
],
"whatsapp_account_id": "p6nq4jyzkyv5x3zl",
"template_id": "6v7m23zxk54vgjy2",
"created_at": "2026-10-14T12:21:16.000000Z"
}
],
"links": {
"first": "https:\/\/api.mailersend.com\/v1\/whatsapp\/messages?page=1",
"last": null,
"prev": null,
"next": null
},
"meta": {
"current_page": 1,
"current_page_url": "https:\/\/api.mailersend.com\/v1\/whatsapp\/messages?page=1",
"from": 1,
"path": "https:\/\/api.mailersend.com\/v1\/whatsapp\/messages",
"per_page": 25,
"to": 2
}
}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, 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 message
Get a single WhatsApp message, together with the delivery to each of its recipients, with this GET request:
GET https://api.mailersend.com/v1/whatsapp/messages/{message_id}Request parameters
| URL parameter | Type | Required | Limitations | Details |
|---|---|---|---|---|
message_id | string | yes | The id of a message, as returned by POST /v1/whatsapp/send in the response body and the X-Message-Id header, or by GET /v1/whatsapp/messages. |
curl --request GET \
--url https://api.mailersend.com/v1/whatsapp/messages/67f91abd69f79df391e9d78d \
--header 'Authorization: Bearer API_KEY_HERE'use MailerSend\MailerSend;
$mailersend = new MailerSend(['api_key' => 'key']);
$whatsappMessage = $mailersend->whatsappMessage->find('message_id');import 'dotenv/config';
import { MailerSend } from "mailersend";
const mailerSend = new MailerSend({
apiKey: process.env.API_KEY,
});
mailerSend.whatsapp.message.single("message_id")
.then((response) => console.log(response.body))
.catch((error) => console.log(error.body));from mailersend import MailerSendClient, WhatsAppMessagesBuilder
ms = MailerSendClient()
request = (WhatsAppMessagesBuilder()
.whatsapp_message_id("message-id")
.build_get_request())
response = ms.whatsapp_messages.get_whatsapp_message(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.WhatsAppMessage.Get(ctx, "message-id")
if err != nil {
log.Fatal(err)
}
}import com.mailersend.sdk.MailerSend;
import com.mailersend.sdk.exceptions.MailerSendException;
import com.mailersend.sdk.whatsapp.messages.WhatsAppMessage;
public void getWhatsAppMessage() {
MailerSend ms = new MailerSend();
ms.setToken("mailersend token");
try {
WhatsAppMessage message = ms.whatsapp().messages().getMessage("message id");
System.out.println(message.id);
System.out.println(message.templateId);
} catch (MailerSendException e) {
e.printStackTrace();
}
}require "mailersend-ruby"
# Intialize the WhatsApp Messages class
ms_whatsapp_messages = Mailersend::WhatsAppMessages.new
# Add parameters
ms_whatsapp_messages.get(whatsapp_message_id: 'your-whatsapp-message-id')Responses
Valid
The response contains the same fields as an item of the list, plus items.
| Response key | Type | Details |
|---|---|---|
data.items | object[] | One item per recipient of the message. Items are created asynchronously, so items can be empty right after the message is sent. |
data.items.*.id | string | ID of the item. The same value is sent as data.whatsapp_item_id in webhooks. |
data.items.*.whatsapp_message_id | string | ID of the message the item belongs to. |
data.items.*.whatsapp_account_id | string|null | The MailerSend sender ID of the phone number the message was sent from. |
data.items.*.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.items.*.to | string | The recipient's phone number or BSUID. |
data.items.*.status | string | The current status: queued, sent, delivered, read or failed. See WhatsApp status list. |
data.items.*.template_id | string|null | The ID of the template that was sent. |
data.items.*.template_name | string|null | The name of the template that was sent. null when the delivery failed before the template was loaded. |
data.items.*.error_code | int|null | The WhatsApp Cloud API error code when the delivery failed, otherwise null. See Meta's error code reference. |
data.items.*.error_message | string|null | The error message returned by WhatsApp when the delivery failed, otherwise null. |
data.items.*.created_at | string | When the item was created, in ISO 8601 format. |
To get the status timeline of one recipient, use GET /v1/whatsapp/items/{item_id} or GET /v1/whatsapp/activities.
Response Code: 200 OK
Response Headers:
content-type: application/json{
"data": {
"id": "67f91abd69f79df391e9d78d",
"from": "15550001234",
"to": [
"48600000001",
"48600000002"
],
"whatsapp_account_id": "3enl6x27wmrxrl2v",
"template_id": "23zxk54v6gjy6v7m",
"created_at": "2026-10-14T12:25:33.000000Z",
"items": [
{
"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"
},
{
"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"
}
]
}
}Error
Response Code: 403 ForbiddenThe token is missing the whatsapp_read or whatsapp_full scope.
Response Code: 404 Not FoundReturned when the message does not exist, belongs to another account, or is older than the 7-day retention period.
Sending a WhatsApp message
Send template-based WhatsApp messages with the MailerSend WhatsApp API. Learn about senders, recipients, personalization and delivery tracking.
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.