# Embeddings

llm.buzz serves embeddings models on the OpenAI Embeddings API, so the OpenAI and OpenRouter SDKs reach them with the base URL alone. Chat Completions, Responses and Messages refuse an embeddings model with a 400 on `model` that names `POST /api/v1/embeddings`.

The route takes your key as a bearer token, as every other model route does ([Authentication](authentication.md)).

## Find an embeddings model

`GET https://api.llm.buzz/api/v1/models` leaves embeddings models out by default: `output_modalities=embeddings` lists them, and `output_modalities=all` lists every model. `GET https://api.llm.buzz/api/v1/embeddings/models` is the same list with that filter fixed, paged with `limit` and `offset`. With your key, both list the embeddings models your key can call; without a key, the public ones.

```bash
curl https://api.llm.buzz/api/v1/embeddings/models
```

An embeddings model lists as `text->embeddings` with its context window. `pricing.prompt` is its input price in US dollars per token, at your rate, and `pricing.completion` is `"0"`: an embeddings call has no output to bill.

The [Models page](/models) lists embeddings models too, and its Output filter picks them out. Each one's page shows its input price per million tokens and its Dimensions: the length of the vectors a request without `dimensions` gets.

## Create embeddings

`POST https://api.llm.buzz/api/v1/embeddings` takes the OpenAI Embeddings API's body and answers in its shape.

```python tab="Python"
from openai import OpenAI
import os

client = OpenAI(
    base_url="https://api.llm.buzz/api/v1",
    api_key=os.environ["LLM_BUZZ_KEY"],
)
result = client.embeddings.create(
    model="qwen/qwen3-embedding-8b",
    input=["first passage", "second passage"],
)
print(len(result.data), len(result.data[0].embedding))
```

```bash tab="curl"
curl https://api.llm.buzz/api/v1/embeddings \
  -H "Authorization: Bearer $LLM_BUZZ_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model": "qwen/qwen3-embedding-8b", "input": ["first passage", "second passage"]}'
```

| Field | Rule |
|---|---|
| `model` | Required: an embeddings model. Another model is a 400 `unsupported_capability` on `model`. |
| `input` | Required: a string, a list of strings, a list of token IDs, or a list of such lists, none of them empty. A flat list of token IDs gets one vector. Token IDs go to the provider unchanged, so they must match the model's tokenizer. |
| `encoding_format` | `float` or `base64`: how the vectors come back. |
| `dimensions` | Sent to the provider as you give it. Without it, the vectors have the model's Dimensions. |
| `provider` | Steers the request as on chat; see [Provider preferences](models-and-routing.md#provider-preferences). |
| `user` | Recorded as the end-user label, and not sent to the provider. |
| `stream` | Leave it out or send `false`. Embeddings are never streamed, and `true` is a 400. |

Fields the route does not know are dropped. The route keeps no answers and ignores an `Idempotency-Key` header, so a retry is a new call, billed again.

The answer:

```json
{"object": "list", "data": [{"object": "embedding", "index": 0, "embedding": [0.0123, -0.0456]}],
 "model": "qwen/qwen3-embedding-8b", "provider": "DeepInfra",
 "usage": {"prompt_tokens": 4, "total_tokens": 4, "cost": 4e-8}}
```

The vectors are the provider's own, one per input. `usage.prompt_tokens` is the input tokens the provider counted, which the call bills, and `usage.cost` is the call's price in US dollars at your rate. `provider` names the provider that answered.

## Billing

An embeddings call bills the input tokens its provider reports, `usage.prompt_tokens`, at that provider's input price and your rate. It has no output price. Your credit, budgets and key limits apply as on chat; [Errors](errors.md) lists the 402 and 403 answers.

- A call that fails over to another provider bills only the provider that answered.
- A call bills nothing when its provider answered an error, or never received the request (the connection was refused, or DNS or TLS failed).
- A timeout, a network fault after the request was sent, or your client disconnecting bills what llm.buzz reserved for the call before calling the provider, since the provider may have done the work and billed it.

## Not supported

Image or other multimodal input to an embeddings model, streaming, and embeddings models in the console's Playground.
