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

# Send List

> Send an interactive menu with sections and selectable options

**Auth:** `TokenAccount` or `TokenInstance` • **Rate-limit:** `Global` (100/min) • **Idempotent:** no

## Description

Sends an **interactive list** with up to **10 sections** and **10 rows** per section (overall limit of **100 rows** across all sections). The recipient taps the button (`buttonText`) to open the menu and pick one of the options, and WhatsApp returns the `id` of the selected row as a reply message. Ideal for menus, short catalogs, guided FAQs and structured support.

## Examples

### Simple list (1 section)

A lean menu with a single "Dishes" section and two rows. The recipient taps "See options" to open the menu and select one of the options, which comes back as a reply carrying the `id` (`p1` or `p2`).

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://ryzeapi.cloud/api/message/list/$Instance_Name" \
    -H "token: $Token_Instance" \
    -H "Content-Type: application/json" \
    -d '{
      "number":      "5511999999999",
      "contentText": "Pick an item from the menu:",
      "buttonText":  "See options",
      "sections": [
        {
          "title": "Dishes",
          "rows": [
            { "id": "p1", "title": "Lasagna", "description": "Bolognese, 4 slices" },
            { "id": "p2", "title": "Risotto", "description": "Mushroom" }
          ]
        }
      ]
    }'
  ```

  ```javascript JavaScript theme={null}
  await fetch(`https://ryzeapi.cloud/api/message/list/${process.env.Instance_Name}`, {
    method: "POST",
    headers: {
      "token":        process.env.Token_Instance,
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      number:      "5511999999999",
      contentText: "Pick an item from the menu:",
      buttonText:  "See options",
      sections: [
        {
          title: "Dishes",
          rows: [
            { id: "p1", title: "Lasagna", description: "Bolognese, 4 slices" },
            { id: "p2", title: "Risotto", description: "Mushroom" }
          ]
        }
      ]
    })
  });
  ```

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

  requests.post(
      f"https://ryzeapi.cloud/api/message/list/{os.environ['Instance_Name']}",
      headers={
          "token":        os.environ["Token_Instance"],
          "Content-Type": "application/json"
      },
      json={
          "number":      "5511999999999",
          "contentText": "Pick an item from the menu:",
          "buttonText":  "See options",
          "sections": [
              {
                  "title": "Dishes",
                  "rows": [
                      {"id": "p1", "title": "Lasagna", "description": "Bolognese, 4 slices"},
                      {"id": "p2", "title": "Risotto", "description": "Mushroom"}
                  ]
              }
          ]
      }
  )
  ```

  ```go Go theme={null}
  package main

  import (
      "net/http"
      "os"
      "strings"
  )

  func main() {
      body := strings.NewReader(`{
          "number":      "5511999999999",
          "contentText": "Pick an item from the menu:",
          "buttonText":  "See options",
          "sections": [
              {
                  "title": "Dishes",
                  "rows": [
                      { "id": "p1", "title": "Lasagna", "description": "Bolognese, 4 slices" },
                      { "id": "p2", "title": "Risotto", "description": "Mushroom" }
                  ]
              }
          ]
      }`)
      req, _ := http.NewRequest("POST", "https://ryzeapi.cloud/api/message/list/"+os.Getenv("Instance_Name"), body)
      req.Header.Set("token", os.Getenv("Token_Instance"))
      req.Header.Set("Content-Type", "application/json")
      http.DefaultClient.Do(req)
  }
  ```
</CodeGroup>

### Multi-section menu (categories)

