API Documentation

Send WhatsApp messages from your own number with simple HTTP requests. No SDK required — works from browser, cURL, PHP, Python, Node.js, Google Sheets, and more.

Quick start

  1. Send your first message with a GET request:

Successful response:

JSON{ "success": true, "message": "Message sent" }

Base URL

All API requests are made to your MessageAPI instance:

Paths in this document are relative to the base URL above.

Authentication

Every API request requires your API key. Pass it in one of two ways:

MethodExample
Query parameter?apikey=msg_your_key_here
HTTP headerX-API-Key: msg_your_key_here
Keep your API key secret. Never expose it in public client-side code.

Tip: prefer the X-API-Key header over query params to keep your key out of logs and browser history.

Prerequisites

Before calling the API, ensure the following:

  • WhatsApp is connected in Settings (QR scan). Sending fails with HTTP 400 while disconnected.
  • Your account has an active trial or paid subscription. Expired accounts return HTTP 403.
  • You have an API key from Settings. It is required on every request.

Endpoints overview

Two interfaces are available: a simple GET API at /send.php and a JSON REST API under /api/v1/. Authentication is the same for both.

MethodPathDescription
GET/send.phpSend text, image or PDF via query parameters
POST/api/v1/sendSend a text message (JSON body)
POST/api/v1/send/imageSend an image from a public URL
POST/api/v1/send/documentSend a PDF from a public URL
GET/api/v1/statusWhatsApp connection status and daily usage
GET/api/v1/messages/:idCheck delivery status of a sent message

Response format

Every endpoint returns JSON. Successful operations use HTTP 200. Client and server errors use 4xx codes with a descriptive message.

Success (HTTP 200)

JSON{ "success": true, "message": "Message sent", "messageId": "550e8400-e29b-41d4-a716-446655440000" }

Every send endpoint returns a messageId. Use it with GET /api/v1/messages/:id to check delivery status.

Error (4xx)

JSON{ "error": "recipient is required" }

When a send attempt fails after the message is logged, the error response may include messageId as well.

Example — missing parameter:

HTTP 400{ "error": "text is required" }

Send text message

GET /send.php

Send a plain-text WhatsApp message. The simplest integration — a single GET request.

ParameterTypeRequiredDescription
recipientstringYesPhone with country code, no + (e.g. 12125551234) or group ID (e.g. 120363...@g.us)
apikeystringYesYour API key
textstringYesMessage body

cURL

Send image

GET /send.php

Send an image from a direct public URL. Optional caption with the text parameter.

ParameterTypeRequiredDescription
recipientstringYesPhone or group ID (120363...@g.us)
apikeystringYesYour API key
filestringYesDirect public URL to the image (.jpg, .png, etc.)
textstringNoCaption text
If the image URL contains & or ?, encode it with encodeURIComponent() before adding it to the request. Use direct image links — stock photo sites often block downloads.

Send PDF document

GET /send.php

Send a PDF document from a direct public URL.

ParameterTypeRequiredDescription
recipientstringYesPhone or group ID (120363...@g.us)
apikeystringYesYour API key
documentstringYesDirect public URL to a PDF file
filenamestringNoDisplay name (default: document.pdf)

Check connection status

GET /api/v1/status

Check whether WhatsApp is connected and how many messages you have sent in the rolling 24-hour window.

Or pass the API key as a header:

Response example:

JSON{ "connected": true, "phone": "12125551234", "dailyLimit": 50, "messagesToday": 12 }

Response fields:

FieldTypeDescription
connectedbooleantrue if WhatsApp is linked and ready to send
phonestringConnected number (country code, no +), or null
dailyLimitinteger | nullDaily cap for your plan. null on Unlimited
messagesTodayintegerMessages sent in the last 24 hours

dailyLimit is null on the Unlimited plan (no cap). Trial: 50/day · Personal: 150/day.

Message delivery status

GET /api/v1/messages/:id

After sending a message, use the returned messageId to check whether it was delivered or failed.

Requires the X-API-Key header. You can only query messages sent by your own account.

Response example:

JSON{ "id": "550e8400-e29b-41d4-a716-446655440000", "recipient": "12125551234", "type": "text", "status": "sent", "error": null, "createdAt": "2026-05-26T23:00:00.000Z" }

Status values

FieldDescription
pendingSend in progress
sentDelivered to WhatsApp successfully
failedSend failed — see error

Errors & limits

Rate limits

Limits apply per account on a rolling 24-hour window. The status endpoint returns your current usage.

Daily message limits depend on your plan:

PlanDaily limit
Trial50 messages
Personal150 messages
UnlimitedNo limit

