> ## 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.

# Authentication

> Secure your API keys and manage session tokens

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.
</Warning>

### Getting Your API Key

See the [API key page](/api-key) 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

<Steps>
  <Step title="Token Request">
    Your server requests a session token from Anam using your API key and
    persona configuration
  </Step>

  <Step title="Token Generation">
    Anam generates a temporary token tied to your specific persona configuration
  </Step>

  <Step title="Client Connection">
    Your client uses the session token with the Anam SDK to establish a direct
    WebRTC connection
  </Step>

  <Step title="Real-time Communication">
    Once connected, the client can send messages and receive video/audio streams
    directly
  </Step>
</Steps>

### Creating Session Tokens

Below is a basic Express server that exposes an endpoint for creating session tokens.

<CodeGroup>
  ```typescript server.ts theme={"system"}
  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: "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: "30fa96d0-26c4-4e55-94a0-517025942e18",
            voiceId: "6bfbe25a-979d-40f3-a92b-5394170af54b",
            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"));
  ```
</CodeGroup>

### 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,
    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:

<CodeGroup>
  ```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;
  ```
</CodeGroup>

## Next Steps
