Embeddings
Turn text into vectors. OpenAI-compatible canonical schema, with cross-provider input_type normalization.
POST/api/v1/embeddings
SearchRouter adopts OpenAI's /embeddings shape as the canonical schema. The request and response mirror OpenAI, with one added field - input_type - to normalize asymmetric embedding models across providers.
Request
| Parameter | Type | Required | Description |
|---|---|---|---|
| model | string | required | Embedding model slug, e.g. openai/text-embedding-3-small, cohere/embed-v4. |
| input | string | string[] | required | A single string or an array of strings to embed. |
| input_type | "query" | "document" | null | optional | Asymmetric hint - see normalization below. Dropped for symmetric models. |
| dimensions | integer | optional | Output dimensionality, where the provider supports truncation. |
| encoding_format | "float" | "base64" | optional | Encoding of the returned vectors. Default float. |
json
{
"model": "openai/text-embedding-3-small",
"input": "hybrid search combines keyword and vector retrieval",
"input_type": "document",
"dimensions": 1536,
"encoding_format": "float"
}The input_type normalization
Asymmetric embedding models embed queries and documents differently for better retrieval, but every provider names this hint differently and uses a different vocabulary. SearchRouter exposes one field - input_type: "query" | "document" | null - and each adapter maps it to the provider's native parameter (or drops it):
| Provider | Native field | "query" maps to | "document" maps to |
|---|---|---|---|
| Cohere | input_type | search_query | search_document |
| Voyage | input_type | query | document |
| Jina | task | retrieval.query | retrieval.passage |
task_type | RETRIEVAL_QUERY | RETRIEVAL_DOCUMENT | |
| OpenAI / Mistral | - | dropped (no concept) | dropped (no concept) |
✓Rule of thumb. Embed your corpus with
input_type: "document" and your search queries with input_type: "query". For symmetric models the field is safely ignored, so you can set it unconditionally.Response
| Field | Type | Required | Description |
|---|---|---|---|
| object | string | optional | Always list. |
| model | string | optional | The resolved model slug. |
| provider | string | optional | The provider that served the request. |
| data | object[] | optional | Array of { object, index, embedding }, in input order. |
| usage | object | optional | { prompt_tokens, total_tokens, cost } - cost in USD. |
json
{
"object": "list",
"model": "openai/text-embedding-3-small",
"provider": "openai",
"data": [
{ "object": "embedding", "index": 0, "embedding": [0.01, -0.02, ...] }
],
"usage": { "prompt_tokens": 8, "total_tokens": 8, "cost": 0.0000002 }
}Examples
cURL
bash
curl https://searchrouter.ai/api/v1/embeddings \
-H "Authorization: Bearer $SR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "openai/text-embedding-3-small",
"input": ["query text", "document text"],
"input_type": "document"
}'Python
python
import os, requests
resp = requests.post(
"https://searchrouter.ai/api/v1/embeddings",
headers={"Authorization": f"Bearer {os.environ['SR_API_KEY']}"},
json={
"model": "openai/text-embedding-3-small",
"input": "hybrid search combines keyword and vector retrieval",
"input_type": "document",
},
)
resp.raise_for_status()
vector = resp.json()["data"][0]["embedding"]
print(len(vector), "dimensions")JavaScript
javascript
const resp = await fetch("https://searchrouter.ai/api/v1/embeddings", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.SR_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "openai/text-embedding-3-small",
input: "hybrid search combines keyword and vector retrieval",
input_type: "document",
}),
});
const { data } = await resp.json();
console.log(data[0].embedding.length, "dimensions");