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

# WhatsApp Templates

> Create, list, and send approved WhatsApp templates through connected Visito channels.

Use the WhatsApp Templates API for proactive messages that must use Meta-approved templates: booking confirmations, check-in instructions, payment reminders, door codes, and other transactional workflows.

All endpoints use the M2M base URL:

```bash theme={null}
https://platform-api.visitoai.com/m2m/v1
```

## Requirements

* A connected, active WhatsApp channel using the Meta provider.
* The channel must have Meta `wabaId`, `phoneNumberId`, and access token details configured in Visito.
* An M2M credential with the template scopes you need.
* `Idempotency-Key` on template send requests.

Use `GET /m2m/v1/channels` to find the `channelId` for the WhatsApp number you want to send from.

## List Templates

```http theme={null}
GET /m2m/v1/whatsapp-templates/{channelId} HTTP/1.1
Host: platform-api.visitoai.com
Authorization: Bearer visito_m2m_...
Accept: application/json
```

Requires the `whatsapp_templates:read` scope.

```json theme={null}
{
  "templates": [
    {
      "id": "1234567890",
      "name": "reservation_confirmed",
      "status": "APPROVED",
      "language": "en_US",
      "category": "UTILITY",
      "components": [
        {
          "type": "BODY",
          "text": "Hi {{1}}, your reservation is confirmed."
        }
      ]
    }
  ]
}
```

## Create a Template

```http theme={null}
POST /m2m/v1/whatsapp-templates/{channelId} HTTP/1.1
Host: platform-api.visitoai.com
Authorization: Bearer visito_m2m_...
Content-Type: application/json
```

Requires `whatsapp_templates:write`.

`template.name` must use lowercase letters, numbers, and underscores. `template.category` must be `UTILITY`, `MARKETING`, or `AUTHENTICATION`.

```json theme={null}
{
  "template": {
    "name": "reservation_confirmed",
    "language": "en_US",
    "category": "UTILITY",
    "components": [
      {
        "type": "BODY",
        "text": "Hi {{1}}, your reservation is confirmed.",
        "example": {
          "body_text": [["Sofia"]]
        }
      }
    ]
  }
}
```

```json theme={null}
{
  "template": {
    "id": "1234567890",
    "name": "reservation_confirmed",
    "status": "PENDING",
    "language": "en_US",
    "category": "UTILITY",
    "components": [
      {
        "type": "BODY",
        "text": "Hi {{1}}, your reservation is confirmed."
      }
    ]
  }
}
```

Templates must be approved by Meta before they can be sent.

## Send a Template

```http theme={null}
POST /m2m/v1/whatsapp-templates/{channelId}/send HTTP/1.1
Host: platform-api.visitoai.com
Authorization: Bearer visito_m2m_...
Idempotency-Key: booking-123-confirmation
Content-Type: application/json
```

Requires `whatsapp_templates:send`.

```json theme={null}
{
  "to": "+525512345678",
  "template": {
    "name": "reservation_confirmed",
    "language": {
      "code": "en_US"
    },
    "components": [
      {
        "type": "body",
        "parameters": [
          {
            "type": "text",
            "text": "Sofia"
          }
        ]
      }
    ]
  }
}
```

If accepted, Visito queues the send and returns `202 Accepted`.

```json theme={null}
{
  "accepted": true,
  "conversationId": "conv_...",
  "conversationKey": "tenant_...:whatsapp:525512345678:phone_number_id",
  "replyId": "reply_...",
  "requestEventId": "event_...",
  "correlationId": "corr_...",
  "status": "queued",
  "acceptedAt": "2026-07-12T00:00:00.000Z"
}
```

Template sends are asynchronous. The API response confirms Visito accepted and queued the outbound work; it does not return the raw Meta send response.

## Send Rules

* The template must exist for the requested language.
* The template status must be `APPROVED`.
* `REJECTED`, `PENDING`, or in-review templates cannot be sent.
* `to` can include formatting such as `+`, spaces, or punctuation; Visito normalizes it to WhatsApp digits.
* Reusing the same `Idempotency-Key` for the same recipient conversation returns the original accepted send instead of creating a duplicate.
* Each WhatsApp channel is limited to 100 template sends per rolling 24-hour window through this API. When the limit is reached, Visito returns `429` with retry details.

## Common Errors

| Code                                       | Meaning                                                  |
| ------------------------------------------ | -------------------------------------------------------- |
| `WHATSAPP_TEMPLATES_CHANNEL_NOT_FOUND`     | The channel does not belong to the authenticated tenant. |
| `WHATSAPP_TEMPLATES_UNSUPPORTED_CHANNEL`   | The channel is not a WhatsApp Meta channel.              |
| `WHATSAPP_TEMPLATES_CHANNEL_NOT_READY`     | The channel is missing Meta connection details.          |
| `WHATSAPP_TEMPLATES_TEMPLATE_NOT_FOUND`    | No template exists with that name and language.          |
| `WHATSAPP_TEMPLATES_TEMPLATE_NOT_APPROVED` | The template exists but is not approved by Meta.         |
| `WHATSAPP_TEMPLATE_SEND_LIMIT_24H_REACHED` | The channel reached the 24-hour template send limit.     |

Rate-limit responses include the wait time in seconds:

```json theme={null}
{
  "error": {
    "code": "WHATSAPP_TEMPLATE_SEND_LIMIT_24H_REACHED",
    "message": "WhatsApp template send limit reached for this channel.",
    "details": {
      "retryAfterSeconds": 3600
    }
  }
}
```

Retry the exact same send body with the same `Idempotency-Key` after the wait period. A replay returns the identifiers from the original accepted operation.
