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

# Embeddings

> Turn text into vectors on /v1/embeddings, OpenAI-compatible. Billed on input tokens only.

`POST /v1/embeddings` is drop-in compatible with OpenAI's Embeddings API. Point an
OpenAI client at the gateway, keep your code, and pay from the same credit balance
as every other endpoint.

Embeddings consume **input tokens only** — there is no generated output — so they
are billed on the input rate alone.

## Models

| Model                           | Max input tokens | Dimensions | Input / 1M |
| ------------------------------- | ---------------- | ---------- | ---------- |
| `openai/text-embedding-3-small` | 8,192            | 1,536      | \$0.02     |
| `openai/text-embedding-3-large` | 8,192            | 3,072      | \$0.13     |

Discover them at runtime instead of hardcoding: `GET /v1/models` returns
`output_modality` on every entry, and `embedding` marks the ones this endpoint
serves.

```bash theme={null}
curl https://api.impossibl.com/v1/models \
  | jq '.data[] | select(.output_modality == "embedding") | .id'
```

## Embed one string

```bash theme={null}
curl https://api.impossibl.com/v1/embeddings \
  -H "Authorization: Bearer imp-rt-..." \
  -H 'content-type: application/json' \
  -d '{
    "model": "openai/text-embedding-3-small",
    "input": "the quick brown fox"
  }'
```

```json theme={null}
{
  "object": "list",
  "model": "openai/text-embedding-3-small",
  "data": [
    { "object": "embedding", "index": 0, "embedding": [0.0023, -0.0091, "..."] }
  ],
  "usage": { "prompt_tokens": 4, "total_tokens": 4 }
}
```

## Embed a batch

Pass an array. Results come back in request order, and `index` records each
vector's position in your `input` — so you can zip them straight back onto your
records.

```bash theme={null}
curl https://api.impossibl.com/v1/embeddings \
  -H "Authorization: Bearer imp-rt-..." \
  -H 'content-type: application/json' \
  -d '{
    "model": "openai/text-embedding-3-small",
    "input": ["first document", "second document", "third document"]
  }'
```

Large batches are split into multiple upstream calls automatically and billed as
one request. Each individual string must fit the model's max input tokens, and a
single request is capped at 300,000 tokens across all values.

## OpenAI SDK

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

client = OpenAI(api_key="imp-rt-...", base_url="https://api.impossibl.com/v1")

res = client.embeddings.create(
    model="openai/text-embedding-3-small",
    input=["first document", "second document"],
)
print(len(res.data[0].embedding))  # 1536
```

```javascript theme={null}
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: "imp-rt-...",
  baseURL: "https://api.impossibl.com/v1",
});

const res = await client.embeddings.create({
  model: "openai/text-embedding-3-small",
  input: ["first document", "second document"],
});
console.log(res.data[0].embedding.length); // 1536
```

## Shorter vectors

`dimensions` truncates the vector, trading a little accuracy for storage and index
size. Both `text-embedding-3-*` models support it.

```bash theme={null}
curl https://api.impossibl.com/v1/embeddings \
  -H "Authorization: Bearer imp-rt-..." \
  -H 'content-type: application/json' \
  -d '{
    "model": "openai/text-embedding-3-large",
    "input": "the quick brown fox",
    "dimensions": 256
  }'
```

Billing does not change: you pay for input tokens, not for vector width.

## Compact transport

`encoding_format: "base64"` returns each vector as base64-encoded little-endian
float32 instead of a JSON number array. Same numbers, far fewer bytes on the wire.
The OpenAI SDKs decode it for you; decoding by hand is four lines:

```python theme={null}
import base64, struct

raw = base64.b64decode(res.data[0].embedding)
vector = list(struct.unpack(f"<{len(raw) // 4}f", raw))
```

## Errors

Embedding models are served **only** by this endpoint, and this endpoint serves
**only** embedding models. Cross the streams and you get a `400` naming the right
destination:

```json theme={null}
{
  "error": {
    "message": "openai/gpt-5.4 is not an embedding model. Use /v1/chat/completions.",
    "type": "invalid_request_error"
  }
}
```

Pre-tokenized input (arrays of integers) is not supported — send strings. See
[Errors](/docs/errors) for the full status table.
