Website widget
Any agent can answer visitors on your website. Paste one script tag and the agent appears as a chat button, or inside a page. It answers from the bucket you attach. If your site has its own login, logged-in visitors can also ask about their own orders, bookings, or account.
Set it up under Agents, on the agent's Website tab. Admin and Developer roles can change it.
Add it to a page
- Turn the widget Active and click Save Changes. That creates the publishable key.
- Add your site to Allowed origins (see Access).
- Copy a snippet and paste it into your site.
Corner button. A chat button in the corner of every page:
<script
src="https://www.cosmicjs.com/agent.js"
data-key="pk_your_key"
async>
</script>
Inside the page. The chat fills an element you choose, so the page header and footer stay:
<div id="chat" style="height: 70vh"></div>
<script
src="https://www.cosmicjs.com/agent.js"
data-key="pk_your_key"
data-target="#chat"
async>
</script>
Optional attributes:
| Attribute | What it does |
|---|---|
data-target | A CSS selector. The chat renders inside that element instead of as a corner button. |
data-theme | light or dark. Forces a theme when your site does not offer both. Without it, the widget follows the page. |
data-width, data-height | Starting size of the corner panel, in pixels. Visitors can drag the edge to resize it. |
The publishable key is public. It lets a visitor send a message from an allowed origin. It is not a content key. Rotate key issues a new one, and sites using the old snippet stop working until you paste the new one.
In a single-page app, the browser runs a script URL only once. If the chat
lives on one route, add the script when that route mounts and remove the chat
element when it unmounts. Adding a query string such as
agent.js?mount=1712345678 makes the browser run it again.
Access
- Allowed origins. Every site the widget runs on, one per line, such as
https://example.comandhttps://www.example.com. Requests from other origins are refused. - Handoff email. When the agent cannot answer, it can show a short form, and the visitor's question goes to this address.
- Daily token cap. The widget stops answering for the day when the cap is reached. The default is 500,000 tokens.
Appearance
Color, greeting, position, and up to six starting questions. The preview beside these settings updates as you type. An optional footer link appears under the chat. Free plans always show the Cosmic mark.
Visitor accounts
Public questions need no login. For questions about one visitor's own records, the widget can log them in through your site, using the Concierge Agent Protocol login.
Turn on Log in button. The widget reads your site's agent.txt. When the file has an OAuth line and your login offers a code login, a Log in button appears in the chat. The visitor approves on your site. If your login recognizes visitors who are already signed in, that takes one click. Their password never reaches Cosmic or the agent.
To build that login, see Add login to your agent. With Node.js, @conciergeprotocol/server serves it, and currentAccount lets a signed-in visitor approve without typing a password.
The site login is between the visitor and your site. Turning the button on does not give Cosmic your customers' accounts.
Account endpoints
With Account endpoints on, the agent keeps answering public questions from your bucket, and calls your own API for the logged-in visitor's data.
- Set Base URL, the start of your account routes, such as
https://store.example.com/api/account. It must be a public https URL. - Add one row per endpoint:
| Name | Method | Path | What it returns or does |
|---|---|---|---|
list_orders | GET | /orders | The customer's recent orders |
get_order | GET | /orders/:number | One order by its number |
cancel_order | POST | /orders/:number/cancel | Ask to cancel an open order. Returns a link the customer approves. |
- Name is how the agent refers to the endpoint. Lowercase letters, numbers, and underscores.
- Path is added to the base URL. A part like
:numberbecomes an input the agent fills in from the conversation, so "where is OMS-0981?" callsGET /orders/OMS-0981. - What it returns or does is what the agent reads to decide when to call it.
- Use GET to look things up. Use POST for a change, and have your route return a confirmation link instead of making the change.
Up to ten endpoints. The agent can only call the endpoints you list, at your base URL, with the inputs in the path. It cannot build its own URLs.
What your routes receive
Each call carries:
Authorization: Bearer <token>: the visitor's login from your site.CAP-From: agent:<agent id>: this agent. The login was issued to the same id.
Your routes must:
- Check the token, and use the account it belongs to. With
@conciergeprotocol/server,door.accountFor(request)returns{ account, scope }, ornull. - Filter every query by that account. Never take a customer id or email from the request.
- Return
401when the login is missing or expired. The agent asks the visitor to log in again. - Hold changes for approval.
door.requestApproval(request, { summary, authorization_details })returns a link to your confirm page, and youractfunction runs the change once the visitor approves. A read-only login getswrite_required.
Optionally, send a CAP-Account response header, such as the visitor's email. Cosmic saves it on the conversation, so you can tell conversations apart.
export async function GET(request) {
const access = await door.accountFor(request)
if (!access) {
return Response.json({ error: { code: 'login_required' } }, { status: 401 })
}
const user = await users.get(access.account)
const list = await orders.listFor(access.account)
return Response.json({ orders: list }, { headers: { 'CAP-Account': user.email } })
}
What is stored
- The visitor's token is never stored. It is used for the calls in one reply, then dropped. It is not written to the conversation, the agent's prompt, or logs.
- The question and the agent's reply are saved, so you can read logged-in conversations with the agent's other conversations. The
CAP-Accountlabel is saved with them when you send it. - Raw responses from your API are not saved. The conversation records that an account lookup happened, not the data it returned.
- Logged-in conversations are deleted once Keep logged-in conversations (days) passes without a new logged-in message. The default is 30 days, up to 365.
Limits
- The daily token cap applies to every reply, logged in or not.
- Each call to your API times out after 10 seconds. Responses over about 12,000 characters are cut short, so return only what a person needs.
- Fields named like secrets, such as
password,access_token,card, orpayment_method, are removed from responses before the agent sees them. Do not rely on this: return only what the visitor should see.