Assistant UI
Publishable keys
A publishable key answers one question: which agent replies. Your page sends it with the first request, and Teaflask uses it to pick the agent and check where the request came from. The key is meant to sit in page source and client bundles. It is not a secret, and it says nothing about who the user is. That's Identity.
How a key is used
When the assistant mounts, it sends the key to Teaflask and gets back a short-lived visitor token. That token authenticates everything else in the conversation, and the assistant renews it before it expires. Teaflask hands out a visitor token when both of these are true:
- The key exists and hasn't been revoked.
- The request comes from one of the key's allowed origins.
Create a key
Open the agent in the dashboard and go to its Install section. Choose New key, pick Live or Test, and enter the allowed origins, one per line. The key belongs to that agent.
Every key has a row in the Install section. Opening a row shows the full key with a copy button, and the key's allowed origins, at any time. Keys created before Teaflask started storing them in full show only a prefix. They keep working, and rotating one gives you a successor that's stored in full.
Live and test keys
| Mode | Use it for |
|---|---|
| Live | Production |
| Test | Local development and staging |
The mode labels the key's traffic and is fixed when you create the key. A test key isn't a sandbox for your application. If its actions adapter points at your production API with a real user's session, the actions are real. Pair a test key with a test environment of your API.
Allowed origins
An origin is a scheme, a host and an optional port, with no path, query or trailing slash:
https://app.example.com
https://staging.example.com
http://localhost:5173
The match is exact. Case is ignored, and a stray trailing slash is ignored, but nothing else is:
| These are different origins | Because |
|---|---|
http://localhost:3000 and http://localhost:5173 |
The ports differ |
http://localhost:3000 and http://127.0.0.1:3000 |
The hosts differ |
http://app.example.com and https://app.example.com |
The schemes differ |
https://example.com and https://app.example.com |
Subdomains are listed one by one; there are no wildcards |
Origins are fixed when you create a key, and rotating keeps them. To serve a new origin, create a new key. A key's reach should never widen quietly.
A request from an origin that isn't on the list gets 403 ORIGIN_NOT_ALLOWED, and the error message names the origin it saw. Compare that with the key's list in the dashboard.
The origin check limits which websites can use your key from a browser. It doesn't prove who is calling: a script outside a browser can send any Origin header it likes. Your own API still has to authenticate users and decide what they may do.
Rotate, replace and revoke
| To | Do this | What happens |
|---|---|---|
| Swap keys with no downtime | Create a second key with the same mode and origins, deploy it, then revoke the old one | Both keys work until you revoke the old one |
| Get a fresh key immediately | Rotate | The old key stops working at once. The new one has the same agent, mode and origins |
| Stop a key for good | Revoke | The key stops working at once. There's no undo |
Rotate and revoke take effect immediately, so pages still sending the old key stop working until you deploy the new one. A key appearing in public code is expected and isn't a reason to rotate.
More than one key
Several keys can select the same agent. That's the normal way to keep environments apart: a test key for local and staging origins, a live key for production. Because each key has its own origins, a key copied from a staging page can't be used from production.
Surfaces that should share a conversation must use the same key, because the key is part of what identifies the conversation. See Surfaces.