> ## Documentation Index
> Fetch the complete documentation index at: https://docs.waply.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Send outbound messages to contacts via the Waply API

> Send text, WhatsApp template, image, and document messages to contacts via the Waply API. Includes the Message object schema and status lifecycle.

The messages API lets you send outbound messages to contacts programmatically. Messages are always sent within a conversation — Waply creates a new conversation automatically if one does not already exist for the contact and channel combination. You can send plain text, approved WhatsApp template messages, images, and documents.

## The Message object

<ResponseField name="id" type="string">
  Unique identifier for the message, prefixed with `msg_`.
</ResponseField>

<ResponseField name="conversation_id" type="string">
  ID of the conversation this message belongs to.
</ResponseField>

<ResponseField name="direction" type="string">
  Either `inbound` (received from a contact) or `outbound` (sent by your team or via the API).
</ResponseField>

<ResponseField name="type" type="string">
  Message type. One of `text`, `template`, `image`, or `document`.
</ResponseField>

<ResponseField name="content" type="string">
  The text body of the message. Present for `text` and `template` types.
</ResponseField>

<ResponseField name="status" type="string">
  Delivery status of an outbound message. One of `sent`, `delivered`, `read`, or `failed`.
</ResponseField>

<ResponseField name="created_at" type="string">
  ISO 8601 timestamp of when the message was created.
</ResponseField>

### Message status values

| Status      | Meaning                                                    |
| ----------- | ---------------------------------------------------------- |
| `sent`      | The message has been accepted by the messaging provider.   |
| `delivered` | The message has been delivered to the recipient's device.  |
| `read`      | The recipient has read the message.                        |
| `failed`    | Delivery failed. Check the conversation for error details. |

<Note>
  Status updates from `sent` to `delivered` and `read` are delivered asynchronously via [webhooks](/api-reference/webhooks). Subscribe to the `message.delivered` and `message.read` events to track status changes in real time.
</Note>

***

## Send a message

### POST /messages/send

Sends an outbound message to a contact. The `type` field determines which other body fields are required.

<ParamField body="contact_id" type="string" required>
  ID of the contact to send the message to.
</ParamField>

<ParamField body="channel" type="string" required>
  The channel to send the message on. One of `whatsapp`, `instagram`, `messenger`, or `webchat`.
</ParamField>

<ParamField body="type" type="string" required>
  Message type. One of `text`, `template`, `image`, or `document`.
</ParamField>

<ParamField body="content" type="string">
  The text body of the message. Required when `type` is `text`.
</ParamField>

<ParamField body="template_name" type="string">
  The name of the approved WhatsApp message template to use. Required when `type` is `template`.
</ParamField>

<ParamField body="template_params" type="string[]">
  Ordered array of parameter values to substitute into the template's variable placeholders. Required when the template contains variables.
</ParamField>

<ParamField body="media_url" type="string">
  Publicly accessible URL of the media file to send. Required when `type` is `image` or `document`.
</ParamField>

***

### Send a text message

<CodeGroup>
  ```bash cURL theme={null}
  curl --request POST \
    --url https://api.waply.io/v1/messages/send \
    --header 'Authorization: Bearer YOUR_API_KEY' \
    --header 'Content-Type: application/json' \
    --data '{
      "contact_id": "con_01HXYZ",
      "channel": "whatsapp",
      "type": "text",
      "content": "Hi Jane, your order #4521 has shipped and is on its way!"
    }'
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch('https://api.waply.io/v1/messages/send', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.WAPLY_API_KEY}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      contact_id: 'con_01HXYZ',
      channel: 'whatsapp',
      type: 'text',
      content: 'Hi Jane, your order #4521 has shipped and is on its way!',
    }),
  });
  const message = await response.json();
  ```

  ```python Python theme={null}
  import requests, os

  response = requests.post(
      'https://api.waply.io/v1/messages/send',
      headers={'Authorization': f'Bearer {os.environ["WAPLY_API_KEY"]}'},
      json={
          'contact_id': 'con_01HXYZ',
          'channel': 'whatsapp',
          'type': 'text',
          'content': 'Hi Jane, your order #4521 has shipped and is on its way!',
      },
  )
  message = response.json()
  ```
</CodeGroup>

**Response**

```json theme={null}
{
  "id": "msg_01HSTU",
  "conversation_id": "conv_01HABC",
  "direction": "outbound",
  "type": "text",
  "content": "Hi Jane, your order #4521 has shipped and is on its way!",
  "status": "sent",
  "created_at": "2026-04-16T10:30:00Z"
}
```

***

### Send a template message

WhatsApp requires pre-approved message templates for outbound messages sent outside the 24-hour customer service window. Provide the template name and an array of parameter values in the order they appear in the template.

<Note>
  Template messages must be approved in WhatsApp Business Manager before you can send them. You can view your approved templates in Waply under Settings > Message Templates.
</Note>

