Sign inGet an API key
API reference

Messages

Send text, media, templates and interactive messages; read status.

Send a message

POST/messagesscope: messages:send

Queues a message and returns 202 Accepted immediately. Delivery status then arrives via webhooks.

Common fields

FieldTypeDescription
tostring, requiredRecipient phone number with country code, digits only or with + (max 20 chars).
typestring, requiredtext, image, video, audio, document, template or interactive.
fromstring, optionalA phone_number_id from GET /me. Defaults to your first active number.

Text

{ "to": "14155550100", "type": "text", "text": { "body": "Your order #1042 has shipped." } }

text.body is required, up to 4096 characters.

Image, video, audio, document

{
  "to": "14155550100",
  "type": "document",
  "media": {
    "link": "https://example.com/invoice-1042.pdf",
    "caption": "Invoice #1042",
    "filename": "invoice-1042.pdf"
  }
}

media.link must be a public https URL. caption (max 1024) and filename (max 200) are optional.

Template

{
  "to": "14155550100",
  "type": "template",
  "template": {
    "name": "order_update",
    "language": "en_US",
    "components": [
      { "type": "body", "parameters": [
        { "type": "text", "text": "Jane" },
        { "type": "text", "text": "#1042" }
      ] }
    ]
  }
}

Only APPROVED templates can be sent — list them with GET /templates. language and components are optional.

Interactive buttons

{
  "to": "14155550100",
  "type": "interactive",
  "interactive": {
    "body": "Would you like to reschedule?",
    "buttons": [ { "title": "Yes" }, { "title": "No" }, { "title": "Call me" } ]
  }
}

body up to 1024 characters; 1–3 buttons, titles up to 20 characters.

The 24-hour window. Text, media and interactive messages are only accepted within 24 hours of the customer’s last message. Outside the window the API returns 422 — send an approved template instead.

Messages to contacts who opted out, or beyond your plan’s monthly quota, are rejected with 422.

Response

HTTP/1.1 202 Accepted

{ "id": 4812, "status": "queued", "to": "14155550100", "conversation_id": 377 }

Get a message

GET/messages/{id}scope: messages:read
{
  "id": 4812, "conversation_id": 377, "direction": "outbound", "type": "template",
  "body": null, "status": "delivered", "wamid": "wamid.HBgM…", "error": null,
  "sent_at": "2026-10-07 10:15:02", "delivered_at": "2026-10-07 10:15:04", "read_at": null,
  "created_at": "2026-10-07 10:15:01"
}

Statuses: queued → sent → delivered → read, or failed (with a reason in error).

List messages

GET/messagesscope: messages:read
QueryDescription
statusFilter by status
directioninbound or outbound
toFilter by contact phone number
page, per_pagePagination — per_page 1–100, default 25

Newest first. Response: { "data": [ … ], "meta": { "page": 1, "last_page": 8, "total": 187 } }.