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
Production Security Secure your production deployment
Error Handling Handle authentication and connection errors