Skip to content

Embeddings

An embedding is a list of numbers that captures what a piece of text means. Texts with similar meanings get vectors that sit close together, which is what powers semantic search, retrieval-augmented generation (RAG), recommendations, clustering and deduplication.

POST /v1/embeddings follows the OpenAI format, so client.embeddings.create and every framework built on it work unchanged.

Create embeddings

import OpenAI from "openai";

const client = new OpenAI({ baseURL: "https://api.cloakray.com/v1", apiKey: process.env.CLOAKRAY_API_KEY });

const result = await client.embeddings.create({
  model: "text-embedding-3-small",
  input: ["How do I reset my password?", "Where can I change my login details?"],
});

const [a, b] = result.data.map((item) => item.embedding);
result = client.embeddings.create(
    model="text-embedding-3-small",
    input=["How do I reset my password?", "Where can I change my login details?"],
)
vectors = [item.embedding for item in result.data]
curl https://api.cloakray.com/v1/embeddings \
  -H "Authorization: Bearer $CLOAKRAY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model": "text-embedding-3-small", "input": "The quick brown fox"}'

Parameters

ParameterWhat it does
modelRequired. An embedding model, for example text-embedding-3-small, text-embedding-3-large, gemini-embedding-001, qwen3-embedding-8b or bge-m3.
inputRequired. A string, or an array of strings to embed in one request. Some models also take token IDs.
dimensionsA shorter vector, on models that support it. Smaller vectors are cheaper to store and search.
encoding_formatfloat (default) or base64, which is smaller on the wire.

The response

{
  "object": "list",
  "model": "text-embedding-3-small",
  "data": [
    { "object": "embedding", "index": 0, "embedding": [0.0023, -0.0094, 0.0158] },
    { "object": "embedding", "index": 1, "embedding": [0.0019, -0.0101, 0.0149] }
  ],
  "usage": { "prompt_tokens": 16, "total_tokens": 16 }
}

index matches the position in input. Embeddings are billed on input tokens only; there is no output. usage also carries the charged cost — see usage and cost.

Comparing vectors

Cosine similarity is the usual measure: values close to 1 mean similar meaning.

const cosine = (a, b) => {
  let dot = 0, na = 0, nb = 0;
  for (let i = 0; i < a.length; i++) { dot += a[i] * b[i]; na += a[i] ** 2; nb += b[i] ** 2; }
  return dot / (Math.sqrt(na) * Math.sqrt(nb));
};

Tips

  • Use one model for both your documents and your queries. Vectors from different models (or different dimensions) are not comparable.
  • Batch many texts in one request instead of sending them one by one.
  • Split long documents into passages of a few hundred tokens and embed each; it retrieves better than one vector per document.
  • To reorder search results by relevance after a vector search, add reranking.