Anam uses a two-tier authentication system: API keys for server-side requests and session tokens for client connections.
Tier 1: API Key
Your API key authenticates server-side requests to the Anam API.
Never expose your API key on the client side . It should only exist in your
server environment.
Getting Your API Key
See the API key page for details on how to get your API key from the Anam Lab.
Tier 2: Session Tokens
Session tokens are temporary credentials (valid for 1 hour) that allow client applications to connect to Anam’s streaming infrastructure without exposing your API key.
How Session Tokens Work
Token Request
Your server requests a session token from Anam using your API key and
persona configuration
Token Generation
Anam generates a temporary token tied to your specific persona configuration
Client Connection
Your client uses the session token with the Anam SDK to establish a direct
WebRTC connection
Real-time Communication
Once connected, the client can send messages and receive video/audio streams
directly
Creating Session Tokens
Below is a basic Express server that exposes an endpoint for creating session tokens.
import express , { Request , Response } from "express" ;
interface PersonaConfig {
name : string ;
avatarId : string ;
voiceId : string ;
llmId ?: string ;
systemPrompt ?: string ;
}
interface SessionTokenResponse {
sessionToken : string ;
}
const app = express ();
app . use ( express . json ());
app . post ( "/api/session-token" , async ( req : Request , res : Response ) => {
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 a helpful assistant." ,
} satisfies PersonaConfig ,
}),
});
if (! response . ok ) {
const errorData = await response . json ();
console . error ( "Token creation failed:" , errorData );
return res . status ( response . status ). json ({ error: "Token creation failed" });
}
const { sessionToken }: SessionTokenResponse = await response . json ();
res . json ({ sessionToken });
} catch ( error ) {
console . error ( "Network error:" , error );
res . status ( 500 ). json ({ error: "Failed to create session" });
}
});
app . listen ( 3000 , () => console . log ( "Server running on port 3000" ));
Using the Session Token (Client-Side)
After your server creates a session token, your client fetches it and uses the Anam SDK to start streaming:
import { createClient } from "@anam-ai/js-sdk" ;
async function startPersonaSession () {
// Fetch token from your server
const response = await fetch ( "/api/session-token" , { method: "POST" });
const { sessionToken } = await response . json ();
// Create client with the session token
const anamClient = createClient ( sessionToken );
// Start streaming to a video element
await anamClient . streamToVideoElement ( "persona-video" );
}
Dynamic Persona Configuration
Instead of using the same persona for all users, you can customize based on context:
User-based Personalization
app . post ( "/api/session-token" , authenticateUser , async ( req , res ) => {
const user = req . user ;
const personaConfig = {
name: `Persona for user: ${ user . id } ` ,
avatarId: user . preferredAvatar || defaultAvatarId ,
voiceId: user . preferredVoice || defaultVoiceId ,
llmId: user . preferredllmId || "0934d97d-0c3a-4f33-91b0-5e136a0ef466" ,
systemPrompt: buildPersonalizedPrompt ( user ),
};
const sessionToken = await fetchAnamSessionToken ( personaConfig );
res . json ({ sessionToken });
});
Context-aware Sessions
app . post ( "/api/session-token" , authenticateUser , async ( req , res ) => {
const { context , metadata } = req . body ;
let personaConfig ;
switch ( context ) {
case "customer-support" :
personaConfig = buildSupportPersona ( metadata );
break ;
case "sales" :
personaConfig = buildSalesPersona ( metadata );
break ;
case "training" :
personaConfig = buildTrainingPersona ( metadata );
break ;
default :
personaConfig = defaultPersonaConfig ;
}
const sessionToken = await fetchAnamSessionToken ( personaConfig );
res . json ({ sessionToken });
});
Environment Setup
Store your API key securely:
ANAM_API_KEY = your-api-key-here
NODE_ENV = production
Next Steps
Your First Persona Create and customize your first persona
Session Tokens Deep Dive Token lifecycle, caching, validation, and advanced error handling
Production Security Secure your production deployment
Error Handling Handle authentication and connection errors