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

# Platform Config

> Manage platform-wide configuration including API keys, feature flags, and service settings.

# Platform Config

Platform configuration is stored in an encrypted key-value store in the database. These endpoints allow superadmins to manage API keys, feature flags, and service settings through the admin UI. Database values take precedence over environment variables.

<Note>
  All API requests require a valid JWT token in the `Authorization: Bearer <token>` header. The API Gateway decodes the JWT and forwards auth context (`user-id`, `organization-id`, `user-email`, `x-platform-role`, `x-org-role`) as headers to downstream services.
</Note>

<Warning>
  All platform config endpoints require **superadmin** access. Non-superadmin requests receive a `403 Forbidden` response.
</Warning>

## Get All Config

<ParamField method="GET" path="/api/auth/admin/config" />

Retrieve all platform configuration values, grouped by category.

### Response (200)

Returns configuration entries organized by category. Sensitive values (API keys) are returned in encrypted form.

<ResponseField name="config" type="object">
  Configuration entries keyed by category.

  <Expandable title="Config structure">
    <ResponseField name="ai" type="object">
      AI service configuration.

      <Expandable title="AI config keys">
        * `OPENROUTER_API_KEY` -- OpenRouter API key
        * `OPENAI_API_KEY` -- OpenAI API key (embeddings)
        * `GEMINI_API_KEY` -- Google Gemini API key (embeddings)
      </Expandable>
    </ResponseField>

    <ResponseField name="voice" type="object">
      Voice service configuration.

      <Expandable title="Voice config keys">
        * `ELEVENLABS_API_KEY` -- ElevenLabs API key
        * `LIVEKIT_API_KEY` -- LiveKit API key
        * `LIVEKIT_API_SECRET` -- LiveKit API secret
        * `LIVEKIT_URL` -- LiveKit server URL
      </Expandable>
    </ResponseField>

    <ResponseField name="knowledge" type="object">
      Knowledge service configuration.

      <Expandable title="Knowledge config keys">
        * `PINECONE_API_KEY` -- Pinecone API key
        * `PINECONE_INDEX_NAME` -- Pinecone index name
        * `PINECONE_ENVIRONMENT` -- Pinecone environment
        * `LLAMA_CLOUD_API_KEY` -- LlamaParse API key
      </Expandable>
    </ResponseField>

    <ResponseField name="feature_flags" type="object">
      Feature flags.

      <Expandable title="Feature flag keys">
        * `VOICE_ENABLED` -- Enable voice features globally
        * `KNOWLEDGE_GRAPH_ENABLED` -- Enable knowledge graph extraction
      </Expandable>
    </ResponseField>
  </Expandable>
</ResponseField>

<CodeGroup>
  ```bash curl theme={null}
  curl https://your-domain.com/api/auth/admin/config \
    -H "Authorization: Bearer $TOKEN"
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch("https://your-domain.com/api/auth/admin/config", {
    headers: { Authorization: `Bearer ${token}` },
  });

  const { config } = await response.json();
  ```
</CodeGroup>

***

## Set Config Value

<ParamField method="POST" path="/api/auth/admin/config" />

Create or update a platform configuration value. Values are encrypted at rest using AES-256-GCM.

### Request Body

<ParamField body="key" type="string" required>
  Configuration key (e.g., `OPENROUTER_API_KEY`).
</ParamField>

<ParamField body="value" type="string" required>
  Configuration value. Will be encrypted before storage.
</ParamField>

<ParamField body="category" type="string" required>
  Category: `ai`, `voice`, `knowledge`, or `feature_flags`.
</ParamField>

### Response (200)

```json theme={null}
{
  "success": true,
  "message": "Configuration updated"
}
```

<CodeGroup>
  ```bash curl theme={null}
  curl -X POST https://your-domain.com/api/auth/admin/config \
    -H "Authorization: Bearer $TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "key": "OPENROUTER_API_KEY",
      "value": "sk-or-v1-...",
      "category": "ai"
    }'
  ```

  ```javascript JavaScript theme={null}
  await fetch("https://your-domain.com/api/auth/admin/config", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${token}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      key: "OPENROUTER_API_KEY",
      value: "sk-or-v1-...",
      category: "ai",
    }),
  });
  ```
</CodeGroup>

***

## Config Health Check

<ParamField method="GET" path="/api/auth/admin/config/health" />

Check the health of platform configuration, including which required keys are set and which are missing.

### Response (200)

<ResponseField name="status" type="string">`healthy`, `degraded`, or `unconfigured`.</ResponseField>
<ResponseField name="configuredKeys" type="string[]">List of configured keys.</ResponseField>
<ResponseField name="missingKeys" type="string[]">List of required but missing keys.</ResponseField>

***

## Setup Status

<ParamField method="GET" path="/api/auth/admin/config/setup-status" />

Check the first-time platform setup status, including whether essential services are configured.

### Response (200)

<ResponseField name="isComplete" type="boolean">Whether initial setup is complete.</ResponseField>

<ResponseField name="steps" type="object">
  Setup step completion status.

  <Expandable title="Setup steps">
    <ResponseField name="adminCreated" type="boolean">Superadmin user exists.</ResponseField>
    <ResponseField name="aiConfigured" type="boolean">At least one AI API key is set.</ResponseField>
    <ResponseField name="emailConfigured" type="boolean">Email service is configured.</ResponseField>
  </Expandable>
</ResponseField>

***

## Configuration Precedence

Platform config follows this precedence order:

1. **Database** (`platform_config` table) -- highest priority
2. **Environment variables** (`.env` files) -- fallback

Services call `getConfigValue(key)` which checks the database first and falls back to `process.env`. This means you can override any environment variable through the admin UI without restarting services.

## Encryption

All config values are encrypted at rest using AES-256-GCM with the `JWT_SECRET` as the encryption key. The `@brainstormer/shared` crypto module handles encryption and decryption transparently.
