---
title: "Allow anonymous chat, or require a sign-in"
description: "Choose between letting visitors chat straight away and requiring a sign-in, learn why the pre-chat form is not an identity, and hand over a verified session."
updated: "2026-08-28"
audience: [administrator]
source: "https://helpdesk-docs.svr1.feedapp.click/en/widget/chat-an-danh-hay-bat-dang-nhap"
---

The **Who can chat** section asks one question: must a visitor say who they are
before chatting, and by what means. Your answer decides whether the data
attached to a conversation can be trusted.

## Goal [#goal]

The channel runs in exactly one of two modes — anonymous chat, or a required
sign-in — and you know how far the data in each mode can be trusted.

## Before you begin [#before-you-begin]

* The administrator role, or another role placed in a permission group that allows channel edits.
* If you plan to require a sign-in: the address of your own log-in page, and a developer who can connect your backend to api-engine.
* The `INTERNAL_API_TOKEN` environment variable set on api-engine. While it is unset that server-to-server door answers `404` rather than opening.
* Read [Roles and per-feature permissions](/en/khai-niem/vai-tro-va-quyen) if you are unsure your account may edit a channel.

## Steps [#steps]

1. In the left column press **Channels**, open the website widget channel, pick the
   **Configuration** tab and go to **Who can chat**.

   ![The Who can chat section of the Configuration tab: the Allow chatting anonymously switch is on, and below it, indented behind a vertical rule, the Enable Pre-Chat Form switch](https://helpdesk-docs.svr1.feedapp.click/images/docs/widget/chat-an-danh-hay-bat-dang-nhap/01-ai-duoc-chat.en.webp)

   *The pre-chat form lives inside the branch that allows anonymous chat.*
2. Leave **Allow chatting anonymously** on if visitors may chat without saying
   anything about themselves. That is the default for a new channel.
3. To ask for details before the first message, turn on **Enable Pre-Chat Form**.
   Three further switches appear underneath.
4. Choose among **Require Name**, **Require Email** and **Require Phone Number**.
   All three fields are always offered; these switches decide which of them a
   visitor cannot skip.
5. When you need an identity you can trust, turn **Allow chatting anonymously**
   off. The form disappears and a **Log-in page** field takes its place.
6. Fill in **Log-in page** with an address starting `https://`. The console refuses
   to save while that field is empty or malformed.
7. Arrange the session handover on your own site, following the two snippets below.
   Without that step a customer can sign in and still not be able to chat.
8. Press **Save Settings**.

> **Warning:** **The pre-chat form collects, it does not verify.** A visitor can type any
> name and any address, and nothing checks them. The session the form opens is
> an ordinary anonymous one. Never use those values to look up an account,
> confirm an order or reveal anything belonging to another customer.

## Handing over a verified session [#handing-over-a-verified-session]

Only the sign-in mode gives you a trustworthy identity, and it travels through
your backend rather than through the browser. Once your backend has
authenticated the person, it calls the server-to-server door on api-engine:

```bash
curl -X POST "https://<your-api>/internal/widget-sessions" \
  -H "X-Internal-Token: <INTERNAL_API_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{ "inbox_id": <INBOX_ID>, "identifier": "cloudfly:1234567", "email": "person@example.com" }'
```

The response carries a `widget_token`. Your page hands it to the widget, and
clears it when the person signs out:

```js
window.CustomChatSDK.identify({ widget_token: "<WIDGET_TOKEN>" });

// On sign-out. Widget tokens outlive a browsing session, so skipping this
// leaves the next person at a shared machine holding the same conversation.
window.CustomChatSDK.reset();
```

> **Note:** The two modes are mutually exclusive, and the console nests the form inside
> the anonymous branch so you cannot switch both on. The reason: while the
> channel requires a sign-in, the anonymous door
> `POST /widgets/:inbox_id/contacts` answers `403` — and that is exactly where
> the form posts. Both enabled would ask a visitor for name, email and phone
> and then fail every submit.

## Verify [#verify]

In anonymous mode with the form on, open the widget in a private browser window.
The form must appear before the composer, and every field you marked required
carries a red asterisk on its label.

In sign-in mode, open the widget while signed out: the chat entry is replaced by
a **Log in to chat** button pointing at the page you declared. Sign in on your
site and reopen the widget: the composer must open, and that person's earlier
conversations must come back.

## Troubleshooting [#troubleshooting]

| Symptom                                                            | Cause                                                                                     | What to do                                        |
| ------------------------------------------------------------------ | ----------------------------------------------------------------------------------------- | ------------------------------------------------- |
| **Save Settings** does nothing and **Log-in page** turns red       | Anonymous chat is off and no log-in page was declared                                     | Enter an address starting `https://`              |
| The visitor signs in and the widget still shows the log-in button  | Your site never called `identify()` with the token the backend fetched                    | Add the session handover described above          |
| Your backend gets `404` from `/internal/widget-sessions`           | `INTERNAL_API_TOKEN` is unset on api-engine, so that door behaves as if it does not exist | Set the variable and restart api-engine           |
| Your backend gets `403` from the same call                         | The `X-Internal-Token` header carries the wrong value                                     | Compare it against api-engine's environment       |
| The next person on a shared machine sees the previous conversation | The site never calls `reset()` on sign-out                                                | Call `CustomChatSDK.reset()` in the sign-out path |

## Next steps [#next-steps]

* [Embed the widget on your website](/en/widget/nhung-vao-website)
* [Add Zalo, Messenger and a hotline](/en/widget/kenh-lien-he-khac)
* [Roles and per-feature permissions](/en/khai-niem/vai-tro-va-quyen)
