> ## Documentation Index
> Fetch the complete documentation index at: https://anam.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# JavaScript SDK Authentication

> Keep Anam API keys on your server, create short-lived session tokens, and authenticate browser sessions with the JavaScript SDK.

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.

> [!WARNING]
>
> **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](https://anam.ai/docs/api-key.md) 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.

```typescript server.ts theme={"system"}
import express, { Request, Response } from "express";

interface PersonaConfig {
  name: string;
  avatarId: string;
  avatarModel: 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: "071b0286-4cce-4808-bee2-e642f1062de3",
          avatarModel: "cara-4",
          voiceId: "de23e340-1416-4dd8-977d-065a7ca11697",
          llmId: "a7cf662c-2ace-4de1-a21e-ef0fbf144bb7",
          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"));
```

```javascript server.js theme={"system"}
const express = require("express");
const app = express();
app.use(express.json());

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: "071b0286-4cce-4808-bee2-e642f1062de3",
          avatarModel: "cara-4",
          voiceId: "de23e340-1416-4dd8-977d-065a7ca11697",
          llmId: "a7cf662c-2ace-4de1-a21e-ef0fbf144bb7",
          systemPrompt: "You are a helpful assistant.",
        },
      }),
    });

    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 } = 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:

```typescript theme={"system"}
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

```javascript theme={"system"}
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,
    avatarModel: user.preferredAvatarModel || "cara-4",
    voiceId: user.preferredVoice || defaultVoiceId,
    llmId: user.preferredllmId || "a7cf662c-2ace-4de1-a21e-ef0fbf144bb7",
    systemPrompt: buildPersonalizedPrompt(user),
  };

  const sessionToken = await fetchAnamSessionToken(personaConfig);
  res.json({ sessionToken });
});
```

#### Context-aware Sessions

```javascript theme={"system"}
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:

```bash .env theme={"system"}
ANAM_API_KEY=your-api-key-here
NODE_ENV=production
```

```javascript config.js theme={"system"}
const config = {
  anamApiKey: process.env.ANAM_API_KEY,
  anamApiUrl: process.env.ANAM_API_URL || "https://api.anam.ai",
};

if (!config.anamApiKey) {
  throw new Error("ANAM_API_KEY environment variable is required");
}

module.exports = config;
```

## Next Steps


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.