Embeddings
/v1/embeddingsVectors for text, in the OpenAI shape.
Request
modelstringbodyrequiredinputstring|arraybodyrequiredResponses
Response
{
"object": "list",
"data": [
{ "object": "embedding", "index": 0, "embedding": [0.0023, -0.0091, 0.0157] }
],
"usage": { "prompt_tokens": 5, "total_tokens": 5, "cost_usd": "0.0000001" }
}Details
Needs a key in Authorization: Bearer or x-api-key.
A straight pass-through to an OpenAI-compatible upstream: this route has no logic of its own beyond the gateway-wide parts — idempotency, the disabled-model check, the balance check and the cost in the answer. Fields other than those listed (dimensions, encoding_format and the rest) are forwarded untouched. The gateway picks no model for you: model must name an embedding model from the catalog.
This request's cost arrives inside the answer: the x-teamtoken-cost-usd header and usage.cost_usd in the body. The value is a decimal string ("0.0000465"), not a number: a number would be re-displayed by the client language's own float rules (Python would show 4.65e-05), while a string reaches your code exactly as written. The cost can also fail to arrive at all — then it is in neither the header nor the field: on a non-streaming answer when the upstream did not report it, on a stream when the model has no catalog tariff. There is no streaming for embeddings: the gateway reads the whole answer. Moderation does not apply to this path — it is only armed where there is a prompt for a model.
A byte-identical request with the same key inside a short TTL (60 s by default) does not reach the model twice — the gateway returns the first answer's body and charges nothing for the second. Only a successful answer of at most 256 KB is cached; anything else goes upstream again. A replay from the cache carries no x-teamtoken-cost-usd header (nothing was charged), and the cost_usd in its body belongs to the first, paid answer. Hence the corollary: an already-paid answer is served even on an empty wallet — the balance check sits AFTER idempotency. Every error arrives in one envelope (the code field is not on every status): { "error": { "message": "...", "type": "...", "code": "PROVIDER_CODE" } }.
The answer always carries back the logical model name you asked for. If it does not fit the gateway's wait (300 s read by default, 60 s without bytes on a stream) you get a 504; the gateway marks that non-streaming attempt, and if the upstream finished and billed anyway, the reconciler credits the amount back to your balance as a compensating grant. Upstream host names are scrubbed out of error bodies, so an error's text can differ from what the upstream sent.
This path has no route of its own: one gateway handler takes every POST /v1/*, and its list of accepted paths is closed — any other /v1/* answers 404.