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

# Agent SDKs & the gateway

> Route your own agents (OpenAI SDK and others) through the Enfors gateway so every call becomes a decision.

Your own agents integrate with Enfors by calling the **gateway** (`llm.enfors.ai`, built on
[LiteLLM](https://litellm.ai)) instead of the model provider directly. The gateway captures
each call, tags it with the agent that made it, and turns it into a
[decision](/concepts/agents-sessions-decisions) — your code only ever waits on the model.

This is the path for the **OpenAI SDK** and other provider SDKs. If you run Claude Code or
Claude Desktop, use the [watcher](/integrations/gateway-installer) instead.

## What you need

<CardGroup cols={2}>
  <Card title="Gateway base URL" icon="link">
    `https://llm.enfors.ai` — set this as the SDK's `base_url`. For raw HTTP nodes, use
    `https://llm.enfors.ai/v1`.
  </Card>

  <Card title="LLM Gateway Key" icon="key">
    Your gateway credential, under **Admin → API Keys**. It's provisioned automatically at
    signup — distinct from the [Personal Access Token](/api-reference/authentication) used to
    read the Data API.
  </Card>
</CardGroup>

## OpenAI SDK

The gateway is OpenAI-compatible, so you point the OpenAI SDK at it. Attribution metadata
travels as query parameters (`default_query`), and you bring your own provider key via a
header.

```python theme={null}
from openai import OpenAI

client = OpenAI(
    base_url="https://llm.enfors.ai",
    api_key="YOUR_GATEWAY_KEY",
    default_query={
        "agent_id": "my-agent",
        "agent_name": "My Agent",
        "execution_id": "run-abc-123",
    },
    default_headers={
        "x-enfors-provider-api-key": "providerApiKey",
    },
)

response = client.chat.completions.create(
    model="openai/gpt-4o",
    messages=[{"role": "user", "content": "Hello"}],
)
print(response.choices[0].message.content)
```

## Fields that matter

<ParamField path="base_url" type="string" required>
  The gateway origin, `https://llm.enfors.ai`. The OpenAI SDK appends `/v1/...` itself; for
  tools where you paste a full base, use `https://llm.enfors.ai/v1`.
</ParamField>

<ParamField path="api_key" type="string" required>
  Your **LLM Gateway Key** (Admin → API Keys). This authenticates you to the gateway — not
  the model provider.
</ParamField>

<ParamField path="model" type="string" required>
  `provider/model-name` format — e.g. `openai/gpt-4o`, `openai/gpt-4o-mini`. The gateway is
  model-agnostic (Anthropic, OpenAI, Gemini, Bedrock, Azure…).
</ParamField>

<ParamField path="default_query.agent_id" type="string" required>
  Stable identifier for the agent making the call — this is what groups its sessions and
  decisions in Enfors.
</ParamField>

<ParamField path="default_query.agent_name" type="string">
  Human-readable name shown in the workspace.
</ParamField>

<ParamField path="default_query.execution_id" type="string">
  Identifier for this run — use a fresh value (e.g. a UUID) per execution to group the calls
  of a single run together.
</ParamField>

<ParamField path="x-enfors-provider-api-key" type="header">
  **Bring your own provider key.** The gateway forwards the call to the provider using this
  key; it's separate from your Gateway Key.
</ParamField>

<Note>
  The `agent_id`, `agent_name`, and `execution_id` parameter names match **API Keys → Query
  parameters** in the Enfors app. You can also pass them on the URL directly, e.g.
  `https://llm.enfors.ai/v1/chat/completions?agent_id=my-agent&agent_name=My+Agent&execution_id=run-abc-123`
  — useful for no-code / workflow nodes.
</Note>

## How it flows

Each call is captured by the gateway and enqueued via its own callback while your client
waits only on the model. Enfors then reconstructs it into a decision with reasoning and
evidence. See [How Enfors works](/getting-started/how-enfors-works) for the full pipeline.
