# OpenAI integration

## Base URL

```
https://www.spendline.ai/v1
```

**With `/v1`.** The OpenAI SDK appends `/chat/completions` or `/responses`
itself. Applies to every OpenAI-compatible client (DeepSeek, Qwen, Together,
Fireworks, Groq, Mistral, xAI, Gemini's OpenAI-compatible endpoint).

## Auth

Two separate credentials, two separate headers:

| Header | Value |
|---|---|
| `Authorization: Bearer …` | The application's **own OpenAI key**. Forwarded upstream. |
| `x-spendline-key` | The **Spendline** key. Consumed by Spendline, stripped before forwarding. |

## Python

```python
import os
from openai import OpenAI

client = OpenAI(
    base_url="https://www.spendline.ai/v1",
    api_key=os.environ["OPENAI_API_KEY"],
    default_headers={
        "x-spendline-key": os.environ["SPENDLINE_API_KEY"],
        "x-agent-id": "doc-summarizer",
        "x-spendline-tags": '{"team":"platform","env":"prod"}',
    },
)

resp = client.chat.completions.create(
    model="gpt-5.6",
    messages=[{"role": "user", "content": "Summarise this."}],
    extra_headers={"x-customer-id": customer_id},   # per request
)
```

## TypeScript

```ts
import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://www.spendline.ai/v1",
  apiKey: process.env.OPENAI_API_KEY!,
  defaultHeaders: {
    "x-spendline-key": process.env.SPENDLINE_API_KEY!,
    "x-agent-id": "doc-summarizer",
    "x-spendline-tags": '{"team":"platform","env":"prod"}',
  },
});

const resp = await client.chat.completions.create(
  { model: "gpt-5.6", messages: [{ role: "user", content: "Summarise this." }] },
  { headers: { "x-customer-id": customerId } },
);
```

## Streaming

Supported on `/v1/chat/completions`. Pass `stream: true` as normal. Spendline
streams the response through and records usage when the stream completes.

## Responses API

`POST https://www.spendline.ai/v1/responses`: same base URL.

- **Non-streaming only.** `stream: true` is rejected with a clear error.
- OpenAI models only.
- Built-in tools such as `web_search` work, and their cost is included in the
  recorded spend.

```python
resp = client.responses.create(
    model="gpt-5.6",
    input="What changed in our pricing page this week?",
    tools=[{"type": "web_search"}],
    extra_headers={"x-customer-id": customer_id},
)
```

## Framework wrappers

**LangChain**: `ChatOpenAI(base_url=..., default_headers={...})`.

**Vercel AI SDK**, 
`createOpenAI({ baseURL: "https://www.spendline.ai/v1", headers: {...} })`.

In every framework, `x-customer-id` must still vary per request. Pass headers
at call time where the framework allows it, or construct the client where the
customer is known.

## Not proxied

Embeddings, image generation, audio and vector search. Leave those pointed at
`api.openai.com`.
