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

# Create embeddings

The OpenAI Embeddings API, for embedding models the node serves (`b3os.kind` is `embedding`). Other models return `404 model_not_available`; the beta node serves no embedding model yet. Bills input tokens. 

` POST /v1/infer/embeddings `

Create embeddings

The OpenAI Embeddings API, for embedding models the node serves (`b3os.kind` is `embedding`). Other models
return `404 model_not_available`; the beta node serves no embedding model yet. Bills input tokens.


## Servers

- ` https://beta-api.b3os.org ` — API (API keys and CLI tokens)

- ` https://beta.b3os.org ` — Dashboard (session cookie and CSRF header; same paths)

## Authentication

The operation accepts these alternatives. Schemes within one alternative are required together.

### Alternative 1

- ` apiKey `: ` http `

  - HTTP scheme: ` bearer ` (b3os_sk_ API key or b3os_pat_ token)

  - `Authorization: Bearer <credential>`. Two credential kinds are accepted:

- **API keys** `b3os_sk_<32 base32>_<crc32>`, created in the dashboard or with `POST /v1/keys`. A key belongs to
  one project, has scopes, an optional spend cap and expiry, and is shown only once.
- **CLI tokens** `b3os_pat_<32 base32>_<crc32>`, issued by the device login (`b3os login`). They act for one
  user in the organization and project chosen at approval.

Keys are stored as SHA-256 hashes. The edge exchanges them for a 60-second node token before forwarding
a request to a node, so nodes never see your key.


### Alternative 2

- ` session `: ` apiKey `

  - Credential: ` __Host-b3os_session ` in ` cookie `

  - The dashboard session cookie on `beta.b3os.org` (host-only, `Secure`, `HttpOnly`). Requests other than
`GET`/`HEAD` must also send `x-b3os-csrf: <csrf_token>` from `GET /v1/auth/session`; SameSite is not relied
on. The cookie is never sent to `beta-api.b3os.org` or `usercontent.b3os.org`.


## Request body (required)

Content type: ` application/json `

- ` value `: type ` object `

  - Required fields: ` model `, ` input `

  - ` model `: type ` string `

  - ` input `: type ` unknown `

    - ` oneOf alternative 1 `: type ` string `

    - ` oneOf alternative 2 `: type ` array `

      - ` array item `: type ` string `

    - ` oneOf alternative 3 `: type ` array `

      - ` array item `: type ` integer `

    - ` oneOf alternative 4 `: type ` array `

      - ` array item `: type ` array `

        - ` array item `: type ` integer `

  - ` encoding_format `: type ` string `

    - enum: ` ["float","base64"] `

    - default: ` "float" `

  - ` dimensions `: type ` integer `

    - minimum: ` 1 `

    - maximum: ` 65536 `

  - ` user `: type ` string `

Example:

```json
{
  "model": "b3os/bge-m3",
  "input": [
    "The loop stays on one machine."
  ]
}
```

## Responses

### ` 200 ` — The embeddings.

Content type: ` application/json `

- ` value `: type ` object `

  - Required fields: ` object `, ` data `, ` model `, ` usage `

  - ` object `: type ` string `

    - enum: ` ["list"] `

  - ` data `: type ` array `

    - ` array item `: type ` object `

      - Required fields: ` object `, ` index `, ` embedding `

      - ` object `: type ` string `

        - enum: ` ["embedding"] `

      - ` index `: type ` integer `

      - ` embedding `: type ` unknown `

        - ` oneOf alternative 1 `: type ` array `

          - ` array item `: type ` number `

        - ` oneOf alternative 2 `: type ` string ` — Base64 of little-endian float32 values (`encoding_format: base64`).

  - ` model `: type ` string `

  - ` usage `: type ` object `

    - Required fields: ` prompt_tokens `, ` total_tokens `

    - ` prompt_tokens `: type ` integer `

    - ` total_tokens `: type ` integer `

Response header ` x-request-id ` — The request ID (`req_…`). It is the `instance` of any problem and the key for `GET /v1/requests/{request_id}`.

- ` value `: type ` string `

  - pattern: ` "^req_[0-9a-hjkmnp-tv-z]{26}$" `

Response header ` Server-Timing ` — Phase durations in milliseconds (W3C Server Timing); the handler's phases break the request down. For a
response whose body size is known, `total` runs from reading the request head to writing the response head.
Streaming responses (event streams, WebSockets, chunked bodies) carry no `total` here: they report their
final phases in the terminal event (`job.succeeded`, `job.failed`, `job.canceled`) or the final job. The
time from the first request byte to the last response byte is recorded in the node's metrics and request
log (`GET /v1/requests/{request_id}`). The edge prepends `edge_auth` and `edge_upstream`.


