# Send a message `POST /api/send-message` (operationId: `sendMessage`, group: Messaging) Sends one message to one contact through the WhatsApp Cloud API: text, a template, or an image, video, audio or document. Free-form text and media can only be sent within 24 hours of the customer’s last message; outside that window send a template. For a chat imported from WhatsApp Web only text is supported, and the response carries channel: whatsapp_web. Subject to the workspace’s consent, assignment and channel rules. Not held to the default per-key request limit. A 500 here usually means WhatsApp refused the message, not that we failed: read errorCode before retrying (see the Errors guide). Part of the core API, included in the Growth and Scale plans. Any one of these scopes is enough: `whatsapp_api`. The workspace must also have the WhatsApp Cloud API enabled (403 feature_disabled_for_org otherwise). **Request body** (JSON, required) | Field | Type | Required | Description | | --- | --- | --- | --- | | `to` | string | yes | Recipient phone number with the country code, digits only. A leading + is accepted. A 10-digit number with no country code is treated as Indian (91 is added). | | `type` | string | no | Default text. One of: `text`, `template`, `image`, `video`, `audio`, `document`. | | `message` | string | no | The text, when type is text. | | `template` | object | no | When type is template. | | `template.name` | string | yes | Approved template name. Required. | | `template.language` | string | no | Language code such as en_US. Looked up from the approved template when omitted. | | `template.parameters` | array of string | no | Values for the body variables, in order. | | `template.headerImage` | string | no | Public URL of a header image. | | `template.headerImageId` | string | no | Uploaded media id of a header image. | | `mediaUrl` | string | no | Public URL of the media, for image, video, audio and document. Send this or mediaId. | | `mediaId` | string | no | A media id you uploaded to WhatsApp. Send this or mediaUrl. | | `caption` | string | no | Caption for image, video and document. | | `filename` | string | no | File name shown for a document. | | `senderId` | string | no | WhatsApp phone number id to send from. Default: the workspace’s main number. | | `confirmPolicy` | string | no | Send again with inbox.reply.sensitive_guard after a 403 policy_confirm, once the person has confirmed the text is meant to go out. | Example: ```json { "to": "919876543210", "type": "template", "template": { "name": "order_confirmation", "language": "en_US", "parameters": [ "ORD-4271", "2026-10-05" ] } } ``` **Response 200**: Accepted by WhatsApp. Delivery and read progress arrive as message_status webhooks, or read them from the receipts calls. Example: ```json { "success": true, "messageId": "wamid.HBgMOTE5ODc2NTQzMjEwFQIAERgSQTEB", "data": { "messaging_product": "whatsapp", "contacts": [ { "input": "919876543210", "wa_id": "919876543210" } ], "messages": [ { "id": "wamid.HBgMOTE5ODc2NTQzMjEwFQIAERgSQTEB" } ] } } ``` **Errors specific to this call.** The common ones (401, 403, 429 and the rest) are in the [Errors guide](https://inboxwa.online/docs/api/guide/errors.md). | Status | error | When | | --- | --- | --- | | 400 | `Phone number is required` | to is missing. | | 400 | `Message text is required` | type is text and message is empty. | | 400 | `Template name is required` | type is template and template.name is missing. | | 400 | `mediaId or mediaUrl is required for media messages` | A media type without media. | | 403 | `feature_disabled_for_org` | The WhatsApp Cloud API is switched off for the workspace. | | 403 | `not_assigned` | The caller is limited to assigned chats and this one is not assigned to them. | | 403 | `policy_denied` | A workspace policy refused the send: someone else is handling the chat (reply lock), the file type is not allowed, the text contains sensitive data the workspace blocks, or the sender holds the most chats allowed. policy names the rule and message says why. | | 403 | `policy_confirm` | The text looks like it contains a card, Aadhaar or PAN number and the workspace asks for confirmation. Send again with confirmPolicy set to the policy named in the reply. | | 500 | `WhatsApp’s own message` | WhatsApp refused the send. errorCode, errorTitle, errorSubcode and errorDetails carry its reason, for example 131047 for a closed 24-hour window. Retrying the same request will fail the same way. | Part of the InboxWA API reference: https://inboxwa.online/docs/api . Full reference as one document: https://inboxwa.online/docs/api.md . OpenAPI: https://inboxwa.online/openapi.json