<CodeGroup>
  ```bash cURL theme={null}
  curl --request POST \
    --url https://api.waply.io/v1/messages/send \
    --header 'Authorization: Bearer YOUR_API_KEY' \
    --header 'Content-Type: application/json' \
    --data '{
      "contact_id": "con_01HXYZ",
      "channel": "whatsapp",
      "type": "template",
      "template_name": "order_shipped",
      "template_params": ["Jane", "4521", "2 business days"]
    }'
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch('https://api.waply.io/v1/messages/send', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.WAPLY_API_KEY}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      contact_id: 'con_01HXYZ',
      channel: 'whatsapp',
      type: 'template',
      template_name: 'order_shipped',
      template_params: ['Jane', '4521', '2 business days'],
    }),
  });
  const message = await response.json();
  ```

  ```python Python theme={null}
  import requests, os

  response = requests.post(
      'https://api.waply.io/v1/messages/send',
      headers={'Authorization': f'Bearer {os.environ["WAPLY_API_KEY"]}'},
      json={
          'contact_id': 'con_01HXYZ',
          'channel': 'whatsapp',
          'type': 'template',
          'template_name': 'order_shipped',
          'template_params': ['Jane', '4521', '2 business days'],
      },
  )
  message = response.json()
  ```
</CodeGroup>

**Response**

```json theme={null}
{
  "id": "msg_01HVWX",
  "conversation_id": "conv_01HABC",
  "direction": "outbound",
  "type": "template",
  "content": "Hi Jane, your order #4521 has shipped. Expected delivery: 2 business days.",
  "status": "sent",
  "created_at": "2026-04-16T10:35:00Z"
}
```

***

### Send an image

<CodeGroup>
  ```bash cURL theme={null}
  curl --request POST \
    --url https://api.waply.io/v1/messages/send \
    --header 'Authorization: Bearer YOUR_API_KEY' \
    --header 'Content-Type: application/json' \
    --data '{
      "contact_id": "con_01HXYZ",
      "channel": "whatsapp",
      "type": "image",
      "media_url": "https://cdn.yourapp.com/images/invoice-4521.png"
    }'
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch('https://api.waply.io/v1/messages/send', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.WAPLY_API_KEY}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      contact_id: 'con_01HXYZ',
      channel: 'whatsapp',
      type: 'image',
      media_url: 'https://cdn.yourapp.com/images/invoice-4521.png',
    }),
  });
  const message = await response.json();
  ```

  ```python Python theme={null}
  import requests, os

  response = requests.post(
      'https://api.waply.io/v1/messages/send',
      headers={'Authorization': f'Bearer {os.environ["WAPLY_API_KEY"]}'},
      json={
          'contact_id': 'con_01HXYZ',
          'channel': 'whatsapp',
          'type': 'image',
          'media_url': 'https://cdn.yourapp.com/images/invoice-4521.png',
      },
  )
  message = response.json()
  ```
</CodeGroup>

**Response**

```json theme={null}
{
  "id": "msg_01HYYY",
  "conversation_id": "conv_01HABC",
  "direction": "outbound",
  "type": "image",
  "content": null,
  "status": "sent",
  "created_at": "2026-04-16T10:40:00Z"
}
```

***

### Send a document

<CodeGroup>
  ```bash cURL theme={null}
  curl --request POST \
    --url https://api.waply.io/v1/messages/send \
    --header 'Authorization: Bearer YOUR_API_KEY' \
    --header 'Content-Type: application/json' \
    --data '{
      "contact_id": "con_01HXYZ",
      "channel": "whatsapp",
      "type": "document",
      "media_url": "https://cdn.yourapp.com/docs/invoice-4521.pdf"
    }'
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch('https://api.waply.io/v1/messages/send', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.WAPLY_API_KEY}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      contact_id: 'con_01HXYZ',
      channel: 'whatsapp',
      type: 'document',
      media_url: 'https://cdn.yourapp.com/docs/invoice-4521.pdf',
    }),
  });
  const message = await response.json();
  ```

  ```python Python theme={null}
  import requests, os

  response = requests.post(
      'https://api.waply.io/v1/messages/send',
      headers={'Authorization': f'Bearer {os.environ["WAPLY_API_KEY"]}'},
      json={
          'contact_id': 'con_01HXYZ',
          'channel': 'whatsapp',
          'type': 'document',
          'media_url': 'https://cdn.yourapp.com/docs/invoice-4521.pdf',
      },
  )
  message = response.json()
  ```
</CodeGroup>

**Response**

```json theme={null}
{
  "id": "msg_01HZZZ",
  "conversation_id": "conv_01HABC",
  "direction": "outbound",
  "type": "document",
  "content": null,
  "status": "sent",
  "created_at": "2026-04-16T10:45:00Z"
}
```

<Tip>
  The `media_url` must be publicly accessible at the time of sending. Waply fetches the file and forwards it to the messaging provider. Signed URLs with short expiry times may cause delivery failures.
</Tip>
