arizuko

arizukohowto › Chat link on your site

put a chat link on your site

A chat link is a URL like https://<host>/chat/<token>/. Open it in a browser and you get a small chat page wired up to one folder's agent. No login. Anyone with the URL can talk.

The primitive is the same one webhooks use — see route tokens for the full story. This page covers the operator-side recipe for getting one URL onto one website.

/chat/<token>/ accepts any valid route token — the JID kind is metadata, not a URL gate. issue_chat_link always returns a /chat/<token>/ URL.

use case

A tenant runs acme.com and wants a “Chat with us” link on the marketing site, against the acme agent. No account creation, no Slack invite — visitors click the link, type, the agent replies in the page.

issue the URL

From the CLI:

arizuko token issue acme chat
# https://acme.fiu.wtf/chat/Yp3v...Q2/

The CLI prints the URL once. Paste it where the “Chat with us” button lives on the website. The token is in the URL — treat the whole URL as a shareable bearer credential.

An agent inside the folder can mint its own:

issue_chat_link()
  → {
    "token": "...",
    "url":   "https://acme.fiu.wtf/chat/.../",
    "jid":   "web:acme"
  }

attach instructions to the link

Either mint face takes an optional context — instructions on how the agent should process what arrives through this specific link:

issue_chat_link(context="bug reports from the acme site; triage and file, don't chat back")

arizuko token acme issue chat acme --context "bug reports; triage, don't chat"

Every message that arrives through the link then carries the text into the agent's prompt as a <link-context> block. The agent treats it as the link's handling contract, not as something to reply to. Two links into the same folder can carry two different contracts. Context is fixed at mint time — to change it, mint a new link and revoke the old.

what the visitor sees

GET /chat/<token>/ serves a minimal HTML chat page baked into webd. The visitor types, the page POSTs to the same URL, the response carries a turn_id, and an SSE stream at /chat/<token>/<turn_id>/sse delivers the agent's reply frames as the turn runs.

Dropped connections reconnect with Last-Event-Id; the server replays missed frames and resumes live. The page works in any modern browser without any account, cookie, or sign-in step.

splitting one folder across pages

Pass a jid_suffix to put two URLs from the same folder on different pages and tell them apart in routing:

arizuko token issue acme chat --suffix support
  → web:acme/support  (https://.../chat/Sup1.../)

arizuko token issue acme chat --suffix sales
  → web:acme/sales    (https://.../chat/Sal2.../)

Both URLs reach the same acme agent, but the JID prefix lets route rules behave differently — e.g. a different persona, a different topic, or a different scheduled escalation. Suffixes are folder segments, not query params; pick names that read well in the route table.

authenticated chat is a different surface

/chat/<token>/ is the anonymous bearer URL. Signed-in chat (a teammate's private pane against their own folder, OAuth-gated through proxyd) is a separate surface served by webd and not covered here.

revocation

arizuko token revoke web:acme/support

The next visitor lands on a 401. Reissue with the same suffix to get a new URL with the same JID and swap it on the site. There is no in-place rotation — the URL is the credential.

go deeper