Quickstart
Three steps to a live agent.
Mint a JWT on your server, render the widget on the page, ship. The browser never sees your embed secret.
You'll need a Tenant ID and Embed Secret from Settings → Profile, plus a Agent ID from any agent's Publish tab.
This guide targets
@onpilot/react and @onpilot/node v0.3.0+. On v0.2 the option was named externalOrgId — install latest with npm i @onpilot/react@latest @onpilot/node@latest. Full migration notes in the SDK changelog.Step 1
Sign an identity token on your server
The Node helper signs a per-user JWT locally with HS256 — no network call. Keep the embed secret server-side; never ship it to the browser.
bash
npm install @onpilot/nodets
// lib/onpilot.ts
import "server-only";
import { OnPilot } from "@onpilot/node";
const onpilot = new OnPilot({
tenantId: process.env.ONPILOT_TENANT_ID!,
embedSecret: process.env.ONPILOT_EMBED_SECRET!,
});
export function signOnPilotIdentity(user: {
id: string;
name?: string;
email?: string;
isAdmin?: boolean;
}) {
return onpilot.signIdentityToken({
copilotId: process.env.ONPILOT_COPILOT_ID!,
user: {
id: user.id,
name: user.name,
email: user.email,
role: user.isAdmin ? "admin" : "user",
},
expiresIn: "1h",
});
}Step 2
Render the widget
React, plain HTML, or any server-rendered framework that can output a script tag. Pass the JWT as a prop or attribute.
React
bash
npm install @onpilot/reacttsx
import { CopilotBubble } from "@onpilot/react";
<CopilotBubble identityToken={identityToken} />;HTML
html
<script
src="https://chat.onpilot.ai/embed.js"
data-identity-token="<%= identityToken %>"
></script>Step 3
You're live
Open your app — the bubble appears in the bottom-right corner. The widget exchanges the JWT for a short-lived chat session and loads.
Heads up — the 1-hour token footgun. If you sign with
expiresIn: "1h" and the user keeps the page open past the hour, chat silently breaks. For long-lived sessions use identityTokenProvider instead — see Identity tokens.