- ` value `: type ` string `

Example:

```json
{
  "object": "list",
  "data": [
    {
      "object": "embedding",
      "index": 0,
      "embedding": [
        0.0123,
        -0.0456,
        0.0789
      ]
    }
  ],
  "model": "b3os/bge-m3",
  "usage": {
    "prompt_tokens": 8,
    "total_tokens": 8
  }
}
```

### ` 400 ` — The request is invalid (`invalid_request`, `unsupported_parameter`, `context_length_exceeded`).

Content type: ` application/json `

- ` value `: type ` object ` — The OpenAI error body. `code` is the B3OS error code; `x-request-id` carries the request ID.

  - Required fields: ` error `

  - ` error `: type ` object `

    - Required fields: ` message `, ` type `, ` param `, ` code `

    - ` message `: type ` string `

    - ` type `: type ` string ` — `invalid_request_error`, `authentication_error`, `permission_error`, `rate_limit_error` or `server_error`.

    - ` param `: type ` string `; nullable

    - ` code `: type ` string `; nullable

Response header ` x-request-id ` — The request ID (`req_…`). It is the `instance` of any problem and the key for `GET /v1/requests/{request_id}`.

- ` value `: type ` string `

  - pattern: ` "^req_[0-9a-hjkmnp-tv-z]{26}$" `

Response header ` Server-Timing ` — Phase durations in milliseconds (W3C Server Timing); the handler's phases break the request down. For a
response whose body size is known, `total` runs from reading the request head to writing the response head.
Streaming responses (event streams, WebSockets, chunked bodies) carry no `total` here: they report their
final phases in the terminal event (`job.succeeded`, `job.failed`, `job.canceled`) or the final job. The
time from the first request byte to the last response byte is recorded in the node's metrics and request
log (`GET /v1/requests/{request_id}`). The edge prepends `edge_auth` and `edge_upstream`.


- ` value `: type ` string `

Example:

```json
{
  "error": {
    "message": "prompt_logprobs is not supported on this node",
    "type": "invalid_request_error",
    "param": "prompt_logprobs",
    "code": "unsupported_parameter"
  }
}
```

### ` 401 ` — Missing or invalid credentials (`unauthorized`).

Content type: ` application/json `

- ` value `: type ` object ` — The OpenAI error body. `code` is the B3OS error code; `x-request-id` carries the request ID.

  - Required fields: ` error `

  - ` error `: type ` object `

    - Required fields: ` message `, ` type `, ` param `, ` code `

    - ` message `: type ` string `

    - ` type `: type ` string ` — `invalid_request_error`, `authentication_error`, `permission_error`, `rate_limit_error` or `server_error`.

    - ` param `: type ` string `; nullable

    - ` code `: type ` string `; nullable

Response header ` x-request-id ` — The request ID (`req_…`). It is the `instance` of any problem and the key for `GET /v1/requests/{request_id}`.

- ` value `: type ` string `

  - pattern: ` "^req_[0-9a-hjkmnp-tv-z]{26}$" `

Response header ` Server-Timing ` — Phase durations in milliseconds (W3C Server Timing); the handler's phases break the request down. For a
response whose body size is known, `total` runs from reading the request head to writing the response head.
Streaming responses (event streams, WebSockets, chunked bodies) carry no `total` here: they report their
final phases in the terminal event (`job.succeeded`, `job.failed`, `job.canceled`) or the final job. The
time from the first request byte to the last response byte is recorded in the node's metrics and request
log (`GET /v1/requests/{request_id}`). The edge prepends `edge_auth` and `edge_upstream`.


- ` value `: type ` string `

Example:

```json
{
  "error": {
    "message": "API key checksum does not match; check that the whole key was copied",
    "type": "authentication_error",
    "param": null,
    "code": "unauthorized"
  }
}
```

### ` 403 ` — The key lacks `infer:run` or `infer:read` (`forbidden`), or the egress guard refused an image URL (`egress_denied`).

Content type: ` application/json `

