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

# Usage in Production

> Securely deploy Anam AI in production environments

## Overview

When deploying to production, do not expose your API key publicly. Instead:

1. Exchange your API key for a short-lived session token on the server side
2. Pass this token to the client
3. Initialize the Anam SDK with the session token

Anam AI offers two types of session tokens: **Stateful** and **Ephemeral**.

## Session Token Types

### Stateful Session Tokens

Stateful tokens reference a persona that you've created and configured in the Anam AI Lab, or using the [Anam AI API](/api-reference/personas/create-persona). These are referenced by a unique ID.

<CardGroup cols={2}>
  <Card title="Pros" icon="check" color="#22c55e">
    Configuration changes are managed in the Lab interface without needing code
    changes. Ideal for personas that don't need to change from session to
    session.
  </Card>

  <Card title="Cons" icon="x" color="#ef4444">
    Less flexibility for per-user customization.
  </Card>
</CardGroup>

### Ephemeral Session Tokens

Ephemeral tokens allow you to define the persona configuration at runtime.

<CardGroup cols={2}>
  <Card title="Pros" icon="check" color="#22c55e">
    Define your persona configuration at runtime, enabling per-session
    customization and fast feedback during development.
  </Card>

  <Card title="Cons" icon="x" color="#ef4444">
    Requires managing persona configuration inside your application.
  </Card>
</CardGroup>

## Getting a Session Token

<Note>
  Session tokens are valid for **1 hour** by default. You should request a new token for each user session rather than caching tokens long-term.
</Note>

<Warning>
  The session token endpoint must be called from your **server**, not from client-side code. Making this request from the browser would expose your API key.
</Warning>

### Stateful Session Token

From your server, make a request to get a stateful session token, referencing your persona ID (found in the [Anam Lab](https://lab.anam.ai) under your persona's settings):

```typescript Fetching a stateful session token on your server theme={"system"}
interface SessionTokenResponse {
  sessionToken: string;
}

async function getStatefulSessionToken(
  apiKey: string,
  personaId: string
): Promise<string> {
  const response = await fetch("https://api.anam.ai/v1/auth/session-token", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      Authorization: `Bearer ${apiKey}`,
    },
    body: JSON.stringify({
      personaConfig: {
        personaId,
      },
    }),
  });

  if (!response.ok) {
    const error = await response.text();
    throw new Error(`Failed to get session token: ${response.status} ${error}`);
  }

  const data: SessionTokenResponse = await response.json();
  return data.sessionToken;
}
```

### Ephemeral Session Token

From your server, make a request to get an ephemeral session token with your persona configuration:

```typescript Fetching an ephemeral session token on your server theme={"system"}
interface EphemeralPersonaConfig {
  name: string;
  avatarId: string;
  voiceId: string;
  llmId: string;
  systemPrompt: string;
}

interface SessionTokenResponse {
  sessionToken: string;
}

async function getEphemeralSessionToken(
  apiKey: string,
  personaConfig: EphemeralPersonaConfig
): Promise<string> {
  const response = await fetch("https://api.anam.ai/v1/auth/session-token", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      Authorization: `Bearer ${apiKey}`,
    },
    body: JSON.stringify({
      personaConfig,
    }),
  });

  if (!response.ok) {
    const error = await response.text();
    throw new Error(`Failed to get session token: ${response.status} ${error}`);
  }

  const data: SessionTokenResponse = await response.json();
  return data.sessionToken;
}

// Example usage
const sessionToken = await getEphemeralSessionToken(apiKey, {
  name: "Cara",
  avatarId: "30fa96d0-26c4-4e55-94a0-517025942e18",
  voiceId: "6bfbe25a-979d-40f3-a92b-5394170af54b",
  llmId: "a7cf662c-2ace-4de1-a21e-ef0fbf144bb7",
  systemPrompt:
    "[STYLE] Reply in natural speech without formatting. Add pauses using '...' and very occasionally a disfluency. [PERSONALITY] You are Cara, a helpful assistant.",
});
```

### Common Error Responses

| Status Code | Meaning                             | Solution                                                               |
| ----------- | ----------------------------------- | ---------------------------------------------------------------------- |
| 401         | Invalid or missing API key          | Check your API key is correct and included in the Authorization header |
| 403         | API key does not have permission    | Verify your API key has the correct permissions in the Lab             |
| 404         | Persona not found (stateful tokens) | Check the persona ID exists and belongs to your account                |
| 429         | Rate limited                        | Reduce request frequency or contact support for higher limits          |

## Client Initialization

Once you have a session token from your server, use the `createClient` method to initialize the Anam client:

```typescript HelloWorld.ts theme={"system"}
import { createClient } from "@anam-ai/js-sdk";

const anamClient = createClient(sessionToken);
```

<Note>
  The client exposes the same methods whether initialized with an API key or
  session token. See [Basic Usage](/javascript-sdk/reference/basic-usage) for streaming and interaction examples.
</Note>

## Understanding a Session

The sequence diagram below shows how a typical session is started.

<Frame>
  <img src="https://mintcdn.com/anam/C1_yhmh0z2cLMID5/images/start-session.png?fit=max&auto=format&n=C1_yhmh0z2cLMID5&q=85&s=e1af3c048119abc5681d3823a3fe4923" alt="Session initialization sequence diagram" width="1420" height="1260" data-path="images/start-session.png" />
</Frame>

## Next Steps

<CardGroup cols={2}>
  <Card title="Talk Commands" icon="message" href="/javascript-sdk/reference/talk-commands">
    Control persona output using talk commands
  </Card>

  <Card title="Audio Control" icon="microphone" href="/javascript-sdk/reference/audio-control">
    Control audio input and streaming behavior
  </Card>
</CardGroup>
