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

# Environment Variables

> Complete reference of the environment variables used by the Annie Mei bot and auth service.

## Overview

Self-hosted Annie Mei has two env surfaces:

* the main `annie-mei` bot service
* the companion `auth` service for AniList OAuth

Use this page as the source of truth when you build `.env` files for both services.

## Shared values

These values should stay aligned across the bot and auth service.

| Variable                       | Required | Notes                                                                               |
| ------------------------------ | -------- | ----------------------------------------------------------------------------------- |
| `OAUTH_CONTEXT_SIGNING_SECRET` | Yes      | Must match so the auth service can validate the bot's signed OAuth context          |
| `USERID_HASH_SALT`             | Yes      | Keep this aligned if you want consistent hashed user identifiers in logs and Sentry |

## Bot service

### Required

| Variable                       | Notes                                                              |
| ------------------------------ | ------------------------------------------------------------------ |
| `DISCORD_TOKEN`                | Discord bot token                                                  |
| `DATABASE_URL`                 | PostgreSQL connection string for the shared Annie Mei database     |
| `REDIS_URL`                    | Redis connection string                                            |
| `SPOTIFY_CLIENT_ID`            | Spotify API client ID                                              |
| `SPOTIFY_CLIENT_SECRET`        | Spotify API client secret                                          |
| `MAL_CLIENT_ID`                | MyAnimeList API client ID                                          |
| `SENTRY_DSN`                   | Required by current bot startup                                    |
| `ENV`                          | Environment name such as `development`, `staging`, or `production` |
| `AUTH_SERVICE_BASE_URL`        | Auth service origin only, with no path                             |
| `OAUTH_CONTEXT_SIGNING_SECRET` | Shared secret used to sign OAuth context payloads                  |
| `USERID_HASH_SALT`             | Salt for hashing Discord user IDs in logs                          |

### Optional

| Variable                      | Default                                                   | Notes                                             |
| ----------------------------- | --------------------------------------------------------- | ------------------------------------------------- |
| `SENTRY_TRACES_SAMPLE_RATE`   | `0.0`                                                     | Float from `0.0` to `1.0`                         |
| `OAUTH_CONTEXT_TTL_SECONDS`   | `300`                                                     | Lifetime of `/register` OAuth links               |
| `GEMINI_API_KEY`              | none                                                      | Enables Gemini or another compatible LLM provider |
| `LLM_MODEL`                   | `gemini-3.1-flash-lite`                                   | Optional LLM model override                       |
| `LLM_BASE_URL`                | `https://generativelanguage.googleapis.com/v1beta/openai` | Optional OpenAI-compatible base URL override      |
| `POSTHOG_PROJECT_API_KEY`     | none                                                      | Enables PostHog LLM analytics events              |
| `POSTHOG_HOST`                | `https://us.i.posthog.com`                                | PostHog ingestion host                            |
| `POSTHOG_CAPTURE_LLM_CONTENT` | `true`                                                    | Capture LLM prompts and outputs in PostHog        |
| `RUST_LOG`                    | `info,serenity=warn`                                      | Tracing filter for local or production logging    |

## Auth service

### Required

| Variable                       | Notes                                                          |
| ------------------------------ | -------------------------------------------------------------- |
| `ANILIST_CLIENT_ID`            | AniList OAuth app client ID                                    |
| `ANILIST_CLIENT_SECRET`        | AniList OAuth app client secret                                |
| `ANILIST_REDIRECT_URI`         | Must match the AniList app callback URL                        |
| `DATABASE_URL`                 | PostgreSQL connection string for the shared Annie Mei database |
| `ROCKET_SECRET_KEY`            | Rocket application secret                                      |
| `OAUTH_CONTEXT_SIGNING_SECRET` | Shared secret used to validate the bot's OAuth context         |
| `USERID_HASH_SALT`             | Salt used for hashed user fingerprints in logs                 |

### Optional

| Variable                    | Default | Notes                                                |
| --------------------------- | ------- | ---------------------------------------------------- |
| `OAUTH_CONTEXT_TTL_SECONDS` | `300`   | Accepted age of signed OAuth context payloads        |
| `OAUTH_STATE_TTL_SECONDS`   | `300`   | Lifetime of the single-use AniList OAuth state value |
| `SENTRY_DSN`                | none    | Enables Sentry in the auth service                   |
| `SENTRY_ENVIRONMENT`        | none    | Environment label used by Sentry                     |
| `SENTRY_TRACES_SAMPLE_RATE` | `0.0`   | Float from `0.0` to `1.0`                            |

## Example local configuration

### Bot `.env`

```bash theme={}
# Discord
DISCORD_TOKEN=your_discord_bot_token

# Storage
DATABASE_URL=postgres://user:password@localhost/annie_mei
REDIS_URL=redis://localhost:6379

# External APIs
SPOTIFY_CLIENT_ID=your_spotify_client_id
SPOTIFY_CLIENT_SECRET=your_spotify_client_secret
MAL_CLIENT_ID=your_mal_client_id

# Monitoring
SENTRY_DSN=https://key@org.ingest.sentry.io/project
ENV=development
SENTRY_TRACES_SAMPLE_RATE=0.0

# Shared values
USERID_HASH_SALT=generate_a_random_secret_value
AUTH_SERVICE_BASE_URL=http://127.0.0.1:8000
OAUTH_CONTEXT_SIGNING_SECRET=generate_a_random_secret_value

# LLM (optional — enables /search natural-language queries)
# GEMINI_API_KEY=
# LLM_MODEL=gemini-3.1-flash-lite
# LLM_BASE_URL=https://generativelanguage.googleapis.com/v1beta/openai

# PostHog LLM analytics (optional)
# POSTHOG_PROJECT_API_KEY=
# POSTHOG_HOST=https://us.i.posthog.com

# Optional
OAUTH_CONTEXT_TTL_SECONDS=300
RUST_LOG=info,serenity=warn
```

### Auth `.env`

```bash theme={}
ANILIST_CLIENT_ID=your_anilist_client_id
ANILIST_CLIENT_SECRET=your_anilist_client_secret
ANILIST_REDIRECT_URI=http://127.0.0.1:8000/oauth/anilist/callback
DATABASE_URL=postgres://user:password@localhost/annie_mei
ROCKET_SECRET_KEY=generate_a_random_secret_key
OAUTH_CONTEXT_SIGNING_SECRET=generate_a_random_secret_value
USERID_HASH_SALT=generate_a_random_secret_value
OAUTH_CONTEXT_TTL_SECONDS=300
OAUTH_STATE_TTL_SECONDS=300
SENTRY_DSN=
SENTRY_ENVIRONMENT=development
SENTRY_TRACES_SAMPLE_RATE=0.0
```

<Warning>
  The bot and auth service must point at the same PostgreSQL database. The auth service owns the OAuth tables, while the bot owns `annie_mei.user_settings` and `annie_mei.guild_settings`. The bot reads `oauth_credentials` from the shared database for `/whoami`, `/unregister`, and member status overlays.
</Warning>

## Where these values are used

* Bot service references come from `annie-mei/src/main.rs` and `annie-mei/src/utils/oauth.rs`
* Auth service references come from `auth/src/main.rs` and `auth/src/routes/healthz.rs`

## Related pages

* [Installation](/installation)
* [Self-hosting architecture](/self-hosting/architecture)
* [Bot service](/self-hosting/bot-service)
* [Auth service](/self-hosting/auth-service)
