# Tolkly > AI support chat for online businesses. It answers from the site's own pages with a source in every answer, and hands what it cannot answer to operators in Telegram or a web inbox. The widget is one script tag; its settings come from the server. The widget endpoint is https://api.tolkly.io. These docs describe the version served at https://tolkly.io. Every page has a Markdown twin: add .md to its address, or send Accept: text/markdown. ## Product - [Tolkly home page](https://tolkly.io/): what Tolkly is, the price compared with Jivo and Intercom, a live demo on your own site - [Questions and answers](https://tolkly.io/faq): price, what counts as an AI conversation, how answers are checked, handoff, Jivo and Intercom - [Articles (in Russian)](https://tolkly.io/blog): Tolkly compared with Jivo, Intercom and other chats, and what an AI support chat changes - [Articles (in Russian)](https://tolkly.io/ru/blog): Tolkly compared with Jivo, Intercom and other chats, and what an AI support chat changes - [Tolkly vs Intercom Fin: a Fin alternative without per-outcome fees](https://tolkly.io/vs/intercom): Tolkly vs Intercom Fin: seats from $29 plus $0.99 per Fin outcome against Tolkly's $49 a month for everything. Costs for 3 and 8 operators, with sources. - [Tolkly или Intercom Fin: альтернатива Fin с ценой без оплаты за исходы](https://tolkly.io/ru/vs/intercom): Tolkly и Intercom Fin: место от $29 плюс $0,99 за исход Fin против $49 в месяц за всё у Tolkly. Расчёт на 3 и 8 операторов, источники, русский интерфейс. - [Tolkly или Jivo: чат с ИИ для сайта без платы за каждого оператора](https://tolkly.io/ru/vs/jivo): Tolkly и Jivo: цены на 2026 год, ИИ-оператор Jivo за 12 990 ₽ против ИИ в тарифе Tolkly от $49, ответы с цитатой из источника, расчёт на 3 и 8 операторов. - [Tolkly, Verbox, Carrot quest или Talk-Me: какой онлайн-чат с ИИ выбрать в 2026](https://tolkly.io/ru/vs/verbox-carrot-quest-talk-me): Сравнение Tolkly с Verbox, Carrot quest и Talk-Me: цены на 2026 год, как устроен ИИ, где отвечают операторы, расчёт на 3 и 8 операторов. - [How AI support chats read your site: Intercom, Zendesk, Chatwoot, Crisp and Tolkly](https://tolkly.io/blog/ai-chat-reads-your-site): Which AI chats read a site by sitemap and links, how often they read it again, what they do with menus, robots.txt and JavaScript, and what to check before launch. - [How an AI support chat affects conversion and the load on operators](https://tolkly.io/blog/ai-chat-conversion): What research says about response time, questions after hours and the share of conversations AI closes, and how to measure it on your own site. - [How to answer website chats from Telegram](https://tolkly.io/blog/operators-in-telegram): How operators answer site visitors from the company's Telegram group in Tolkly: a topic per conversation, shifts, files, and why it beats a separate app. - [What an AI support chat costs and how a hard cap on the bill works](https://tolkly.io/blog/ai-chat-cost-cap): Why paying per seat and per AI outcome grows the bill, how Tolkly's hard cap works, and a worked example for 3,000 conversations a month. - [Why support bots make up prices and deadlines, and how to prevent it](https://tolkly.io/blog/ai-hallucinations-support): Real cases of support chatbots inventing rules, why it happens, and how a quoted answer, a check in code and an honest refusal prevent it. - [Альтернативы Jivo в 2026: 6 онлайн-чатов с ИИ для сайта](https://tolkly.io/ru/blog/jivo-alternatives): Чем заменить Jivo в 2026: Tolkly, Carrot quest, Verbox, Talk-Me, Intercom Fin и Chatwoot. Цены с датами и источниками, сильные стороны каждого, расчёт на 3 и 8 операторов. - [Как ИИ-чат поддержки влияет на конверсию и нагрузку на операторов](https://tolkly.io/ru/blog/ai-chat-conversion): Что говорят исследования о скорости ответа, вопросах в нерабочее время и доле разговоров, которые закрывает ИИ, и как это измерить на своём сайте. - [Как ИИ-чаты поддержки читают ваш сайт: Intercom, Zendesk, Chatwoot, Crisp, Jivo и Tolkly](https://tolkly.io/ru/blog/ai-chat-reads-your-site): Кто из ИИ-чатов читает сайт по sitemap и ссылкам, как часто перечитывает, что делает с меню, robots.txt и JavaScript, и что проверить до запуска. - [Как отвечать на чаты с сайта из Telegram](https://tolkly.io/ru/blog/operators-in-telegram): Как операторы отвечают посетителям сайта из Telegram-группы компании в Tolkly: тема на разговор, смены, файлы, и почему это удобнее приложения. - [Почему бот поддержки выдумывает цены и сроки и как это предотвратить](https://tolkly.io/ru/blog/ai-hallucinations-support): Реальные случаи, когда чат-бот поддержки выдумал правила, почему так происходит и как ответ с цитатой, проверкой кодом и честным отказом это предотвращает. - [Сколько стоит ИИ-чат поддержки и как работает жёсткий потолок счёта](https://tolkly.io/ru/blog/ai-chat-cost-cap): Почему оплата за операторов и за исходы ИИ растит счёт, как работает жёсткий потолок в Tolkly и пример расчёта для 3 000 разговоров в месяц. Plans: Start $49 a month (up to 10 operators, 1,000 AI conversations), Business $149 (operators without limit, 5,000 AI conversations); the first month is free. At the limit the bot hands conversations to operators and never charges extra. --- # Install on a site > Where the two lines go and how to check that the chat is live. The chat is a web component. You add two lines to the layout all your pages share. Everything else comes from the Tolkly server. ## The two lines ```html ``` Replace `your-project` with the project's id. In the app, open the project's «Install» section, block «Install on your site». The lines are there with the id filled in, next to a «Copy the code» button. - `widget.js` is about a kilobyte: it loads the chat from `https://api.tolkly.io`, and if the chat has not come up within 2.5 s, from our next address ([visitors in Russia](#russia)). - The tag needs no `endpoint`: the chat talks to the address its script came from. - Load the script from `https://api.tolkly.io`. Do not copy it into your repository or bundle. This way new releases reach your site on their own. - Add no other attributes. The chat's name, greeting, colours and who answers (the AI or only people) come from the server. The element reads them from `GET https://api.tolkly.io/v1/projects//widget` when it connects. Attributes are only for the rare site that wants its own values ([attributes](https://tolkly.io/docs/en/widget-attributes.md)). ## Where they go Add both lines once, just before ``, in the template every page uses: the root layout, the base template or the theme's footer. Do not add them page by page. For your stack, see [Frameworks](https://tolkly.io/docs/en/frameworks.md). ### Single-page apps In React, Vue, Angular, Next.js or Nuxt, the chat must stay on the page when the route changes: - Render `` once, outside the router outlet: in `index.html` or the root layout. Inside a page component, the element is removed and created again on every navigation. - Load the script once, not on every page. - In TypeScript JSX, declare the element instead of casting it to `any` ([TypeScript and JSX](https://tolkly.io/docs/en/frameworks.md#typescript-and-jsx)). ## What loads on every page Most visitors never open the chat. So most page views load only the launcher: | Request | When | Caching | |---|---|---| | `https://api.tolkly.io/widget.js` | every page | `no-cache` with an ETag: a repeat view gets a `304` with no body | | `GET …/v1/projects//widget` | every page | the browser keeps it for `WIDGET_SETTINGS_MAX_AGE_SECONDS` (60 s by default) | | `POST …/v1/projects//identify` | every page with `data-identity`, and on `identify()` | a `POST`, never cached ([identity](https://tolkly.io/docs/en/identity.md)) | | `https://api.tolkly.io/widget/chat-.js` | when the visitor first reaches for the chat | named by its content, kept for a year | The chat window loads in three cases: - the visitor reaches for it: hovers, focuses or taps the launcher; - the page opens it; - the visitor already has a conversation going (then it loads at once). Scripts are sent compressed, with brotli or gzip, whichever the browser accepts. The window's code comes from the same place as `widget.js`, under `/widget/`. ## Visitors in Russia Since June 2025 Russian providers cut connections to Cloudflare after the first ~16 KB, so for a visitor in Russia without a VPN the chat from `https://api.tolkly.io` may never finish loading. `widget.js` is small enough to arrive whole; it waits for the chat itself, not for a script's `load` event (a stalled download fires neither `load` nor `error`), and then loads the chat from our address in Russia. The address that worked is remembered in the site's `localStorage` for a day, so the next page starts with it; a browser that refuses storage only loses that memory. The chat then sends every request to the address it was loaded from: `https://api.tolkly.io https://ru.tolkly.io` all serve the same chat and the same conversations. ## Check that it works 1. Open two different pages of the site. The chat button shows in the bottom right corner of both. 2. In the browser's network panel, `GET https://api.tolkly.io/v1/projects//widget` answers `200`. Its JSON has no `refused` field. Check this in the browser on your site, not with `curl`. The server decides by the page's `Origin` header, and it never refuses a request without one. 3. Within a few minutes of the deploy, the project's «Install» section in the app says «The chat is live on example.com · 2 min ago». Until then it says «Not installed yet». How the site gets recorded: - The server takes the site from the `Origin` header of the settings request. - It updates the last-seen time at most once per `WIDGET_ORIGIN_TOUCH_SECONDS` (300 s by default). - A page on the same host as `https://api.tolkly.io` sends no `Origin`, so it is not recorded. - A site the owner blocked is never shown there. ## If the chat does not show | What you see | Why, and what to do | |---|---| | No request to `https://api.tolkly.io` in the network panel | The browser got a page without the lines. Check the page source, the layout the site really uses and any page cache. | | `/widget` answers `{"refused": "origin_blocked"}` | The owner blocked this domain. They can unblock it in the project's «Install» section, block «Domains» ([Domains](https://tolkly.io/docs/en/domains.md)). | | `/widget` answers `{"refused": "origin_not_allowed"}` | The project is in strict mode and this domain is not on its list. The owner can allow it ([Domains](https://tolkly.io/docs/en/domains.md)). | | `/widget` answers `404` | The `project` attribute does not match any project on this server. | | The console reports a Content-Security-Policy violation | The site's policy blocks the widget. See [Content-Security-Policy](https://tolkly.io/docs/en/csp.md). | | The console says `tolkly: the identity token was refused (…)` | The chat works, but anonymously. See [Signed visitor identity](https://tolkly.io/docs/en/identity.md#rejected). | A refused site gets `200`, not `403`. So the page's console stays clean, and the widget simply draws nothing. To hand the install to a coding agent, see [AI agents](https://tolkly.io/docs/en/agents.md). Source: https://tolkly.io/docs/en/install.md --- # Frameworks > Where the two lines go in Next.js, Nuxt, React, Vue, Angular, WordPress, Tilda and Bitrix. Every stack uses the same two lines ([Install on a site](https://tolkly.io/docs/en/install.md)). Add the script once and the element once, in the layout all pages share. Replace `your-project` with the project's id. ## Plain HTML Add the lines before `` on every page, or in the template that builds them: ```html ``` Other server templates work the same way: Laravel's Blade layout, Django's `base.html`, Rails' `application.html.erb`. Put the lines before `` of the base layout. ## Next.js (App Router) The root layout stays mounted when the visitor navigates. Put the chat there: ```tsx // app/layout.tsx import Script from 'next/script' import type { ReactNode } from 'react' export default function RootLayout({ children }: { children: ReactNode }) { return ( {children} '; echo ''; }); ``` No access to theme files? Any plugin that adds custom code before `` on every page will do. Then clear the page cache, if the site has one. ## Tilda Add both lines to an HTML code block (T123). Put the block in a footer that every page uses, or on each page where the chat should show. Then publish the pages again. ## 1C-Bitrix Add the lines just before `` in the site template's `footer.php`. It is at `/local/templates/