- ` value `: type ` object ` — The OpenAI error body. `code` is the B3OS error code; `x-request-id` carries the request ID.

  - Required fields: ` error `

  - ` error `: type ` object `

    - Required fields: ` message `, ` type `, ` param `, ` code `

    - ` message `: type ` string `

    - ` type `: type ` string ` — `invalid_request_error`, `authentication_error`, `permission_error`, `rate_limit_error` or `server_error`.

    - ` param `: type ` string `; nullable

    - ` code `: type ` string `; nullable

Response header ` x-request-id ` — The request ID (`req_…`). It is the `instance` of any problem and the key for `GET /v1/requests/{request_id}`.

- ` value `: type ` string `

  - pattern: ` "^req_[0-9a-hjkmnp-tv-z]{26}$" `

Response header ` Server-Timing ` — Phase durations in milliseconds (W3C Server Timing); the handler's phases break the request down. For a
response whose body size is known, `total` runs from reading the request head to writing the response head.
Streaming responses (event streams, WebSockets, chunked bodies) carry no `total` here: they report their
final phases in the terminal event (`job.succeeded`, `job.failed`, `job.canceled`) or the final job. The
time from the first request byte to the last response byte is recorded in the node's metrics and request
log (`GET /v1/requests/{request_id}`). The edge prepends `edge_auth` and `edge_upstream`.


- ` value `: type ` string `

### ` 404 ` — The model is not served on this node (`model_not_available`).

Content type: ` application/json `

- ` value `: type ` object ` — The OpenAI error body. `code` is the B3OS error code; `x-request-id` carries the request ID.

  - Required fields: ` error `

  - ` error `: type ` object `

    - Required fields: ` message `, ` type `, ` param `, ` code `

    - ` message `: type ` string `

    - ` type `: type ` string ` — `invalid_request_error`, `authentication_error`, `permission_error`, `rate_limit_error` or `server_error`.

    - ` param `: type ` string `; nullable

    - ` code `: type ` string `; nullable

Response header ` x-request-id ` — The request ID (`req_…`). It is the `instance` of any problem and the key for `GET /v1/requests/{request_id}`.

- ` value `: type ` string `

  - pattern: ` "^req_[0-9a-hjkmnp-tv-z]{26}$" `

Response header ` Server-Timing ` — Phase durations in milliseconds (W3C Server Timing); the handler's phases break the request down. For a
response whose body size is known, `total` runs from reading the request head to writing the response head.
Streaming responses (event streams, WebSockets, chunked bodies) carry no `total` here: they report their
final phases in the terminal event (`job.succeeded`, `job.failed`, `job.canceled`) or the final job. The
time from the first request byte to the last response byte is recorded in the node's metrics and request
log (`GET /v1/requests/{request_id}`). The edge prepends `edge_auth` and `edge_upstream`.


- ` value `: type ` string `

Example:

```json
{
  "error": {
    "message": "gpt-5 is not served on this node; set \"route\":\"gateway\" to use the B3IQ gateway",
    "type": "invalid_request_error",
    "param": "model",
    "code": "model_not_available"
  }
}
```

### ` 413 ` — The request body exceeds the model's `max_request_bytes` (`payload_too_large`).

Content type: ` application/json `

- ` value `: type ` object ` — The OpenAI error body. `code` is the B3OS error code; `x-request-id` carries the request ID.

  - Required fields: ` error `

  - ` error `: type ` object `

    - Required fields: ` message `, ` type `, ` param `, ` code `

    - ` message `: type ` string `

    - ` type `: type ` string ` — `invalid_request_error`, `authentication_error`, `permission_error`, `rate_limit_error` or `server_error`.

    - ` param `: type ` string `; nullable

    - ` code `: type ` string `; nullable

Response header ` x-request-id ` — The request ID (`req_…`). It is the `instance` of any problem and the key for `GET /v1/requests/{request_id}`.

- ` value `: type ` string `

  - pattern: ` "^req_[0-9a-hjkmnp-tv-z]{26}$" `

Response header ` Server-Timing ` — Phase durations in milliseconds (W3C Server Timing); the handler's phases break the request down. For a
response whose body size is known, `total` runs from reading the request head to writing the response head.
Streaming responses (event streams, WebSockets, chunked bodies) carry no `total` here: they report their
final phases in the terminal event (`job.succeeded`, `job.failed`, `job.canceled`) or the final job. The
time from the first request byte to the last response byte is recorded in the node's metrics and request
log (`GET /v1/requests/{request_id}`). The edge prepends `edge_auth` and `edge_upstream`.


- ` value `: type ` string `

Example:

