Skip to Content
JavaScript SDKQuick start

Quick start

Put a real-time talking avatar in a web page. The SDK joins a session your server created, shows the avatar in a <video> element, plays its voice, sends the user’s microphone, and gives you live captions and the character’s client tool calls.

Before you start

You need two things from the AvatarGo console :

  • An API key. In the console, open API Keys and press Create key. The key is shown only once: copy it then, and keep it on your server — for example as the environment variable AVATARGO_API_KEY. It never goes into a web page. See Authentication.
  • A published character. Build one under Build: a face, a voice and what it should say. Press Publish — sessions created with your API key use the published version only — then Copy character ID at the top of the page. A character’s ID starts with ch_.

Install

npm install @avatargo/sdk

It is an ES module, built on livekit-client, its only dependency.

Without a bundler

A plain HTML page can load both from a CDN with an import map, then use the same import as your page below. Pin both versions: livekit-client at the one this SDK release is built with.

<script type="importmap"> { "imports": { "@avatargo/sdk": "https://cdn.jsdelivr.net/npm/@avatargo/sdk@0.1.0/dist/index.js", "livekit-client": "https://cdn.jsdelivr.net/npm/livekit-client@2.22.3/dist/livekit-client.esm.mjs" } } </script> <script type="module"> import { createClient } from "@avatargo/sdk"; // … the Quick start's page code </script>

How a session works

Your API key never goes to the browser. Two steps, two places:

  1. Your server asks AvatarGo for a session, with your API key: POST /v1/auth/session-token. It gets back a sessionToken, valid for one hour.
  2. The browser gets that token from your server and hands it to the SDK. The SDK trades it for a place in the session’s room and joins.
browser ──(1) "start a call"──▶ your server ──POST /v1/auth/session-token (API key)──▶ AvatarGo browser ◀──── sessionToken ──── your server ◀──────────── { sessionToken, sessionId } ─┘ browser ──(2) createClient(sessionToken).streamToVideoElement(…) ──▶ AvatarGo + the avatar

A session is one of two kinds, chosen when your server creates it:

  • Character (characterId, or a characterConfig written out in the request): the character listens to the user and answers. The SDK sends the microphone and shows captions; this is the usual case, and the one on this page.
  • Avatar only: your server sends the speech audio itself, and the avatar lip-syncs to it. The page only shows the avatar — join with { microphone: false }. There are no captions or client tools. See Avatar only (your own audio).

Your server

Your own endpoint, in Node or Python:

Any framework — here plain fetch.

// POST /api/avatar-session — your own endpoint, called by your page. const res = await fetch("https://api.avatargo.ai/v1/auth/session-token", { method: "POST", headers: { authorization: `Bearer ${process.env.AVATARGO_API_KEY}`, "content-type": "application/json", }, body: JSON.stringify({ characterId: "ch_…" }), // a character you built and published in the console }); const body = await res.json(); // Refusals come here, before the page is involved — e.g. concurrency_limit when your plan's calls at once are all going. if (!res.ok) throw new Error(`${body.error.code}: ${body.error.message}`); const { sessionToken } = body; // send { sessionToken } to the page

Your page

<video id="avatar" autoplay playsinline></video> <button id="start">Talk</button> <button id="stop">End</button>
import { createClient } from "@avatargo/sdk"; let client; document.getElementById("start").onclick = async () => { const { sessionToken } = await (await fetch("/api/avatar-session", { method: "POST" })).json(); client = createClient(sessionToken); client.on("message", (m) => console.log(m.role, m.content, m.final)); // live captions client.on("session_ended", () => console.log("ended")); await client.streamToVideoElement("avatar"); // asks for the microphone, joins, shows the avatar }; document.getElementById("stop").onclick = () => client?.stopStreaming();

Start from a click, as here: browsers only play sound, and ask for the microphone, after the user has interacted with the page.