Getting Started
Get a talking AI avatar running in your web app in a few minutes.
- An
appIdanduserKeyissued from the API Key page (see Get appId and userKey). KeepuserKeyon your server, never in the browser. - Node.js and a bundler (Vite, webpack, Next.js, …) so you can install the SDK from npm.
- A modern browser (latest Chrome, Edge, or Safari).
Install the SDK
npm install @deepbrainai/aihuman-web-sdk
import AIPlayer from "@deepbrainai/aihuman-web-sdk";
The package is a browser bundle. AIPlayer is the same class used in the rest of this guide.
Get appId and userKey
The API Key page has two tabs, and they issue different keys. The Web SDK works only with the Interactive Avatar API key. The AI Video API key on the other tab is for video generation and will fail authentication here.
- Open the API Key page and sign in (or create an account: top right → Login / Sign in).
- Select the Interactive Avatar API tab — not AI Video API, which is selected by default.
- Click Issue key on that tab. A dialog shows App ID (Client ID) and User Key (Secret) —
these are the
appIdanduserKeyused below. - Copy the User Key before closing the dialog. It is shown only once and cannot be retrieved later (the table Copy button copies App ID only). If you lose the User Key, issue a new key.
- If Issue key is disabled and the page says key issuance is being prepared, ask support to enable it for your account.
userKey is a long‑lived secret. Only your backend should read it.
Mint a ClientToken on your server
The browser must not see userKey. Your server signs a short‑lived JWT (ClientToken) and the
page exchanges it with generateToken().
npm install jsonwebtoken
import jwt from "jsonwebtoken";
const userKey = process.env.AIHUMAN_USER_KEY; // never ship this to the client
const payload = {
appId: process.env.AIHUMAN_APP_ID,
platform: "web",
};
const options = {
header: { typ: "JWT", alg: "HS256" },
expiresIn: 60 * 5, // 5 minutes
};
export function generateJWT(req, res) {
const token = jwt.sign(payload, userKey, options);
res.json({ appId: payload.appId, token });
}
Expose that as GET (or POST) /api/generateJWT. The page calls it when it needs a ClientToken
(including after error 1402).
Complete example
Put a wrapper and a button in the page, then run this after install. Replace getClientToken() with
a fetch to your /api/generateJWT.
<div id="AIPlayerWrapper" style="width: 480px; height: 720px;"></div>
<button id="speakBtn">Speak</button>
import AIPlayer from "@deepbrainai/aihuman-web-sdk";
async function main() {
const AI_PLAYER = new AIPlayer(document.getElementById("AIPlayerWrapper"));
const { appId, token: clientToken } = await getClientToken();
const auth = await AI_PLAYER.generateToken({ appId, token: clientToken });
if (auth.status !== "success") throw new Error(auth.message);
const list = await AI_PLAYER.getAIList();
const aiName = list.data.ai[0].ai_name; // not model_id
await AI_PLAYER.init({ aiName });
document.getElementById("speakBtn").onclick = () =>
AI_PLAYER.send("Hello! Nice to meet you.");
}
main();
Browsers block audio until the user interacts with the page. Trigger the first send() from a
click (or tap). Calling send() on page load will render the avatar but stay silent.
Step by step
1. Create the player
const wrapper = document.getElementById("AIPlayerWrapper");
const AI_PLAYER = new AIPlayer(wrapper);
The avatar fills the container — size it with CSS.
2. Authenticate
- On your server, mint a ClientToken (
appId+userKey,platform: "web"). - In the browser, exchange it with
generateToken().
const { appId, token: clientToken } = await getClientToken();
const result = await AI_PLAYER.generateToken({ appId, token: clientToken });
// result.status === "success"
// result.data.token / result.data.token_expire — JWT is stored inside the SDK
// there is no defaultAI; pick ai_name from getAIList()
Generate the ClientToken on your server. Send only the short‑lived ClientToken to the client.
3. Look up aiName and load
There is no separate “search avatar by display name” API. After generateToken(), call
getAIList(). v2 returns the human API envelope as-is (no camelCase remap):
const list = await AI_PLAYER.getAIList();
// list.status === "success"
// list.data.ai = [{ ai_name, ai_type, ai_display_name?, model_id?, language?, thumb_url? }, ...]
const aiName =
list.data.ai.find((m) => m.ai_display_name === "My Avatar")?.ai_name ??
list.data.ai[0].ai_name;
await AI_PLAYER.init({ aiName });
init({ aiName }) needs ai_name. Do not pass model_id. ai_display_name is UI-only.
language and thumb_url may be omitted. init() resolves when the avatar is ready to speak.
New accounts typically see sample-sage-v2 in this list. That is the sample avatar used in
the rest of these docs.
4. Speak
AI_PLAYER.send("Nice to meet you");
AI_PLAYER.send(["Nice to meet you", "How are you?"]);
Handle events (optional)
AI_PLAYER.onAIPlayerLoadingProgressed = (r) => console.log("loading", r?.loading);
AI_PLAYER.onAIPlayerEvent = (e) => console.log("event", e?.type);
AI_PLAYER.onAIPlayerErrorV2 = async (err) => {
if (err?.code === 1402) {
const { appId, token: clientToken } = await getClientToken();
await AI_PLAYER.generateToken({ appId, token: clientToken });
AI_PLAYER.reconnect();
return;
}
if (err?.code === 1407) {
console.error(err.code, err.message);
return;
}
console.error(err?.code, err?.message);
};
| Event | Fires when |
|---|---|
LOADING_PROGRESS | Resources are downloading (r.loading = %) |
LOAD_COMPLETED | The avatar is ready |
SPEECH_STARTED / SPEECH_COMPLETED | A send() begins / finishes playing |
See Troubleshooting for 1402 / 1407. Do not call release() on those
errors — reconnect after generateToken() to keep the same session.