```json
{
  "error": {
    "message": "Request body is 12582912 bytes; this model accepts at most 10485760",
    "type": "invalid_request_error",
    "param": null,
    "code": "payload_too_large"
  }
}
```

### ` 415 ` — The body is not JSON (`unsupported_media_type`): send `Content-Type: application/json`.

Content type: ` application/json `

- ` value `: type ` object ` — The OpenAI error body. `code` is the B3OS error code; `x-request-id` carries the request ID.

  - Required fields: ` error `

  - ` error `: type ` object `

    - Required fields: ` message `, ` type `, ` param `, ` code `

    - ` message `: type ` string `

    - ` type `: type ` string ` — `invalid_request_error`, `authentication_error`, `permission_error`, `rate_limit_error` or `server_error`.

    - ` param `: type ` string `; nullable

    - ` code `: type ` string `; nullable

Response header ` x-request-id ` — The request ID (`req_…`). It is the `instance` of any problem and the key for `GET /v1/requests/{request_id}`.

- ` value `: type ` string `

  - pattern: ` "^req_[0-9a-hjkmnp-tv-z]{26}$" `

Response header ` Server-Timing ` — Phase durations in milliseconds (W3C Server Timing); the handler's phases break the request down. For a
response whose body size is known, `total` runs from reading the request head to writing the response head.
Streaming responses (event streams, WebSockets, chunked bodies) carry no `total` here: they report their
final phases in the terminal event (`job.succeeded`, `job.failed`, `job.canceled`) or the final job. The
time from the first request byte to the last response byte is recorded in the node's metrics and request
log (`GET /v1/requests/{request_id}`). The edge prepends `edge_auth` and `edge_upstream`.


- ` value `: type ` string `

Example:

```json
{
  "error": {
    "message": "expected Content-Type: application/json",
    "type": "invalid_request_error",
    "param": null,
    "code": "unsupported_media_type"
  }
}
```

### ` 429 ` — A limit applies (`rate_limited` for requests, tokens or remote image bytes per minute, `concurrency_limited` for requests in flight for the organization, `quota_exceeded`; `credits_exhausted` arrives as 402).

Content type: ` application/json `

- ` value `: type ` object ` — The OpenAI error body. `code` is the B3OS error code; `x-request-id` carries the request ID.

  - Required fields: ` error `

  - ` error `: type ` object `

    - Required fields: ` message `, ` type `, ` param `, ` code `

    - ` message `: type ` string `

    - ` type `: type ` string ` — `invalid_request_error`, `authentication_error`, `permission_error`, `rate_limit_error` or `server_error`.

    - ` param `: type ` string `; nullable

    - ` code `: type ` string `; nullable

Response header ` x-request-id ` — The request ID (`req_…`). It is the `instance` of any problem and the key for `GET /v1/requests/{request_id}`.

- ` value `: type ` string `

  - pattern: ` "^req_[0-9a-hjkmnp-tv-z]{26}$" `

Response header ` Server-Timing ` — Phase durations in milliseconds (W3C Server Timing); the handler's phases break the request down. For a
response whose body size is known, `total` runs from reading the request head to writing the response head.
Streaming responses (event streams, WebSockets, chunked bodies) carry no `total` here: they report their
final phases in the terminal event (`job.succeeded`, `job.failed`, `job.canceled`) or the final job. The
time from the first request byte to the last response byte is recorded in the node's metrics and request
log (`GET /v1/requests/{request_id}`). The edge prepends `edge_auth` and `edge_upstream`.


- ` value `: type ` string `

Response header ` Retry-After ` — Seconds to wait before retrying or polling again.

- ` value `: type ` integer `

  - minimum: ` 0 `

Response header ` RateLimit-Limit ` — Requests allowed in the current window for the limit that applies to this operation.

- ` value `: type ` integer `

Response header ` RateLimit-Remaining ` — Requests left in the current window.

- ` value `: type ` integer `

Response header ` RateLimit-Reset ` — Seconds until the current window resets.

- ` value `: type ` integer `

Example:

```json
{
  "error": {
    "message": "200000 tokens per minute allowed on b3os/qwen3.5-9b; retry in 9 seconds",
    "type": "rate_limit_error",
    "param": null,
    "code": "rate_limited"
  }
}
```

### ` 500 ` — Something failed inside B3OS (`internal`).

Content type: ` application/json `