Error (4xx)

HTTP codeMeaning
400Bad request — missing params, WhatsApp not connected, invalid URL
401Invalid or missing API key
403Subscription inactive or expired
429Daily message limit reached

Personal plan allows up to 5 recipients (no groups). Unlimited supports any recipient and groups.

Advanced topics

REST API (JSON)

For integrations that prefer POST requests with JSON bodies and header authentication.

All REST endpoints require the X-API-Key header and Content-Type: application/json.

POST /api/v1/send
ParameterTypeRequiredDescription
recipientstringYesPhone or group ID
tostringNoAlias for recipient (REST only)
textstringYesMessage body
POST /api/v1/send/image
ParameterTypeRequiredDescription
recipientstringYesPhone or group ID
filestringYesDirect public URL to the image
imagestringNoAlias for file (REST image endpoint)
text / captionstringNoCaption text
POST /api/v1/send/document
ParameterTypeRequiredDescription
recipientstringYesPhone or group ID
documentstringYesDirect public URL to a PDF file
filenamestringNoDisplay name (default: document.pdf)

Send to groups

Use the same endpoints as for individual chats. Set recipient to the group ID (120363...@g.us) instead of a phone number.

Your connected number must be a group admin and stay in the group. Group messages count toward your daily limit.

Get the Group ID

  1. In WhatsApp, open the group → Invite via link → copy the link.
  2. In Settings, open Message groups, paste the link, and copy the result.

Send text to a group

ParameterRequiredDescription
recipientYesGroup ID from Settings (e.g. 120363...@g.us)
apikeyYesYour API key
textYesMessage body

Send image or PDF to a group

Same parameters as Send image or Send PDF — only change recipient to the group ID.

REST API

Webhooks

With the Unlimited plan, MessageAPI can POST events to your server. Configure the webhook URL in Settings.

Available on the Unlimited plan only. WhatsApp must stay connected for incoming messages. Text messages only (v1).

Example handler

Download a minimal PHP script that logs each webhook request to a file. Upload it to your server, paste the URL in Settings, and use Test incoming to verify.

Download webhook-logger.php

Disconnect alerts

All plans can receive an email when WhatsApp disconnects. Enable or disable this in Settings → WhatsApp Connection. Unlimited accounts also receive a session.disconnected webhook event.

Event types

EventDescription
message.receivedSomeone sent a text message to your WhatsApp
message.sentAn outbound message was delivered successfully
message.failedAn outbound message failed to send
session.disconnectedWhatsApp disconnected and could not be restored automatically

Incoming message payload

Every delivery is a POST with Content-Type: application/json:

JSON{ "event": "message.received", "timestamp": "2026-05-26T23:00:00.000Z", "message": { "id": "3EB0...", "from": "12125551234", "fromJid": "12125551234@s.whatsapp.net", "pushName": "Juan", "isGroup": false, "groupId": null, "participant": null, "type": "text", "text": "Hello" } }

For group messages, isGroup is true, groupId is set, and participant is the sender's number.

Delivery status payload

After each send via the API, MessageAPI can notify your webhook when the message is sent or fails:

JSON — message.sent{ "event": "message.sent", "timestamp": "2026-05-26T23:00:00.000Z", "message": { "id": "550e8400-e29b-41d4-a716-446655440000", "recipient": "12125551234", "type": "text", "status": "sent", "error": null, "createdAt": "2026-05-26T23:00:00.000Z" } }
JSON — message.failed{ "event": "message.failed", "timestamp": "2026-05-26T23:00:01.000Z", "message": { "id": "550e8400-e29b-41d4-a716-446655440000", "recipient": "12125551234", "type": "text", "status": "failed", "error": "WhatsApp not connected. Scan QR code in Settings.", "createdAt": "2026-05-26T23:00:00.000Z" } }

The message.id matches the messageId returned by send endpoints and the status query.

Disconnect payload

JSON — session.disconnected{ "event": "session.disconnected", "timestamp": "2026-05-26T23:00:00.000Z", "session": { "phone": "12125551234", "reason": "connection_lost", "status": "disconnected" } }

reason is logged_out when WhatsApp was unlinked from another device, or connection_lost when the session could not be restored automatically.

Your endpoint

  • Respond with HTTP 200 to acknowledge receipt.
  • Use HTTPS in production.
  • Use Send test in Settings to verify your integration.
  • Use Test delivery in Settings to simulate a message.sent event.

Responsible use

Messages are sent from your own WhatsApp number. WhatsApp enforces its own limits and may restrict accounts that send unsolicited or high-volume messages.