This guide creates a minimal but complete web application with an interactive AI persona. You will build a Node.js server that handles authentication and a client that streams the persona to a video element.
Looking for a faster start? The Quickstart guide gets you running in a single HTML file without a server.
Prerequisites
Node.js (version 16 or higher) and npm installed on your system
Basic knowledge of JavaScript
An Anam API key (get one here )
A microphone and speakers for voice interaction
Project Setup
This example creates a web application with three main files:
my-anam-app/
├── server.js # Express server for secure API key handling
├── package.json # Node.js dependencies
├── public/ # Static files served to the browser
│ ├── index.html # Main HTML page with video element
│ └── script.js # Client-side JavaScript for persona control
└── .env # Environment variables (optional)
Create project directory
mkdir my-anam-app
cd my-anam-app
Initialize Node.js project
Install dependencies
npm install express dotenv
Create environment file
Create a .env file in your project root to store your API key securely: ANAM_API_KEY = your-api-key-here
Replace your-api-key-here with your actual Anam API key. Never commit this file to version control.
Step 1: Set up your server
Create a basic Express server to handle session token generation. In a production application, integrate this into your existing backend service.
require ( "dotenv" ). config ();
const express = require ( "express" );
const app = express ();
app . use ( express . json ());
app . use ( express . static ( "public" ));
app . post ( "/api/session-token" , async ( req , res ) => {
try {
const response = await fetch ( "https://api.anam.ai/v1/auth/session-token" , {
method: "POST" ,
headers: {
"Content-Type" : "application/json" ,
Authorization: `Bearer ${ process . env . ANAM_API_KEY } ` ,
},
body: JSON . stringify ({
personaConfig: {
name: "Cara" ,
avatarId: "30fa96d0-26c4-4e55-94a0-517025942e18" ,
voiceId: "6bfbe25a-979d-40f3-a92b-5394170af54b" ,
llmId: "0934d97d-0c3a-4f33-91b0-5e136a0ef466" ,
systemPrompt:
"You are Cara, a helpful customer service representative. Be friendly and concise in your responses." ,
},
}),
});
if ( ! response . ok ) {
const errorData = await response . json (). catch (() => ({}));
console . error ( "Anam API error:" , response . status , errorData );
return res . status ( response . status ). json ({
error: errorData . message || "Failed to create session token" ,
});
}
const data = await response . json ();
res . json ({ sessionToken: data . sessionToken });
} catch ( error ) {
console . error ( "Server error:" , error );
res . status ( 500 ). json ({ error: "Internal server error" });
}
});
app . listen ( 3000 , () => {
console . log ( "Server running on http://localhost:3000" );
});
The server exchanges your API key for a temporary session token. This token has limited scope and expires, so your API key stays secure on the server.
Step 2: Set up your HTML
Create an HTML page with a video element for the persona and controls to start/stop the chat:
<! DOCTYPE html >
< html lang = "en" >
< head >
< meta charset = "UTF-8" />
< meta name = "viewport" content = "width=device-width, initial-scale=1.0" />
< title > My First Anam Persona </ title >
</ head >
< body >
< div style = "text-align: center; padding: 20px;" >
< h1 > Chat with Cara </ h1 >
< video
id = "persona-video"
autoplay
playsinline
style = "max-width: 100%; border-radius: 8px;"
></ video >
< div style = "margin-top: 20px;" >
< button id = "start-button" > Start Chat </ button >
< button id = "stop-button" disabled > Stop Chat </ button >
</ div >
< div id = "status" style = "margin-top: 10px; color: #666;" ></ div >
</ div >
< script type = "module" src = "script.js" ></ script >
</ body >
</ html >
Step 3: Initialize the Anam client
Create the client-side JavaScript to control your persona connection:
import { createClient } from "https://esm.sh/@anam-ai/js-sdk@latest" ;
let anamClient = null ;
const startButton = document . getElementById ( "start-button" );
const stopButton = document . getElementById ( "stop-button" );
const videoElement = document . getElementById ( "persona-video" );
const statusElement = document . getElementById ( "status" );
function setStatus ( message ) {
statusElement . textContent = message ;
}
async function startChat () {
try {
startButton . disabled = true ;
setStatus ( "Creating session..." );
// Get session token from your server
const response = await fetch ( "/api/session-token" , {
method: "POST" ,
});
if ( ! response . ok ) {
const error = await response . json ();
throw new Error ( error . error || "Failed to get session token" );
}
const { sessionToken } = await response . json ();
setStatus ( "Connecting..." );
// Create the Anam client
anamClient = createClient ( sessionToken );
// Start streaming to the video element
await anamClient . streamToVideoElement ( "persona-video" );
startButton . disabled = true ;
stopButton . disabled = false ;
setStatus ( "Connected - start speaking!" );
} catch ( error ) {
console . error ( "Failed to start chat:" , error );
setStatus ( `Error: ${ error . message } ` );
startButton . disabled = false ;
}
}
function stopChat () {
if ( anamClient ) {
anamClient . stopStreaming ();
anamClient = null ;
videoElement . srcObject = null ;
startButton . disabled = false ;
stopButton . disabled = true ;
setStatus ( "Chat ended" );
}
}
startButton . addEventListener ( "click" , startChat );
stopButton . addEventListener ( "click" , stopChat );
For details on createClient, streamToVideoElement, and stopStreaming, see the SDK Reference .
Step 4: Run your application
Start your server:
Open http://localhost:3000 in your browser
Click “Start Chat” to begin your conversation with Cara
You should see Cara appear in the video element, ready to chat through voice interaction.
How it works
Server-side authentication : Your server exchanges the API key for a session token, keeping credentials secure
Client connection : The SDK creates a WebRTC connection for real-time video streaming
Voice interaction : Cara listens for your voice input and responds with synchronized audio and video
Connection control : Start and stop buttons control when the persona is active
Next steps
Cookbook: Basic Next.js App Full tutorial for building a Next.js app with the Anam SDK
Core Concepts Learn how personas, tokens, and streaming work
Handle Events React to conversation events and user interactions
Production Setup Deploy your persona securely at scale
Common issues
Persona not appearing?
Check that your API key is set correctly in .env
Ensure the video element has autoplay and playsinline attributes
Check the browser console for errors
No audio?
Make sure your browser allows autoplay with sound
The user must interact with the page first (clicking “Start Chat” satisfies this)
Connection issues?
Verify your server can reach api.anam.ai
Check network connectivity and firewall settings