Skip to main content
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

1

Token Request

Your server requests a session token from Anam using your API key and persona configuration
2

Token Generation

Anam generates a temporary token tied to your specific persona configuration
3

Client Connection

Your client uses the session token with the Anam SDK to establish a direct WebRTC connection
4

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