For owners

Domains and mirrors

The chat works on any of your domains, tells you of each new site, and lets you block one that is not yours or keep the chat to a list.

On this page

Mirrors change more often than anyone opens the settings. So by default the chat works on any domain. When it appears on a new site, you get a notice. You can block a site that is not yours with one button.

A notice for each new site

The first time the chat loads on a site, the bot posts in your company's Telegram group, in its general topic: «the chat appeared on brand38.shop». The notice has a «Block» button.

  • Only an owner or admin of the company can press it; anyone else is told so. After a press, the notice shows who blocked the site and offers «Unblock».
  • The bot announces each site only once.
  • It never announces a developer's machine or a private network (localhost, *.local, 192.168.* and the like).
  • If the chat loaded on a site before the group was linked, the site is listed in the app but never announced.

The domains list

The app lists every site the chat loaded on: the project's «Install» section, block «Domains». For each site you see:

  • when the chat was first and last seen there;
  • how many conversations started there;
  • «New» for the first 7 days.
StateWhat it means
«Works»The chat runs there. The site is not on your list.
«Allowed»The site is on your list. The chat runs there, in strict mode too.
«Not allowed»Strict mode is on and turns the site away.
«Blocked»You blocked the site. No chat there.
«Not seen for N days»The chat was last seen on this site, and it has not shown there for over 7 days. The code may have been removed (red dot).

Owners and admins can press «Block», «Unblock» and «Allow». «Allow» adds the site's domain to the list and unblocks it.

Without strict mode, «Allow» changes nothing for the chat. It only confirms the domain is yours. That matters for the domain rule: the rule then reads the domain as a mirror or as a site of its own. The «Read new domains» row at the end of the block turns the rule on. With the rule on, the Telegram notice of a new site offers «Allow» too.

Operators see the list without the buttons. A project keeps up to 50 sites. Past that, new sites are neither recorded nor announced.

What a blocked site gets

Nothing is drawn: no chat button, no hint, nothing in the browser console. If a page had the chat open before the block, it can't send anything more. So a blocked site spends none of your limit. A block from the app or from Telegram applies at once.

Strict mode

Use it when the chat must show only on your own domains. Open «Install» › «Advanced settings», block «Strict mode». Turn on «Only allowed domains» and fill in «Allowed domains and masks», one per line. A mask covers the whole domain, never a part of it:

EntryMatchesDoes not match
brand.combrand.comwww.brand.com, brand.com.evil.io
*.brand.comwww.brand.com, pay.brand.combrand.com
brand*.shopbrand.shop, brand38.shopbrand38.evil.shop

In strict mode, a site off the list gets no chat. The group gets «a try from an unknown site» with «Allow» and «Block».

Leave strict mode off while your mirrors change often. If strict mode is on and the list is empty, the chat works nowhere.

The mirror script's key

If a script moves your site to a new mirror, it can add the new domain to the list itself. It needs a key: in «Install» › «Advanced settings», block «Key for your mirror script», press «Issue a key». The key is shown once. «Issue a new key» stops the old one at once. Give the key to your developer to keep on the server, never in a page.

An example for your developer. The address is in the block, under «Example: add a mirror to the list»:

Terminal
KEY=tk_domains_…
API=https://api.tolkly.io/v1/projects/<project>/origins

# What is on the list now
curl -H "Authorization: Bearer $KEY" $API

# Add the new mirror, drop the old one; the rest stays
curl -X POST $API -H "Authorization: Bearer $KEY" -H 'Content-Type: application/json' \
  -d '{"add": ["brand39.shop"], "remove": ["brand38.shop"]}'

# Replace the whole list; "strict" is optional and switches the mode
curl -X PUT $API -H "Authorization: Bearer $KEY" -H 'Content-Type: application/json' \
  -d '{"patterns": ["brand.com", "*.brand.com", "brand\\d+\\.shop"], "strict": true}'

The list matters even with strict mode off: it tells the chat which domains are yours for source links (below).

Hand it to an AI agent

Under the key, owners and admins get «Hand it to an AI agent». It gives a prompt, with the project filled in, for the coding agent that edits your mirror script (Claude Code, Cursor). With it, the agent:

  • adds the new domain before visitors are sent there;
  • keeps the key in the server's TOLKLY_DOMAINS_KEY environment variable, never in the repository or a page;
  • checks that the domain shows as «Allowed».

Here the prompt has your-project in place of the project's id. «Open in…» → «Prompt for an AI agent» copies it.

Make this site’s mirror switch add the new domain to the Tolkly chat’s list of allowed domains, so the chat keeps working in strict mode.

Project: your-project
Domains API: https://api.tolkly.io/v1/projects/your-project/origins
Key: the environment variable TOLKLY_DOMAINS_KEY on the server that runs the switch. The owner issues it in Tolkly: «Install» › «Advanced settings» › «Key for your mirror script».

1. Read https://tolkly.io/docs/en/domains.md, the sections on strict mode and the mirror script’s key. If it does not load, this prompt is enough.
2. Find the script or job that moves the site to a new mirror domain: a deploy step, a DNS or CDN change, a scheduled job that registers domains. If there is none, stop and tell me.
3. In it, before DNS or a redirect sends visitors to the new domain, add the domain to the list: POST https://api.tolkly.io/v1/projects/your-project/origins with the headers "Authorization: Bearer $TOLKLY_DOMAINS_KEY" and "Content-Type: application/json" and the body {"add": ["<new domain>"]}. A domain is a host only (brand39.casino), with no scheme or path. With strict mode on, a domain off the list gets no chat, so this call comes first.
4. Optionally drop the old mirror in the same call: {"add": ["<new domain>"], "remove": ["<old domain>"]}. Do not use PUT unless I ask: it replaces the whole list.
5. Treat a failed call as a failed step of the switch: retry on 429 and 5xx; stop and report on 401 (no key, or a key the owner replaced) and on 400 (the answer names the entry it refused). Log the status, never the key.
6. Read the key from TOLKLY_DOMAINS_KEY only: never put it in the repository, a page, browser code or a log. The API sends no CORS headers, so it is never called from a browser. If the variable is not set where the script runs, stop and ask me to set it.
7. Check it: GET https://api.tolkly.io/v1/projects/your-project/origins with the same Authorization header answers {"strict": …, "patterns": […]} with the new domain among the patterns. Once the chat loads on that domain, «Install» › «Domains» in Tolkly shows it as «Allowed». Then list the files you changed.

A visitor on a new mirror

  • Source links follow the visitor. If a link in an answer points at another domain of yours, it opens on the site the visitor writes from. On brand38.shop, https://brand.com/rules becomes https://brand38.shop/rules, because the main domain may be blocked for the visitor. Your domains are the indexed site, the domains your list matches, and the sites the chat ran on that nobody blocked.
  • A signed-in visitor keeps their conversation. The browser keeps a conversation per site, so on a new mirror an anonymous visitor starts a new one. If your site signs the visitor in, they get their latest open conversation back on any mirror. Setup for your developer: Visitor identity.