Understand how the public widget key, visitor token, anonymous handle, tracking, and verified customer identity fit together.
The embedded widget uses a separate visitor protocol from the organization REST API. The official loader performs the bootstrap sequence automatically; this guide documents the trust boundaries for installation, debugging, and advanced identity integrations.
Use the public widget key copied from the Convor dashboard:
<script
src="https://cdn.convor.io/widget.js"
data-key="convor_wpk_..."
data-locale="en"
async
></script>convor_wpk_… is intentionally visible on the page. It identifies the widget
configuration but does not authorize organization REST API access.
Do not use an organization API key in the widget
A convor_sk_… key is a server secret. Never put it in data-key,
Convor.init(), browser storage, or client-side requests.
The official widget follows this sequence:
GET /api/widget/config?key=convor_wpk_... without an Authorization
header.visitorHandle UUID scoped to that public
widget key.visitorHandle with
POST /api/auth/visitor-token.visitorId, and orgId.The visitor token lifetime is one hour. The official client refreshes its session as needed; custom clients must obtain a new token rather than treating a visitor token as permanent.
GET /api/widget/config returns public appearance, localization, content,
pre-chat, department, knowledge-base, and branding settings for the widget key.
It requires no secret credential.
When the organization configures allowed domains, Convor permits the embed only for a matching host. The configuration endpoint reflects CORS access only for an origin that passes the same domain rule. A blocked origin receives a forbidden response; it is not a reason to expose another credential in the browser.
The official widget stores a random UUID visitor handle in local storage, separately for each public widget key. The handle is sent during visitor-token issuance. Convor HMAC-derives the actual visitor UUID from the organization and handle, which provides stable identity across page refreshes without trusting a browser-supplied database ID.
The handle is:
Use Convor.resetVisitor() when the authenticated user changes on a shared
browser so the next user does not inherit the previous visitor session.
After token issuance, the widget sends page views to
POST /api/tracking/visitors/track using the visitor bearer token. New clients
include:
sessionId UUID for the browsing session;pageViewId UUID for each page view;Single-page applications should notify the widget after client-side route changes. The official loader handles its supported page-change API and avoids storing recognized crawler or webdriver traffic.
Use the widget SDK methods according to the trust level:
Convor.updateVisitor() and attribute helpers store self-reported profile
data. They do not prove that the visitor owns an account or email address.Convor.identify() links the visitor to a customer identity verified by your
server with HMAC-SHA256.See the Widget SDK reference for the complete browser API.
Never expose the organization identity-verification secret to browser code. First obtain the current visitor ID from the widget, then send the customer traits to your backend. Sign this exact UTF-8 JSON structure and property order; missing optional values must be empty strings:
import {createHmac} from "node:crypto";
export function createConvorIdentityHash({visitorId, customer}) {
const payload = JSON.stringify({
visitorId,
id: customer.id,
email: customer.email ?? "",
name: customer.name ?? "",
phone: customer.phone ?? "",
});
return createHmac("sha256", process.env.CONVOR_IDENTITY_SECRET)
.update(payload)
.digest("hex");
}Return only the hash to the authenticated page, then call:
const {visitorId} = await Convor.ready();
const {userHash} = await fetch("/api/convor-identity-hash", {
credentials: "include",
}).then((response) => response.json());
await Convor.identify({
id: currentUser.id,
email: currentUser.email,
name: currentUser.name,
phone: currentUser.phone,
userHash,
});The public widget key, visitor bearer token, visitorId, traits, and HMAC must
all refer to the same organization and visitor. Convor checks the HMAC with a
timing-safe comparison and rejects identity verification when the organization
has no identity secret configured.
Prefer the official widget. A custom visitor client must implement all of the following correctly:
The customer REST API reference intentionally excludes protocol-only widget and Centrifugo callback routes. Their presence in the server does not make them organization automation endpoints.
Last updated: Aug 3, 2026
Was this page helpful?
Outbound Webhooks
Receive signed Convor event deliveries, verify the raw request body, deduplicate retries, and distinguish customer webhooks from provider callbacks.
Realtime Connections
Understand Convor connection tokens, channel-scoped subscription tokens, tenant channel names, refresh behavior, and protocol-only proxy routes.