- ` value `: type ` object ` — The OpenAI error body. `code` is the B3OS error code; `x-request-id` carries the request ID.

  - Required fields: ` error `

  - ` error `: type ` object `

    - Required fields: ` message `, ` type `, ` param `, ` code `

    - ` message `: type ` string `

    - ` type `: type ` string ` — `invalid_request_error`, `authentication_error`, `permission_error`, `rate_limit_error` or `server_error`.

    - ` param `: type ` string `; nullable

    - ` code `: type ` string `; nullable

Response header ` x-request-id ` — The request ID (`req_…`). It is the `instance` of any problem and the key for `GET /v1/requests/{request_id}`.

- ` value `: type ` string `

  - pattern: ` "^req_[0-9a-hjkmnp-tv-z]{26}$" `

Response header ` Server-Timing ` — Phase durations in milliseconds (W3C Server Timing); the handler's phases break the request down. For a
response whose body size is known, `total` runs from reading the request head to writing the response head.
Streaming responses (event streams, WebSockets, chunked bodies) carry no `total` here: they report their
final phases in the terminal event (`job.succeeded`, `job.failed`, `job.canceled`) or the final job. The
time from the first request byte to the last response byte is recorded in the node's metrics and request
log (`GET /v1/requests/{request_id}`). The edge prepends `edge_auth` and `edge_upstream`.


- ` value `: type ` string `

Example:

```json
{
  "error": {
    "message": "internal error (request req_01m5t4yg394wegr3j4y01qb363)",
    "type": "server_error",
    "param": null,
    "code": "internal"
  }
}
```

### ` 503 ` — The model runtime, the voice service or the B3IQ gateway route is restarting, overloaded or not set up on
this node (`infer_backend_unavailable`, `capacity_unavailable`), or the node is unavailable
(`node_unavailable`).


Content type: ` application/json `

- ` value `: type ` object ` — The OpenAI error body. `code` is the B3OS error code; `x-request-id` carries the request ID.

  - Required fields: ` error `

  - ` error `: type ` object `

    - Required fields: ` message `, ` type `, ` param `, ` code `

    - ` message `: type ` string `

    - ` type `: type ` string ` — `invalid_request_error`, `authentication_error`, `permission_error`, `rate_limit_error` or `server_error`.

    - ` param `: type ` string `; nullable

    - ` code `: type ` string `; nullable

Response header ` x-request-id ` — The request ID (`req_…`). It is the `instance` of any problem and the key for `GET /v1/requests/{request_id}`.

- ` value `: type ` string `

  - pattern: ` "^req_[0-9a-hjkmnp-tv-z]{26}$" `

Response header ` Server-Timing ` — Phase durations in milliseconds (W3C Server Timing); the handler's phases break the request down. For a
response whose body size is known, `total` runs from reading the request head to writing the response head.
Streaming responses (event streams, WebSockets, chunked bodies) carry no `total` here: they report their
final phases in the terminal event (`job.succeeded`, `job.failed`, `job.canceled`) or the final job. The
time from the first request byte to the last response byte is recorded in the node's metrics and request
log (`GET /v1/requests/{request_id}`). The edge prepends `edge_auth` and `edge_upstream`.


- ` value `: type ` string `

Response header ` Retry-After ` — Seconds to wait before retrying or polling again.

- ` value `: type ` integer `

  - minimum: ` 0 `

Example:

```json
{
  "error": {
    "message": "The model runtime on n1 is restarting; retry in 5 seconds",
    "type": "server_error",
    "param": null,
    "code": "infer_backend_unavailable"
  }
}
```

## Request examples

### cURL

```curl
curl -X POST 'https://beta-api.b3os.org/v1/infer/embeddings' \
  -H 'Authorization: Bearer YOUR_API_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
  "model": "b3os/bge-m3",
  "input": [
    "The loop stays on one machine."
  ]
}'
```

### JavaScript

```javascript
const response = await fetch('https://beta-api.b3os.org/v1/infer/embeddings', {
  method: 'POST',
  headers: {
      "Authorization": "Bearer YOUR_API_TOKEN",
      "Content-Type": "application/json"
  },
  body: JSON.stringify({
    "model": "b3os/bge-m3",
    "input": [
      "The loop stays on one machine."
    ]
  })
});

const data = await response.json();
console.log(data);
```

### Python

```python
import requests

headers = {
    'Authorization': 'Bearer YOUR_API_TOKEN'
}

response = requests.post('https://beta-api.b3os.org/v1/infer/embeddings', headers=headers, json={
  "model": "b3os/bge-m3",
  "input": [
    "The loop stays on one machine."
  ]
})
print(response.json())
```