It is your agent, not a copy of it
Visitors talk to your existing agent through the shared thinqOS chat interface. It uses that agent’s Mind and configured capabilities. You do not maintain a separate website bot.
The agent can retain facts about a visitor for future conversations. Public exposure still needs deliberate configuration: review the knowledge and actions your agent can use before enabling it.
It knows it is talking to a stranger
The visitor has an anonymous identity. The platform identifies the conversation as an embedded experience, and visitor credentials permit a limited set of chat actions. They do not sign the visitor into your account.
The agent’s knowledge and capabilities still need review before public use. An anonymous chat is not an owner conversation.
Visitors are remembered without an account
The embedded chat stores a visitor token in the browser when storage is available. Returning to the same agent in that browser can reopen the conversation without a login. Browser storage restrictions can prevent recognition.
Different agents use separate visitor tokens. If you create a thinqOS account on thinqos.com after chatting anonymously, the conversation and what the agent learned about you are designed to carry over, because that visitor token lives on thinqOS's own site. This does not yet happen when the agent is embedded on a different company's website, because the browser keeps that site's storage separate from thinqOS's.
The visible “Forget me” control deletes the conversation and visitor-specific memory records, revokes the token and starts a new conversation after deletion succeeds. If the request fails, you can retry. Some inactive internal records can remain; see the privacy policy for the limits.
You decide who can reach it, and what it can spend
An agent is not reachable from the internet until you switch its embed on. You then list the exact origins allowed to show it. The origin list is enforced as a framing boundary: the chat only ever loads inside an iframe on a page whose origin you named.
Origins are matched exactly. There are no wildcards on purpose: a pattern like a wildcard subdomain cannot tell your own subdomain apart from a stranger who signed up for a subdomain on the same shared host.
What actually bounds your cost is the two ceilings, not the origin list. Set them deliberately: one caps how many turns a single visitor can run, the other caps the whole agent for the day. Both are designed to be enforced before any model is called, so a refused turn does not reach a model.
Give it the page context
The iframe cannot read its host page by itself. In the owner setup, under “What the agent can see on your page”, you choose one of three settings. The agent receives page content as website evidence, separate from the visitor’s message. It does not grant access to more data or actions.
Nothing unless your code sends it is the default and today’s behaviour. Your page can send its path, title and up to 6,000 characters of public text with setPageContext. Call it again after a client-side route change, and send null on private pages to clear the previous context.
Page text lets the loader read the page address, title and visible text for you. It follows client-side routing, so the agent keeps up when your site changes pages without a full reload. Page text and a picture when the visitor chooses adds a Show this page option to the chat. Nothing is captured unless the visitor presses it, or agrees when the agent asks to see the page. The picture blanks form fields, text areas, selects and editable regions, so what a visitor types into a form is not shown.
Visitors can always attach files and take photos. Sharing another tab, window or screen needs the owner setting “Let visitors share another tab, window or screen” and a host page that does not block screen capture with its own Permissions-Policy or a custom iframe that omits allow="display-capture".
Mark anything else private by adding the data-thinqos-private attribute to its element. Marked content is left out of both the text and the picture. Do not put secrets in page text, whichever setting you choose.
Choose how visitors open the chat
Use a floating chat button, place the chat inline in a page, or connect your own button. All three use the same agent and shared chat interface. The v2 loader adds the surrounding controls; it does not create a second agent. The HTML iframe works without the loader.
The generator below gives you code for each option, a React iframe component, or a prompt to hand to your AI website builder. Use any thinqOS agent that you own and have enabled for public embedding. This does not connect an arbitrary external agent endpoint.
Wix and other website builders
For Wix, use an Embed HTML element for an inline chat, or site-wide Custom Code for the floating script where your plan supports it. Give an inline block enough height, then publish and test the real site. A floating script inside a small HTML block stays inside that block.
For Webflow or Framer, use an Embed element for the iframe, or site-wide custom code for the floating launcher. For WordPress, use a Custom HTML block if your account permits iframes; site-wide scripts require an appropriate theme or code-injection facility. Squarespace code blocks and code injection depend on your plan. These are copy-and-paste installation methods; native marketplace plugins are not provided.
Some builders nest your HTML inside another iframe. Every ancestor origin must be allowed by your agent, including the builder frame’s origin. Prefer site-wide custom code if available. Do not allow a shared builder domain without considering who else can publish there. A sandbox with an opaque origin cannot use the page-context bridge.
| Website platform | Paste location | Presentation and checks |
|---|---|---|
| Custom HTML | Before the closing body tag, or your site-wide body code setting. | Floating or own button; inline needs its container before the deferred script. |
| React / Next.js | Copy the generated iframe component into your page or layout. | Inline; give it a title and height. No browser script is required during server rendering. |
| AI website builder | Paste Copy instructions into your builder’s chat. | Includes complete code; keep the shared chat and agent address, publish, then test. |
| Wix | Add Elements → Embed Code → Embed HTML. For floating: Settings → Custom Code → Add Custom Code → Body end, when available. | HTML block: iframe inline with 600px height. Custom Code: floating. Publish; an HTML block cannot float outside its frame. |
| Webflow | Add panel → Code Embed; or Site settings → Custom code → Footer code. | Embed: iframe inline; footer: floating. Save and publish to the exact allowed domain. |
| Framer | Insert → Embed; or Site settings → Custom Code → End of body. | Inline iframe or site-wide floating. Custom-code availability varies; test the published domain. |
| WordPress | Page editor → Custom HTML block; or an approved site-wide code facility. | Iframe inline when your role and plan allow it. If saving strips code, use an allowed facility and recheck the published page. |
| Squarespace | Edit page → Add block → Code; or Settings → Developer Tools → Code Injection → Footer, where available. | Inline iframe or site-wide floating. Code injection and scripts depend on your plan; test after publishing. |
| Shopify | Floating: Online Store → Themes → Edit code → layout/theme.liquid, paste once before </body>. Inline: Customize → Add section → Custom Liquid, paste the 600px iframe; the theme must support that section. For a script-based inline chat or your own button, use an approved theme code location with the container or button on that page. Theme editing requires the appropriate store permission; code facilities depend on your plan and theme. Save and publish the theme, then test the live storefront outside the editor. This recipe does not install chat in checkout. | Theme code: floating, inline or your own button. Custom Liquid: inline iframe with 600px height. Authorize the exact live storefront origin, publish and test a visitor session, then explicitly test an answer under normal owner-funded limits. Not certified on published Shopify stores. |
| HTML-only builder | HTML/embed block; paste the generated iframe. | Inline, width 100%, height 600px. Page context needs host JavaScript and is unavailable on the raw iframe alone. |
Set up the agent once
Use Add your agent above and sign in. Choose an agent by name, choose your website platform and presentation, preview it, and enter your published website URL. Review the exact origin before saving: https://example.com and https://www.example.com are different origins. Preview domains need separate permission. The appearance preview does not start a visitor session or buy a model turn.
Review the public exposure acknowledgement and spending limits, save, and copy the complete code. If another owner changes the settings while you work, reload the latest settings before saving again. For developers, authenticated GET and PUT /api/agents/YOUR_AGENT_ID/embed remain available; PUT replaces configuration, so preserve existing fields and use the current revision.
Review the agent’s Mind and capabilities before acknowledging public exposure. The server checks ownership, billing and information scope. Browser snippets contain only the public agent ID, never your account credentials or API keys. The setup API requires your signed-in owner session. Enablement is separate from generating installation code.
Developer contract and page context
Load https://app.thinqos.com/embed/v2.js once. ThinqOS.mount accepts agentId, an optional instance id, mode (floating, inline or button), target (a selector or element for inline), title, position (left or right), and baseUrl (the HTTPS origin of a dedicated thinqOS install). The returned handle exposes open(), close(), setPageContext(pageOrNull) and destroy(). ThinqOS.get(id) retrieves it. Reusing an instance ID returns the same handle; destroy before changing its configuration.
A deferred script can use data-agent-id, data-instance, data-mode, data-target, data-title and data-position instead. It uses the install serving the script. Floating and button modes load the iframe on first open and keep it when closed. Inline mode loads immediately. Set --thinqos-embed-height on the inline container to change its default 600px height. The floating launcher and panel follow the visitor’s light or dark preference; set --thinqos-embed-accent, --thinqos-embed-accent-text, --thinqos-embed-surface, --thinqos-embed-text, --thinqos-embed-radius or --thinqos-embed-offset on the page to match your brand. Internal chat styling is managed by thinqOS.
Page context is off by default (the manual setting). Call setPageContext with path, title and text strings, or null to clear it. Only send public text; call again after route changes and clear before entering a private page. Paths exclude query strings and fragments; limits are 300 characters for path, 200 for title and 6,000 for text.
If the owner chose Page text or Page text and a picture when the visitor agrees in thinqOS, the loader also reads the page address, title and visible text itself and refreshes it after client-side route changes. While your code keeps calling setPageContext, that call wins over the automatic text. Calling setPageContext(null) clears the automatic text until the next route change. Form values are never read as text. Elements marked data-thinqos-private are excluded from both text and picture. With the picture setting, the loader draws the page only after the visitor agrees in the chat, and it blanks form fields, text areas, selects and contenteditable regions first.
The thinqOS:embed-settings, thinqOS:embed-look-request and thinqOS:embed-look-response window messages are internal to the loader and the iframe. They are not an API, and they can change without a new major version.
The lifecycle window event in the example below carries id, agentId and state: mounted, open, close, bridge-ready, session-ready, session-error, answer-complete or destroy. Bridge-ready means the context listener is ready. Session-ready means a visitor session was authorized; answer-complete follows a completed answer to an explicit question. Each is a separate check. Events never contain conversation text or visitor credentials. JavaScript errors report invalid configuration. Chat errors and Forget me remain inside the shared chat interface.
Verify your installation
After publishing, use Test my installation in setup and open the chat on the actual website. Saved settings, copied code, a loaded messaging bridge and a working visitor session are separate checks. Only an explicit real question can verify a model answer; that turn uses the owner’s normal budget and limits. Then close the chat and reopen it. Check keyboard access, the Close control, Escape, mobile sizing and Forget me. Confirm that a site outside the allowed origins cannot frame it. Browser storage restrictions may prevent returning-visitor recognition.
If the frame is blank or refused, check embed enablement, exact origins and every ancestor frame, then the browser console for Content Security Policy errors. Your host must allow the app origin in frame-src and the loader origin in script-src and style-src. Microphone input also depends on HTTPS, the host Permissions-Policy and the visitor’s permission. A direct link to /embed/AGENT_ID is intentionally not a public chat page: embed it inside your own page and share that page’s URL.
Get your embed code
For the guided setup, choose your agent by name. This optional developer generator uses an agent ID. Enable its embed and allow your website’s exact origin first. This generator does not change your agent settings.
Choose an option and enter your agent ID. No account credentials belong in this code.
Your installation code will appear here.
Commands
Observe widget lifecycle events
window.addEventListener("thinqos:embed-state", (event) => {
const { id, agentId, state } = event.detail;
// bridge-ready means context messaging is ready, not session success.
console.log(id, agentId, state);
});Add it to a page
<iframe id="agent-chat" src="https://app.thinqos.com/embed/YOUR_AGENT_ID"
referrerpolicy="origin" style="width:100%;height:600px;border:0"
allow="microphone; display-capture; camera" title="Chat"></iframe>Share the current public page
const frame = document.querySelector("#agent-chat");
const agentId = "YOUR_AGENT_ID";
const origin = "https://app.thinqos.com";
function sendPageContext() {
frame.contentWindow.postMessage({
type: "thinqos:embed-context", version: 1, agentId,
page: { path: location.pathname, title: document.title, text: "" }
}, origin);
}
frame.addEventListener("load", sendPageContext);
window.addEventListener("message", (event) => {
if (event.origin === origin && event.source === frame.contentWindow &&
event.data?.type === "thinqos:embed-ready" &&
event.data.version === 1 && event.data.agentId === agentId) {
sendPageContext();
}
});