A list with multiple categories grouped into sections. Each section is rendered with its own header inside the menu, visually separating the groups.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://ryzeapi.cloud/api/message/list/$Instance_Name" \
    -H "token: $Token_Instance" \
    -H "Content-Type: application/json" \
    -d '{
      "number":      "5511999999999",
      "contentText": "Full menu. Choose an option:",
      "buttonText":  "Open menu",
      "sections": [
        {
          "title": "Main dishes",
          "rows": [
            { "id": "p1", "title": "Lasagna", "description": "Bolognese, 4 slices" },
            { "id": "p2", "title": "Risotto", "description": "Mushroom" },
            { "id": "p3", "title": "Salmon",  "description": "Grilled with vegetables" }
          ]
        },
        {
          "title": "Drinks",
          "rows": [
            { "id": "b1", "title": "Natural juice" },
            { "id": "b2", "title": "Soda" }
          ]
        },
        {
          "title": "Desserts",
          "rows": [
            { "id": "s1", "title": "Pudding" },
            { "id": "s2", "title": "Ice cream", "description": "3 flavors" }
          ]
        }
      ]
    }'
  ```

  ```javascript JavaScript theme={null}
  await fetch(`https://ryzeapi.cloud/api/message/list/${process.env.Instance_Name}`, {
    method: "POST",
    headers: {
      "token":        process.env.Token_Instance,
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      number:      "5511999999999",
      contentText: "Full menu. Choose an option:",
      buttonText:  "Open menu",
      sections: [
        {
          title: "Main dishes",
          rows: [
            { id: "p1", title: "Lasagna", description: "Bolognese, 4 slices" },
            { id: "p2", title: "Risotto", description: "Mushroom" },
            { id: "p3", title: "Salmon",  description: "Grilled with vegetables" }
          ]
        },
        {
          title: "Drinks",
          rows: [
            { id: "b1", title: "Natural juice" },
            { id: "b2", title: "Soda" }
          ]
        },
        {
          title: "Desserts",
          rows: [
            { id: "s1", title: "Pudding" },
            { id: "s2", title: "Ice cream", description: "3 flavors" }
          ]
        }
      ]
    })
  });
  ```

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

  requests.post(
      f"https://ryzeapi.cloud/api/message/list/{os.environ['Instance_Name']}",
      headers={
          "token":        os.environ["Token_Instance"],
          "Content-Type": "application/json"
      },
      json={
          "number":      "5511999999999",
          "contentText": "Full menu. Choose an option:",
          "buttonText":  "Open menu",
          "sections": [
              {
                  "title": "Main dishes",
                  "rows": [
                      {"id": "p1", "title": "Lasagna", "description": "Bolognese, 4 slices"},
                      {"id": "p2", "title": "Risotto", "description": "Mushroom"},
                      {"id": "p3", "title": "Salmon",  "description": "Grilled with vegetables"}
                  ]
              },
              {
                  "title": "Drinks",
                  "rows": [
                      {"id": "b1", "title": "Natural juice"},
                      {"id": "b2", "title": "Soda"}
                  ]
              },
              {
                  "title": "Desserts",
                  "rows": [
                      {"id": "s1", "title": "Pudding"},
                      {"id": "s2", "title": "Ice cream", "description": "3 flavors"}
                  ]
              }
          ]
      }
  )
  ```

  ```go Go theme={null}
  package main

  import (
      "net/http"
      "os"
      "strings"
  )

  func main() {
      body := strings.NewReader(`{
          "number":      "5511999999999",
          "contentText": "Full menu. Choose an option:",
          "buttonText":  "Open menu",
          "sections": [
              {
                  "title": "Main dishes",
                  "rows": [
                      { "id": "p1", "title": "Lasagna", "description": "Bolognese, 4 slices" },
                      { "id": "p2", "title": "Risotto", "description": "Mushroom" },
                      { "id": "p3", "title": "Salmon",  "description": "Grilled with vegetables" }
                  ]
              },
              {
                  "title": "Drinks",
                  "rows": [
                      { "id": "b1", "title": "Natural juice" },
                      { "id": "b2", "title": "Soda" }
                  ]
              },
              {
                  "title": "Desserts",
                  "rows": [
                      { "id": "s1", "title": "Pudding" },
                      { "id": "s2", "title": "Ice cream", "description": "3 flavors" }
                  ]
              }
          ]
      }`)
      req, _ := http.NewRequest("POST", "https://ryzeapi.cloud/api/message/list/"+os.Getenv("Instance_Name"), body)
      req.Header.Set("token", os.Getenv("Token_Instance"))
      req.Header.Set("Content-Type", "application/json")
      http.DefaultClient.Do(req)
  }
  ```
</CodeGroup>

### List with header and footer

