Anam uses a two-tier authentication system to keep your API keys secure while enabling real-time client connections.
Tier 1: API Key
Your API key is used to authenticate your requests to the Anam API. It is a secret key that is used to sign your requests and is stored on your server.
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 that allow your client applications to connect directly to Anam’s streaming infrastructure while keeping your API keys secure.
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
Basic Token Creation
Below is a basic express server example that exposes a single endpoint which a client application can use to create a session token.
const express = require('express');
const app = express();
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",
brainType: "ANAM_GPT_4O_MINI_V1",
systemPrompt: "You are a helpful assistant.",
},
}),
});
const { sessionToken } = await response.json();
res.json({ sessionToken });
} catch (error) {
res.status(500).json({ error: 'Failed to create session' });
}
});
Advanced Token Creation
Instead of using the same persona configuration for all users, you can utilise context to create different persona configurations for different situations.
Pattern 1: User-based Personalization
For applications with different user types or preferences:
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,
brainType: user.preferredBrainType || "ANAM_GPT_4O_MINI_V1",
systemPrompt: buildPersonalizedPrompt(user),
};
const sessionToken = await fetchAnamSessionToken(personaConfig);
res.json({ sessionToken });
});
Pattern 2: Context-aware Sessions
For applications where the persona changes based on context:
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 });
});
Error Handling
Common authentication errors and how to handle them:
app.post('/api/session-token', async (req, res) => {
try {
const response = await fetch("https://api.anam.ai/v1/auth/session-token", {
// ... config
});
if (!response.ok) {
const errorData = await response.json();
switch (response.status) {
case 401:
console.error('Invalid API key');
return res.status(500).json({ error: 'Authentication failed' });
case 400:
console.error('Invalid persona config:', errorData);
return res.status(400).json({ error: 'Invalid configuration' });
default:
console.error('Unexpected error:', errorData);
return res.status(500).json({ error: 'Service unavailable' });
}
}
const { sessionToken } = await response.json();
res.json({ sessionToken });
} catch (error) {
console.error('Network error:', error);
res.status(500).json({ error: 'Network error' });
}
});
Environment Setup
Store your API key securely:
ANAM_API_KEY=your-api-key-here
NODE_ENV=production
Next Steps