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

# API Keys

> Per-request API keys via headers and request body for OpenAI, Google, and Anthropic in Agentium transport.

# API Keys

Agentium supports **per-request API key overrides** so clients can pass their own API keys instead of relying on server-side environment variables. Useful for multi-tenant apps, user-provided keys, and development.

***

## Supported Headers

| Header                | Provider  | Use Case                                    |
| --------------------- | --------- | ------------------------------------------- |
| `x-openai-api-key`    | OpenAI    | GPT, embeddings                             |
| `x-google-api-key`    | Google    | Gemini, embeddings                          |
| `x-anthropic-api-key` | Anthropic | Claude                                      |
| `x-api-key`           | Generic   | Fallback when provider-specific key not set |

***

## How It Works

1. Client sends a request with one of the headers (or `apiKey` in body).
2. Transport layer extracts the key via `extractApiKey()`.
3. Key is passed to `agent.run(input, { apiKey })` or `agent.stream(input, { apiKey })`.
4. The model provider uses the per-request key instead of `process.env.*`.

***

## REST (Express)

```bash theme={null}
# OpenAI agent
curl -X POST http://localhost:3000/api/agents/assistant/run \
  -H "Content-Type: application/json" \
  -H "x-openai-api-key: sk-..." \
  -d '{"input": "Hello!"}'

# In body (alternative)
curl -X POST http://localhost:3000/api/agents/assistant/run \
  -H "Content-Type: application/json" \
  -d '{"input": "Hello!", "apiKey": "sk-..."}'
```

***

## Socket.IO

```javascript theme={null}
// Via handshake
const socket = io("http://localhost:3000/agentium", {
  auth: { apiKey: "sk-..." },
});

socket.emit("agent.run", {
  name: "assistant",
  input: "Hello",
  // Uses handshake.auth.apiKey if apiKey not in payload
});

// Per-request override
socket.emit("agent.run", {
  name: "assistant",
  input: "Hello",
  apiKey: "sk-...",
});
```

***

## Provider Matching

The transport layer uses a priority-based matching system:

1. **Provider-specific headers** — Highest priority. Matched directly to the provider:
   * `x-openai-api-key` → used when agent uses an OpenAI model
   * `x-google-api-key` → used when agent uses a Google/Vertex model
   * `x-anthropic-api-key` → used when agent uses an Anthropic model

2. **Generic header** — `x-api-key` is used as a fallback when no provider-specific header is found. The transport passes it to whatever provider the agent uses.

3. **Body parameter** — `apiKey` in the request body is the final fallback.

This allows a single request to carry keys for multiple providers — useful when an agent uses one provider for the main model and another for embeddings or memory extraction:

```typescript theme={null}
// Client sends keys for both OpenAI (main model) and Google (embeddings)
fetch("/api/agents/assistant/run", {
  method: "POST",
  headers: {
    "x-openai-api-key": "sk-...",
    "x-google-api-key": "AIza...",
  },
  body: JSON.stringify({ input: "Hello!" }),
});
```

***

## Security Notes

<CardGroup cols={2}>
  <Card title="HTTPS Required" icon="lock">
    Always use HTTPS in production. API keys sent over HTTP are visible to network intermediaries.
  </Card>

  <Card title="No Key Logging" icon="warning">
    Never log request headers or bodies that may contain API keys. Configure your logging middleware to redact sensitive headers.
  </Card>

  <Card title="Key Rotation" icon="rotate">
    Support key rotation by accepting new keys without downtime. Per-request keys make this seamless — clients switch to new keys immediately.
  </Card>

  <Card title="Rate Limiting" icon="gauge">
    Apply rate limiting per API key to prevent abuse in multi-tenant setups.
  </Card>
</CardGroup>

```typescript theme={null}
// Example: Express middleware to strip API keys from logs
app.use((req, res, next) => {
  const sanitized = { ...req.headers };
  delete sanitized["x-openai-api-key"];
  delete sanitized["x-google-api-key"];
  delete sanitized["x-anthropic-api-key"];
  delete sanitized["x-api-key"];
  req.sanitizedHeaders = sanitized;
  next();
});
```

***

## Swagger UI

When Swagger is enabled, the OpenAPI spec includes security schemes for these headers. Users can click "Authorize" and enter their key; it will be sent with each request.