Adds `headerText` (title above the body) and `footerText` (text in gray below the button), useful for branding and short disclaimers.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://ryzeapi.cloud/api/message/list/$Instance_Name" \
    -H "token: $Token_Instance" \
    -H "Content-Type: application/json" \
    -d '{
      "number":      "5511999999999",
      "headerText":  "RyzeAPI Support",
      "contentText": "How can we help you today?",
      "footerText":  "24/7 support",
      "buttonText":  "See options",
      "sections": [
        {
          "title": "Support",
          "rows": [
            { "id": "sup_tec",  "title": "Technical support" },
            { "id": "sup_fin",  "title": "Billing" },
            { "id": "sup_com",  "title": "Sales",   "description": "Talk to sales" }
          ]
        }
      ]
    }'
  ```

  ```javascript JavaScript theme={null}
  await fetch(`https://ryzeapi.cloud/api/message/list/${process.env.Instance_Name}`, {
    method: "POST",
    headers: {
      "token":        process.env.Token_Instance,
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      number:      "5511999999999",
      headerText:  "RyzeAPI Support",
      contentText: "How can we help you today?",
      footerText:  "24/7 support",
      buttonText:  "See options",
      sections: [
        {
          title: "Support",
          rows: [
            { id: "sup_tec", title: "Technical support" },
            { id: "sup_fin", title: "Billing" },
            { id: "sup_com", title: "Sales", description: "Talk to sales" }
          ]
        }
      ]
    })
  });
  ```

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

  requests.post(
      f"https://ryzeapi.cloud/api/message/list/{os.environ['Instance_Name']}",
      headers={
          "token":        os.environ["Token_Instance"],
          "Content-Type": "application/json"
      },
      json={
          "number":      "5511999999999",
          "headerText":  "RyzeAPI Support",
          "contentText": "How can we help you today?",
          "footerText":  "24/7 support",
          "buttonText":  "See options",
          "sections": [
              {
                  "title": "Support",
                  "rows": [
                      {"id": "sup_tec", "title": "Technical support"},
                      {"id": "sup_fin", "title": "Billing"},
                      {"id": "sup_com", "title": "Sales", "description": "Talk to sales"}
                  ]
              }
          ]
      }
  )
  ```

  ```go Go theme={null}
  package main

  import (
      "net/http"
      "os"
      "strings"
  )

  func main() {
      body := strings.NewReader(`{
          "number":      "5511999999999",
          "headerText":  "RyzeAPI Support",
          "contentText": "How can we help you today?",
          "footerText":  "24/7 support",
          "buttonText":  "See options",
          "sections": [
              {
                  "title": "Support",
                  "rows": [
                      { "id": "sup_tec", "title": "Technical support" },
                      { "id": "sup_fin", "title": "Billing" },
                      { "id": "sup_com", "title": "Sales", "description": "Talk to sales" }
                  ]
              }
          ]
      }`)
      req, _ := http.NewRequest("POST", "https://ryzeapi.cloud/api/message/list/"+os.Getenv("Instance_Name"), body)
      req.Header.Set("token", os.Getenv("Token_Instance"))
      req.Header.Set("Content-Type", "application/json")
      http.DefaultClient.Do(req)
  }
  ```
</CodeGroup>

## Success response

The returned `content` is the `contentText` you sent, and `messageType` is fixed at `list`. Store the `messageId` to correlate with the selection events that arrive via webhook.

```json 200 OK theme={null}
{
  "success": true,
  "message": "List message sent successfully",
  "status":  "sent",
  "data": {
    "messageId":   "3EB08FCF27E532F1B0F5",
    "direction":   "sent",
    "messageType": "list",
    "content":     "Pick an item from the menu:",
    "source":      "api",
    "timestamp":   "2026-04-30T14:30:00Z",
    "chat": {
      "jid":     "5511999999999@s.whatsapp.net",
      "isGroup": false
    },
    "sender": {
      "jid":      "5511777777777@s.whatsapp.net",
      "instance": "minha-instancia"
    }
  }
}
```

<Note>
  When the recipient picks an option, WhatsApp sends a reply message containing the `id` of the selected row, capture that response via webhook/websocket of events to continue the flow.
</Note>

## Path parameters

<ParamField path="instance" type="string" required>
  Instance name (e.g., `$Instance_Name`).
</ParamField>

## Headers

<ParamField header="token" type="string" required>
  `TokenAccount` or `TokenInstance`.
