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

# Webchat

> How to use the Connecta DESK webchat through the API: send messages to visitors, including interactive messages, and chat as a visitor from your own system.

The webchat is a channel like the others: each company webchat has a `channelId` (see
`GET /webchat` or `GET /channels`) and its conversations land in the inbox. Through the API you do
two things with it:

<Columns cols={2}>
  <Card title="Talk to the visitor" icon="send">
    The company sends messages to whoever is on the webchat, with `POST /messages`, including
    interactive messages. `messages` module.
  </Card>

  <Card title="Be the visitor" icon="messages-square">
    Your system opens a session for one of your users, sends their messages and reads the team's
    replies. `webchat` module.
  </Card>
</Columns>

## Send to a visitor

A webchat visitor does not need a phone number, so the recipient is the `ticketId` of a
conversation or the `contactId` of someone who has already opened this webchat:

```bash theme={null}
curl --request POST \
  --url "$CONNECTA_URL/messages" \
  --header "Authorization: Bearer $CONNECTA_TOKEN" \
  --header "Content-Type: application/json" \
  --header "Idempotency-Key: order-88213-notice" \
  --data '{
    "channelId": 11,
    "type": "text",
    "contactId": 842,
    "body": "Hi, Maria! Your order is out for delivery."
  }'
```

A contact who has never opened this webchat gets `422 ERR_API_CONTACT_UNREACHABLE`. The rest of
the send works like the other channels: `202` with a `jobId`, and the job lookup at
`GET /messages/jobs/{jobId}`. See [Send messages](/en/guides/enviar-mensagens).

<Note>
  The webchat does not use templates. `type: template` only applies to official WhatsApp channels.
</Note>

## Interactive messages

The webchat shows the visitor the same interactive messages as the official WhatsApp API, with the
same `interactive` object: the payload you already send to official WhatsApp works on the webchat
with no changes. Only the `channelId` and the recipient change.

| `type` | What the visitor sees |
| - | - |
| `button` | Up to 3 reply buttons, with an optional header (text, image, video or document) and footer. |
| `list` | A button that opens the list of options, organized in sections, with descriptions. |
| `cta_url` | A button that opens the link in a new tab. |
| `location_request_message` | A button that asks the browser for the location and sends it. |
| `carousel` | Side-by-side cards, each with an image or video, text and one link button or reply buttons. |

`flow`, `product`, `product_list`, `catalog_message`, `address_message`, `voice_call` and
`call_permission_request` depend on Meta resources and do not exist on the webchat.

```json theme={null}
{
  "channelId": 11,
  "type": "interactive",
  "contactId": 842,
  "interactive": {
    "type": "list",
    "header": { "type": "text", "text": "Menu" },
    "body": { "text": "What would you like to order?" },
    "footer": { "text": "Delivery within 40 min" },
    "action": {
      "button": "See menu",
      "sections": [
        {
          "title": "Burgers",
          "rows": [
            { "id": "cheeseburger", "title": "Cheeseburger", "description": "Bun, patty and cheese" },
            { "id": "salad-burger", "title": "Salad burger" }
          ]
        },
        { "title": "Drinks", "rows": [{ "id": "juice", "title": "Fresh juice" }] }
      ]
    }
  }
}
```

On the webchat, `interactive` is checked during the call itself, with the WhatsApp limits
(3 buttons, 10 rows, 20- or 24-character titles and the others, listed in the `interactive` field of
`POST /messages`). Outside them, the response is a `422` right away, with the field and the reason
in `message`:

```json theme={null}
{
  "error": {
    "code": "ERR_API_INTERACTIVE_INVALID",
    "message": "interactive.action.buttons: de 1 a 3 botões"
  }
}
```

<Warning>
  Header and card media only by a public `http` or `https` `link`. The webchat does not use media
  uploaded to Meta (`id`).
</Warning>

### The visitor's reply

The choice arrives as it does on WhatsApp: a text message from the visitor with the option
**title**, replying to (quoting) the interactive message. A location arrives like a WhatsApp
location, with `mediaType: locationMessage`. If you follow the conversation with
`GET /tickets/{ticketId}/messages`, nothing changes compared to WhatsApp.

## Chat as the visitor

With the `webchat` module, your system plays the visitor's part: for example, your own app that
shows the support conversation inside it.

<Steps>
  <Step title="Open the session">
    Use the webchat `slug` (from `GET /webchat`). With `externalId`, the same person always returns
    to the same session and the same contact.

    ```bash theme={null}
    curl --request POST \
      --url "$CONNECTA_URL/webchat/site-institucional-3f9a/sessions" \
      --header "Authorization: Bearer $CONNECTA_TOKEN" \
      --header "Content-Type: application/json" \
      --data '{
        "externalId": "user-1029",
        "visitor": { "name": "Maria Souza", "email": "maria@email.com" }
      }'
    ```

    Keep the `session.id`. The response also includes a `visitorToken`, which your front end uses
    to receive messages in real time (`/webchat`, Socket.IO, `auth: { token }`) without exposing
    the API token.
  </Step>

  <Step title="Send the visitor's messages">
    ```bash theme={null}
    curl --request POST \
      --url "$CONNECTA_URL/webchat/site-institucional-3f9a/sessions/$SESSION/messages" \
      --header "Authorization: Bearer $CONNECTA_TOKEN" \
      --header "Content-Type: application/json" \
      --data '{ "text": "Hi, I would like a quote" }'
    ```

    The first message opens the ticket in the webchat queue. A file goes as
    `multipart/form-data`, in the `media` field.
  </Step>

  <Step title="Read the replies">
    Without real time, poll with `after` set to the `createdAt` of the last message received:

    ```bash theme={null}
    curl --request GET \
      --url "$CONNECTA_URL/webchat/site-institucional-3f9a/sessions/$SESSION/messages?after=2026-10-01T13:45:00.000Z" \
      --header "Authorization: Bearer $CONNECTA_TOKEN"
    ```

    Mark messages as read with `POST /webchat/{slug}/sessions/{sessionId}/read` and close the
    session with `POST /webchat/{slug}/sessions/{sessionId}/close`.
  </Step>
</Steps>

### Reply to an interactive message

In the company's interactive messages, `interactive` has what to render (type, header, body,
footer and the options) and `options` lists the reply options with `id` and `title`. To choose one,
send the message `id` and the option `id`:

```json theme={null}
{ "interactiveReply": { "messageId": "6f1d2c1e-8a8b-4f35-a1e6-1f2f3c4d5e6f", "optionId": "cheeseburger" } }
```

The saved title comes from the message itself: there is no need, and no way, to send a different
one. An option that is not in the message gets `422 ERR_WEBCHAT_INTERACTIVE_REPLY_INVALID`.

For a location request (`interactive.type: location_request`), send the coordinates, quoting the
request:

```json theme={null}
{
  "location": { "latitude": -23.561399, "longitude": -46.656571 },
  "quotedMessageId": "6f1d2c1e-8a8b-4f35-a1e6-1f2f3c4d5e6f"
}
```

Any message can reply to another one with `quotedMessageId`.

<CardGroup cols={2}>
  <Card title="Send messages" icon="send" href="/en/guides/enviar-mensagens">
    The four send types, the `jobId` and the job states.
  </Card>

  <Card title="Errors" icon="triangle-alert" href="/en/essentials/erros">
    The webchat and message codes.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.