# OpenAI-compatible endpoints

KolWrite's managed AI answers on the same shapes as the OpenAI API. Point an
OpenAI SDK, or any tool that lets you set a base URL, at KolWrite and use a
personal access token as the API key:

```
Base URL: https://api.kolwrite.com/api/v1/ai/openai
API key:  your kol_... token (scope ai:use)
```

Calls spend credits from the account that owns the token, metered per token of
usage. They are separate from transcription jobs (see the
[agents guide](/agents.md)).

## Requirements

- The token has the `ai:use` scope. The app's Automation preset does not include
  it, so tick it when you create the token.
- The token was created from a signed-in KolWrite app session. Older tokens that
  are not bound to a product are refused with `legal_product_required`: create a
  new one.
- The account has accepted the current third-party AI disclosure in the app.
  Until then the API answers HTTP 428 with `legal_acceptance_required`.
- API access is enabled for the account (Settings → Account → API access).

## Endpoints

| Endpoint | What it does |
|---|---|
| `GET /models` | The models you can use, with `credit_pricing` for each |
| `POST /chat/completions` | Chat completions, with streaming (`"stream": true`) |
| `POST /responses` | The Responses API |
| `POST /embeddings` | Embeddings |
| `POST /audio/transcriptions` | Text for a short voice clip (multipart `file`) |
| `POST /images/generations` | Image generation |

Models are named by stable aliases: `kw-auto` (routes between a fast and a
stronger model), `kw-fast` and `kw-pro`. `GET /models` is the source of truth for
what is available to your token; each entry reports `context_window` and
whether it supports tools, vision and audio.

## Python

```python
import os
from openai import OpenAI

client = OpenAI(
    base_url="https://api.kolwrite.com/api/v1/ai/openai",
    api_key=os.environ["KOLWRITE_TOKEN"],
)

reply = client.chat.completions.create(
    model="kw-auto",
    messages=[{"role": "user", "content": "Summarize this transcript in five bullets: ..."}],
)
print(reply.choices[0].message.content)

vectors = client.embeddings.create(model="kw-embedding", input=["first text", "second text"])
```

## JavaScript

```js
import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://api.kolwrite.com/api/v1/ai/openai",
  apiKey: process.env.KOLWRITE_TOKEN,
});

const stream = await client.chat.completions.create({
  model: "kw-fast",
  messages: [{ role: "user", content: "Write a title for this meeting." }],
  stream: true,
});
for await (const chunk of stream) process.stdout.write(chunk.choices[0]?.delta?.content ?? "");
```

## curl

```bash
curl https://api.kolwrite.com/api/v1/ai/openai/chat/completions \
  -H "Authorization: Bearer $KOLWRITE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"model": "kw-auto", "messages": [{"role": "user", "content": "Hello"}]}'

curl https://api.kolwrite.com/api/v1/ai/openai/audio/transcriptions \
  -H "Authorization: Bearer $KOLWRITE_TOKEN" \
  -F file=@clip.wav -F model=kw-fast -F language=auto
```

## Short clips or a full recording?

`/audio/transcriptions` is a fast path for short clips: one request, one answer,
no job. It does not make speaker labels or the saved, versioned transcript. For a
meeting, an interview or a long file, upload the media and create a transcription
job instead: it returns word timings, speakers, SRT and VTT.

With `want_words=true` the clip answer also carries `words` as `{w, start, end}`
in seconds from the start of the clip.

## What is different from OpenAI

- Model names are KolWrite aliases, not OpenAI model names.
- The token is a KolWrite personal access token, billed in KolWrite credits.
- `kw-max` is not available with API tokens.
- Errors use `detail.code`, as in [errors](/errors.md).

## Questions

### Can I use the OpenAI SDK with KolWrite?

Yes. Set the base URL to `https://api.kolwrite.com/api/v1/ai/openai` and the API
key to a KolWrite token with the `ai:use` scope.

### Does it support streaming and tools?

Chat completions stream with `"stream": true`. `GET /models` tells you, per
model, whether it supports tools, vision and audio.

### Which endpoint transcribes audio?

`POST /audio/transcriptions` for short clips; transcription jobs for everything
else.
