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

# Send WhatsApp Messages with RelayOS

> Step-by-step guide to sending transactional WhatsApp messages using the POST /v1/messages endpoint, with template variables and status tracking.

The `POST /v1/messages` endpoint is how you send a WhatsApp message through RelayOS. Every message is built on a Meta-approved template — you select the template by name, supply your recipient's phone number, and optionally pass dynamic variable values to personalize the content. RelayOS queues the request, delivers it via the official WhatsApp Cloud API, and gives you a message ID you can use to track delivery in real time.

## Request parameters

<ParamField body="to" type="string" required>
  The recipient's phone number in [E.164 format](https://en.wikipedia.org/wiki/E.164), including the country code. Example: `+5511999998888`.
</ParamField>

<ParamField body="template" type="string" required>
  The exact name of a Meta-approved template registered in your account. Example: `lembrete_consulta`. Template names are case-sensitive.
</ParamField>

<ParamField body="language" type="string" required>
  The BCP 47 language code for the template. Must match the language the template was approved in. Common values: `pt_BR`, `en_US`.
</ParamField>

<ParamField body="variables" type="object">
  An object mapping numbered string keys to their replacement values for template placeholders. Keys start at `"1"` and match the order of `{{1}}`, `{{2}}`, … in your template body. Example: `{"1": "João", "2": "14h"}`.
</ParamField>

## Send a message

The example below sends a consultation reminder with three dynamic variables filled in.

<Info>
  Include an `Idempotency-Key` header on every request to prevent duplicate messages if your client retries due to a network error. RelayOS returns the original response for any repeated key. See [Use Idempotency Keys](/guides/idempotency) for details.
</Info>

```bash theme={null}
curl -X POST https://api.relayos.com.br/v1/messages \
  -H "Authorization: Bearer rly_live_xxx..." \
  -H "Idempotency-Key: pedido-42-lembrete" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "+5511999998888",
    "template": "lembrete_consulta",
    "language": "pt_BR",
    "variables": {
      "1": "João Silva",
      "2": "14h",
      "3": "Dra. Helena"
    }
  }'
```

## Response

A successful request returns `202 Accepted` with a JSON body confirming the message has been queued.

```json theme={null}
{
  "id": "msg_01hwz3k8j2fxqbv9r4tp6d",
  "status": "QUEUED",
  "to": "+5511999998888",
  "template": "lembrete_consulta",
  "queuedAt": "2026-05-14T10:30:00Z"
}
```

### Response fields

<ResponseField name="id" type="string" required>
  Unique identifier for this message. Use it to query status with `GET /v1/messages/{id}` or to correlate webhook events.
</ResponseField>

<ResponseField name="status" type="string" required>
  Initial delivery status. Always `QUEUED` immediately after a successful request.
</ResponseField>

<ResponseField name="to" type="string" required>
  The recipient phone number, echoed back in E.164 format.
</ResponseField>

<ResponseField name="template" type="string" required>
  The template name used for this message.
</ResponseField>

<ResponseField name="queuedAt" type="string" required>
  ISO 8601 timestamp of when RelayOS accepted and queued the message.
</ResponseField>

## Message status lifecycle

After a message is queued, RelayOS advances its status as it moves through the delivery pipeline. You can track these changes in real time by configuring a [webhook](/guides/webhooks).

```
QUEUED → SENT → DELIVERED → READ
              ↘
              FAILED
```

| Status      | Meaning                                                                                          |
| ----------- | ------------------------------------------------------------------------------------------------ |
| `QUEUED`    | RelayOS accepted the request and is forwarding it to Meta.                                       |
| `SENT`      | Meta confirmed the message left their servers.                                                   |
| `DELIVERED` | The message arrived on the recipient's device.                                                   |
| `READ`      | The recipient opened the message.                                                                |
| `FAILED`    | All delivery attempts failed. RelayOS retried with exponential backoff before marking it failed. |

<Note>
  A `FAILED` status means all automatic retries were exhausted. Check the webhook payload for an error code from Meta, then determine whether to re-send the message.
</Note>
