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

# POST Send a message

> Send an immediate message in direct mode or with a template.

## Endpoint

```txt theme={null}
POST /api/v1/messages/send
```

## Important — how to get `instanceId`

`instanceId` is required to send a message.

Do not use these instead:

* `name`
* `waNumber`

To get the correct `instanceId`:

1. call `GET /api/v1/instances`
2. select the target instance
3. copy `data[n].id`
4. send this value in the `instanceId` field

Example:

* `id` = technical identifier required by the API
* `name` = human-readable label
* `waNumber` = connected number shown to the user

## Body

| Field             | Type   | Required               | Description                                                                                   |
| ----------------- | ------ | ---------------------- | --------------------------------------------------------------------------------------------- |
| `instanceId`      | UUID   | yes                    | Technical identifier of the MsgFlash instance, obtained via `GET /api/v1/instances`           |
| `to`              | string | yes                    | E.164 number                                                                                  |
| `type`            | enum   | yes if no `templateId` | `text`, `image`, `video`, `audio`, `document`, `voice_note`, `location`, `contact`, `buttons` |
| `templateId`      | UUID   | yes if no `type`       | Template to render                                                                            |
| `text`            | string | depends on type        | Body du message                                                                               |
| `mediaUrl`        | string | depends on type        | Public media URL                                                                              |
| `latitude`        | number | if `location`          | Latitude                                                                                      |
| `longitude`       | number | if `location`          | Longitude                                                                                     |
| `locationName`    | string | no                     | Location name                                                                                 |
| `locationAddress` | string | no                     | Address                                                                                       |
| `contactId`       | UUID   | no                     | Shared contact or template context                                                            |
| `variables`       | object | no                     | `custom.*` values                                                                             |
| `title`           | string | if `buttons`           | Button message title                                                                          |
| `description`     | string | if `buttons`           | Button message description                                                                    |
| `footer`          | string | no                     | Button message footer                                                                         |
| `buttons`         | array  | if `buttons`           | List of buttons (max 2)                                                                       |

### Buttons

Each button must follow this structure:

```json theme={null}
{
  "title": "reply", // reply | url | call | copy | pix
  "displayText": "Button text",
  "id": "button_id",
  "url": "https://example.com", // for type url
  "phoneNumber": "+5511999999999", // for type call
  "copyCode": "dGV4dA==", // for type copy
  "currency": "BRL", // for type pix
  "name": "John Doe", // for type pix
  "keyType": "random", // for type pix
  "key": "0ea59ac5-f001-4f0e-9785-c7..." // for type pix
}
```

## Request example

```bash theme={null}
curl -X POST https://srv.msgflash.com/api/v1/messages/send \
  -H "x-api-key: msgf_live_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "instanceId": "INSTANCE_UUID",
    "to": "+33612345678",
    "type": "text",
    "text": "Hello"
  }'
```

## Messages with buttons

Messages with buttons require a WhatsApp Business account. They let you add up to 2 interactive buttons.

### Supported button types

| Type    | Description                 | Required fields                                     |
| ------- | --------------------------- | --------------------------------------------------- |
| `reply` | Quick reply button          | `displayText`, `id`                                 |
| `copy`  | Button to copy text         | `displayText`, `copyCode`                           |
| `url`   | Button that opens a URL     | `displayText`, `url`                                |
| `call`  | Button to call              | `displayText`, `phoneNumber`                        |
| `pix`   | Pix payment button (Brazil) | `displayText`, `currency`, `name`, `keyType`, `key` |

### Button message example

```bash theme={null}
curl -X POST https://srv.msgflash.com/api/v1/messages/send \
  -H "x-api-key: msgf_live_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "instanceId": "INSTANCE_UUID",
    "to": "+33612345678",
    "type": "buttons",
    "title": "Choose an option",
    "description": "What would you like to do?",
    "footer": "Reply quickly",
    "buttons": [
      {
        "title": "reply",
        "displayText": "View menu",
        "id": "menu_option"
      },
      {
        "title": "url",
        "displayText": "Visit website",
        "url": "https://example.com"
      }
    ]
  }'
```

## Success response `201`

```json theme={null}
{
  "data": {
    "id": "msg_uuid",
    "instanceId": "inst_uuid",
    "contactId": null,
    "campaignId": null,
    "type": "text",
    "to": "+33612345678",
    "body": "Hello",
    "mediaUrl": null,
    "status": "queued",
    "warnings": [
      "This instance is still in the warmup phase."
    ],
    "safety": {
      "decision": "warn",
      "riskLevel": "medium",
      "state": "warming",
      "score": 56,
      "reasons": [
        "This instance is still in the warmup phase."
      ],
      "recommendations": [
        "Start with previously engaged contacts before scaling volume."
      ]
    },
    "error": null,
    "providerMessageId": null,
    "createdAt": "2026-04-01T10:00:00.000Z",
    "updatedAt": "2026-04-01T10:00:00.000Z"
  }
}
```

<Note>
  In V1, safety warnings do not block sending. They are informational only.
</Note>

## Common errors

| HTTP  | Code                              | When                                                    |
| ----- | --------------------------------- | ------------------------------------------------------- |
| `400` | `VALIDATION_ERROR`                | Invalid body                                            |
| `400` | `TEMPLATE_INVALID`                | Template invalid                                        |
| `400` | `TEMPLATE_VARIABLES_MISSING`      | Required variables missing                              |
| `400` | `TEMPLATE_CONTEXT_UNAVAILABLE`    | Invalid contact or instance context                     |
| `403` | `SUBSCRIPTION_INACTIVE`           | Subscription not usable                                 |
| `403` | `UNSUPPORTED_FEATURE`             | Unsupported feature (buttons without WhatsApp Business) |
| `404` | `NOT_FOUND`                       | Instance, contact, or template not found                |
| `429` | `MONTHLY_OUTBOUND_QUOTA_EXCEEDED` | Sending quota exhausted                                 |
