API
Embeddings
Vectors from the Spark class, billed on input tokens only — the cheapest thing on the network, and the one with the sharpest footgun.
Endpoint
const res = await client.embeddings.create({ model: "bge-m3", input: ["the first passage", "the second passage"],}); console.log(res.data[0].embedding.length); // 1024| Field | Type | Description |
|---|---|---|
| modelrequired | string | Currently bge-m3 at F16, 1024 dimensions, 8192-token context. |
| inputrequired | string | string[] | One passage or a batch. Up to 256 items per request. |
| encoding_format | string | float (default) or base64. Base64 is roughly a third of the bytes over the wire for large batches. |
{ "object": "list", "model": "bge-m3", "data": [ { "object": "embedding", "index": 0, "embedding": [0.0123, -0.0456, "..."] }, { "object": "embedding", "index": 1, "embedding": [0.0789, -0.0012, "..."] } ], "usage": { "prompt_tokens": 12, "total_tokens": 12 }, "vacuum": { "receipt": "0x41ab77e0c9d2358f", "node": "vac1qp82ne6tz0k4wxv", "epoch": 2926, "cost_usdc": "0.000000144" }}Batching
Embedding models are small, so the round trip dominates. One request of 256 passages is dramatically faster than 256 requests of one, and it produces one receipt instead of 256.
- Order is preserved. Match results by the index field, not by position in the array.
- A batch is served by a single node, so it either all succeeds or all fails. There is no partial result to reconcile.
- Passages longer than the context window are rejected rather than silently truncated — you would otherwise be embedding something other than what you sent.
What it costs
Embeddings are billed on input tokens only, at $0.012 per million. There is no output rate because there is no generated text. At that price a million-passage corpus of short documents lands in the low single dollars.
max_tokens the reserved and debited amounts are the same. An embeddings call never refunds.A warning about consistency
Vectors are only comparable when they come from the same model build. On Vacuum that build is pinned by a registry ID that includes the weights hash, the quantization format and the inference engine version — and the catalogue entry bge-m3 resolves to whichever build is current.
If you are populating a vector index you intend to query for months, pin the registry ID rather than the friendly name, and store it next to the index:
{ "model": "bge-m3@0x7c19d3a4f8e2b05617ac9d4e3f1b8266" }When a new build is published, re-embed against it before switching. Mixing builds in one index degrades recall quietly — nothing errors, the results just get worse. See Models for how registry IDs work.