</ParamField>

<ParamField header="Content-Type" type="string" required>
  `application/json`
</ParamField>

## Request body

<ParamField body="number" type="string" required>
  Destination: phone (`5511999999999`) or JID (`@s.whatsapp.net`, `@lid`, `@g.us`, `@newsletter`).
</ParamField>

<ParamField body="contentText" type="string" required>
  Main body of the message (description). Appears above the button that opens the list.
</ParamField>

<ParamField body="buttonText" type="string" required>
  Text of the button that opens the list (e.g., `"See options"`, `"Open menu"`). Limited by WhatsApp to a few characters.
</ParamField>

<ParamField body="sections" type="ListSection[]" required>
  Array of **1 to 10 sections**. The total number of rows across all sections cannot exceed **100**.

  <Expandable title="ListSection">
    <ParamField body="title" type="string" required>
      Section title (group header inside the menu).
    </ParamField>

    <ParamField body="rows" type="ListRow[]" required>
      Array of **1 to 10 rows** per section.

      <Expandable title="ListRow">
        <ParamField body="id" type="string" required>
          Unique identifier of the row. It is the value that comes back as a reply when the user selects this option.
        </ParamField>

        <ParamField body="title" type="string" required>
          Title displayed for the option.
        </ParamField>

        <ParamField body="description" type="string">
          Secondary text in gray, below the title.
        </ParamField>
      </Expandable>
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="headerText" type="string">
  Title displayed above `contentText`. Optional.
</ParamField>

<ParamField body="footerText" type="string">
  Light gray text below the button. Optional, ideal for short disclaimers.
</ParamField>

<ParamField body="delay" type="int" default="0">
  Time in **seconds** to wait before sending. During the interval, the server sends the "typing..." indicator to the recipient and fires "paused" before the actual send.
</ParamField>

<ParamField body="replyTo" type="string">
  ID of the message to be quoted (reply). The original message must belong to the same instance and have been saved in the database.
</ParamField>

<ParamField body="replyPrivate" type="boolean" default="false">
  When `true` **and** `replyTo` points to a message originating from a group, the reply is redirected to the original author's **private** chat (keeping the quote).
</ParamField>

<ParamField body="source" type="string" default="api">
  Origin identifier for traceability (e.g., `crm`, `bot-suporte`, `n8n`). Saved on the message record in the database and propagated to webhooks.
</ParamField>

## Notes

<Note>
  * **WhatsApp limits:** maximum of **10 sections**, **10 rows per section** and **100 rows in total**. Exceeded? The server responds with `400` before attempting to send.
  * The row selected by the user is returned through the message event as a reply carrying the original `id`, capture this via webhook to map the choice.
  * Lists work well in DMs, groups and channels, but the UX may vary between WhatsApp Business and personal WhatsApp.
  * `description` is optional per row, but greatly improves readability when the title alone is ambiguous.
</Note>

## Errors

| HTTP | Internal status  | Message                                                      |
| ---- | ---------------- | ------------------------------------------------------------ |
| 400  | ,                | `Instance name is required`                                  |
| 400  | ,                | `Invalid request body: <detail>`                             |
| 400  | ,                | `Number is required`                                         |
| 400  | ,                | `ContentText is required`                                    |
| 400  | ,                | `ButtonText is required`                                     |
| 400  | ,                | `At least one section is required`                           |
| 400  | ,                | `Maximum of 10 sections allowed`                             |
| 400  | ,                | `Section N: Title is required`                               |
| 400  | ,                | `Section N: At least one row is required`                    |
| 400  | ,                | `Section N: Maximum of 10 rows allowed`                      |
| 400  | ,                | `Section N, Row M: ID is required`                           |
| 400  | ,                | `Section N, Row M: Title is required`                        |
| 400  | ,                | `Total number of rows across all sections cannot exceed 100` |
| 400  | `invalid_number` | `Invalid phone number format: <detail>`                      |
| 404  | ,                | `Instance not found`                                         |
| 500  | `send_failed`    | `Failed to send message: <reason>`                           |
| 503  | `disconnected`   | `Instance is not connected to WhatsApp`                      |

Error envelope:

```json theme={null}
{
  "success": false,
  "error": { "message": "ContentText is required" }
}
```
