> ## 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 Text

> Send a text message with support for delay, link preview, reply, private reply and mentions

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

## Description

Sends a text message to a 1-on-1 contact, group (`@g.us`) or channel (`@newsletter`). Supports `replyTo` (quote by ID), `replyPrivate` (reply privately to a group message), `mention` / `mentionAll` (group chats only), `linkPreview` and `delay` (in seconds) to simulate real typing. It is the most-used endpoint and serves as a "Hello World" to validate that the instance is connected.

## Examples

### Minimum

Sends a text message with the minimum payload (`number` + `message`). No `delay`, no preview, no quoting, useful as a "Hello World" to validate that the instance is connected.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://ryzeapi.cloud/api/message/text/$Instance_Name" \
    -H "token: $Token_Instance" \
    -H "Content-Type: application/json" \
    -d '{
      "number":  "5511999999999",
      "message": "Hello! This is a test of RyzeAPI."
    }'
  ```

  ```javascript JavaScript theme={null}
  await fetch(`https://ryzeapi.cloud/api/message/text/${process.env.Instance_Name}`, {
    method: "POST",
    headers: {
      "token":        process.env.Token_Instance,
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      number:  "5511999999999",
      message: "Hello! This is a test of RyzeAPI."
    })
  });
  ```

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

  requests.post(
      f"https://ryzeapi.cloud/api/message/text/{os.environ['Instance_Name']}",
      headers={
          "token":        os.environ["Token_Instance"],
          "Content-Type": "application/json"
      },
      json={
          "number":  "5511999999999",
          "message": "Hello! This is a test of RyzeAPI."
      }
  )
  ```

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

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

  func main() {
      body := strings.NewReader(`{
          "number":  "5511999999999",
          "message": "Hello! This is a test of RyzeAPI."
      }`)
      req, _ := http.NewRequest("POST", "https://ryzeapi.cloud/api/message/text/"+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>

### With delay and link preview

Sends a "typing..." indicator for 3 seconds and then sends the message with a preview of the detected URL.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://ryzeapi.cloud/api/message/text/$Instance_Name" \
    -H "token: $Token_Instance" \
    -H "Content-Type: application/json" \
    -d '{
      "number":      "5511999999999",
      "message":     "Check this out: https://ryzeapi.cloud",
      "delay":       3,
      "linkPreview": true
    }'
  ```

  ```javascript JavaScript theme={null}
  await fetch(`https://ryzeapi.cloud/api/message/text/${process.env.Instance_Name}`, {
    method: "POST",
    headers: {
      "token":        process.env.Token_Instance,
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      number:      "5511999999999",
      message:     "Check this out: https://ryzeapi.cloud",
      delay:       3,
      linkPreview: true
    })
  });
  ```

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

  requests.post(
      f"https://ryzeapi.cloud/api/message/text/{os.environ['Instance_Name']}",
      headers={
          "token":        os.environ["Token_Instance"],
          "Content-Type": "application/json"
      },
      json={
          "number":      "5511999999999",
          "message":     "Check this out: https://ryzeapi.cloud",
          "delay":       3,
          "linkPreview": True
      }
  )
  ```

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

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

  func main() {
      body := strings.NewReader(`{
          "number":      "5511999999999",
          "message":     "Check this out: https://ryzeapi.cloud",
          "delay":       3,
          "linkPreview": true
      }`)
      req, _ := http.NewRequest("POST", "https://ryzeapi.cloud/api/message/text/"+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>

### As a reply

Quotes an existing message (`replyTo` receives the `messageId` of the original). The original message must belong to the same instance and have been saved in the database (any message that flows through webhook/send is saved automatically).

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://ryzeapi.cloud/api/message/text/$Instance_Name" \
    -H "token: $Token_Instance" \
    -H "Content-Type: application/json" \
    -d '{
      "number":  "5511999999999",
      "message": "Yes, confirmed!",
      "replyTo": "3EB08FCF27E532F1B0F5"
    }'
  ```

  ```javascript JavaScript theme={null}
  await fetch(`https://ryzeapi.cloud/api/message/text/${process.env.Instance_Name}`, {
    method: "POST",
    headers: {
      "token":        process.env.Token_Instance,
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      number:  "5511999999999",
      message: "Yes, confirmed!",
      replyTo: "3EB08FCF27E532F1B0F5"
    })
  });
  ```

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

  requests.post(
      f"https://ryzeapi.cloud/api/message/text/{os.environ['Instance_Name']}",
      headers={
          "token":        os.environ["Token_Instance"],
          "Content-Type": "application/json"
      },
      json={
          "number":  "5511999999999",
          "message": "Yes, confirmed!",
          "replyTo": "3EB08FCF27E532F1B0F5"
      }
  )
  ```

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

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

  func main() {
      body := strings.NewReader(`{
          "number":  "5511999999999",
          "message": "Yes, confirmed!",
          "replyTo": "3EB08FCF27E532F1B0F5"
      }`)
      req, _ := http.NewRequest("POST", "https://ryzeapi.cloud/api/message/text/"+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>

### As a private reply (from a group)

When someone sends a message in a **group** and you want to reply **privately** to that person (without sending the reply back to the group), use `replyPrivate: true`. The `number` should point to the JID of the group where the original message was sent, the server extracts the original author and redirects the reply to their private chat, keeping the quote.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://ryzeapi.cloud/api/message/text/$Instance_Name" \
    -H "token: $Token_Instance" \
    -H "Content-Type: application/json" \
    -d '{
      "number":       "120363406289005073@g.us",
      "message":      "Replying to you privately so we don't clutter the group.",
      "replyTo":      "3EB08FCF27E532F1B0F5",
      "replyPrivate": true
    }'
  ```

  ```javascript JavaScript theme={null}
  await fetch(`https://ryzeapi.cloud/api/message/text/${process.env.Instance_Name}`, {
    method: "POST",
    headers: {
      "token":        process.env.Token_Instance,
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      number:       "120363406289005073@g.us",
      message:      "Replying to you privately so we don't clutter the group.",
      replyTo:      "3EB08FCF27E532F1B0F5",
      replyPrivate: true
    })
  });
  ```

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

  requests.post(
      f"https://ryzeapi.cloud/api/message/text/{os.environ['Instance_Name']}",
      headers={
          "token":        os.environ["Token_Instance"],
          "Content-Type": "application/json"
      },
      json={
          "number":       "120363406289005073@g.us",
          "message":      "Replying to you privately so we don't clutter the group.",
          "replyTo":      "3EB08FCF27E532F1B0F5",
          "replyPrivate": True
      }
  )
  ```

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

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

  func main() {
      body := strings.NewReader(`{
          "number":       "120363406289005073@g.us",
          "message":      "Replying to you privately so we don't clutter the group.",
          "replyTo":      "3EB08FCF27E532F1B0F5",
          "replyPrivate": true
      }`)
      req, _ := http.NewRequest("POST", "https://ryzeapi.cloud/api/message/text/"+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>

### With member mention(s) (group)

Adds visible mentions with `@5511...` in the message body and lists the numbers in the `mention` array. The text and the array must be **consistent**, WhatsApp only turns into a clickable link what is in `mention`.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://ryzeapi.cloud/api/message/text/$Instance_Name" \
    -H "token: $Token_Instance" \
    -H "Content-Type: application/json" \
    -d '{
      "number":  "120363406289005073@g.us",
      "message": "Heads up @5511888888888 and @5511777777777, meeting at 2pm.",
      "mention": ["5511888888888", "5511777777777"]
    }'
  ```

  ```javascript JavaScript theme={null}
  await fetch(`https://ryzeapi.cloud/api/message/text/${process.env.Instance_Name}`, {
    method: "POST",
    headers: {
      "token":        process.env.Token_Instance,
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      number:  "120363406289005073@g.us",
      message: "Heads up @5511888888888 and @5511777777777, meeting at 2pm.",
      mention: ["5511888888888", "5511777777777"]
    })
  });
  ```

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

  requests.post(
      f"https://ryzeapi.cloud/api/message/text/{os.environ['Instance_Name']}",
      headers={
          "token":        os.environ["Token_Instance"],
          "Content-Type": "application/json"
      },
      json={
          "number":  "120363406289005073@g.us",
          "message": "Heads up @5511888888888 and @5511777777777, meeting at 2pm.",
          "mention": ["5511888888888", "5511777777777"]
      }
  )
  ```

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

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

  func main() {
      body := strings.NewReader(`{
          "number":  "120363406289005073@g.us",
          "message": "Heads up @5511888888888 and @5511777777777, meeting at 2pm.",
          "mention": ["5511888888888", "5511777777777"]
      }`)
      req, _ := http.NewRequest("POST", "https://ryzeapi.cloud/api/message/text/"+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>

### Hidden mention (group)

**Pings every member of the group** without listing @s in the text, using `mentionAll: true`. The displayed text stays clean, but the participants receive the mention notification. Useful for silent announcements. To mention specific people in a hidden way, just use `mention: ["..."]` **without** placing `@number` in the text, they will also receive the notification without appearing tagged.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://ryzeapi.cloud/api/message/text/$Instance_Name" \
    -H "token: $Token_Instance" \
    -H "Content-Type: application/json" \
    -d '{
      "number":     "120363406289005073@g.us",
      "message":    "General notice: meeting confirmed for tomorrow at 2pm.",
      "mentionAll": true
    }'
  ```

  ```javascript JavaScript theme={null}
  await fetch(`https://ryzeapi.cloud/api/message/text/${process.env.Instance_Name}`, {
    method: "POST",
    headers: {
      "token":        process.env.Token_Instance,
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      number:     "120363406289005073@g.us",
      message:    "General notice: meeting confirmed for tomorrow at 2pm.",
      mentionAll: true
    })
  });
  ```

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

  requests.post(
      f"https://ryzeapi.cloud/api/message/text/{os.environ['Instance_Name']}",
      headers={
          "token":        os.environ["Token_Instance"],
          "Content-Type": "application/json"
      },
      json={
          "number":     "120363406289005073@g.us",
          "message":    "General notice: meeting confirmed for tomorrow at 2pm.",
          "mentionAll": True
      }
  )
  ```

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

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

  func main() {
      body := strings.NewReader(`{
          "number":     "120363406289005073@g.us",
          "message":    "General notice: meeting confirmed for tomorrow at 2pm.",
          "mentionAll": true
      }`)
      req, _ := http.NewRequest("POST", "https://ryzeapi.cloud/api/message/text/"+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 response includes the `messageId` (use it in `replyTo` to quote this message in future sends), `direction: "outgoing"` and the chat/sender markers. The `mentions` and `replyTo` fields only appear when applicable, and `chat.groupName` is included in group messages.

```json 200 OK theme={null}
{
  "success": true,
  "message": "Message sent successfully",
  "status":  "sent",
  "data": {
    "messageId":   "3EB08FCF27E532F1B0F5",
    "direction":   "outgoing",
    "messageType": "text",
    "content":     "Hello! This is a test of RyzeAPI.",
    "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"
    },
    "mentions": {
      "mentionedUsers": ["5511888888888"],
      "mentionAll":     false,
      "totalMentions":  1
    },
    "replyTo": {
      "messageId": "3EB08FCF27E532F1A1A1",
      "content":   "Are we good for tomorrow?"
    }
  }
}
```

## 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="message" type="string" required>
  Body text. Cannot be empty.
</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="linkPreview" type="boolean" default="false">
  When `true`, the server extracts the first URL from `message`, fetches Open Graph metadata (title, description, thumbnail) and sends the message as `ExtendedTextMessage` with the preview card embedded. When `false` or omitted, the URL appears as plain text.
</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. Possible errors: `reply_message_not_found`, `reply_message_instance_mismatch`.
</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). Useful for answering questions individually without cluttering the group. Ignored if the original message is not from a group.
</ParamField>

<ParamField body="mention" type="string[]">
  List of numbers (or JIDs) to mention. **Group chats only** (`@g.us`). Limit of **10** mentions per message; excess numbers are ignored with a warning. To appear as a clickable link, include `@5511...` in `message`. Without that, they become hidden mentions (notify only).
</ParamField>

<ParamField body="mentionAll" type="boolean" default="false">
  When `true`, mentions **every group member** (except the instance itself). Equivalent to `@everyone`. The server queries the participants list and injects each JID into the context's `MentionedJID`, without changing the displayed text. **Group chats only.**
</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. When omitted, defaults to `"api"`.
</ParamField>

## Notes

<Note>
  * **`delay` is in seconds** (unlike many APIs that use ms). A value of `3` = 3 seconds of "typing".
  * In groups, text with `@5511...` alone **does not become clickable**, it is the `mention` array that WhatsApp processes. Keep both consistent.
  * `mention` **and** `mentionAll` are exclusive to groups. If sent to a DM/channel, the response is `400 Mentions are only supported in group chats`.
  * For BR numbers (starting with `55`), the service automatically tries variations with and without the 9th digit, avoiding the long-standing inconsistency in older area codes.
  * `linkPreview` requires that the server be able to fetch the URL's Open Graph metadata; sites with bot blocking may fall back to plain text without a visible error.
  * Messages sent via `replyPrivate: true` appear in the recipient's private chat with the card of the quoted group message, they can see which conversation it came from.
</Note>

## Errors

| HTTP | Internal status                   | Message                                             |
| ---- | --------------------------------- | --------------------------------------------------- |
| 400  | ,                                 | `Instance name is required`                         |
| 400  | ,                                 | `Invalid request body: <detail>`                    |
| 400  | ,                                 | `Number is required`                                |
| 400  | ,                                 | `Message is required`                               |
| 400  | `invalid_number`                  | `Invalid phone number format: <detail>`             |
| 400  | `mentions_not_supported`          | `Mentions are only supported in group chats`        |
| 400  | `reply_message_not_found`         | `Original message not found (ID: ...)`              |
| 400  | `reply_message_instance_mismatch` | `Original message does not belong to this instance` |
| 400  | `private_reply_failed`            | (reason for the private redirection error)          |
| 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": "Message is required" }
}
```
