Skip to content

Embeddings

An embedding is a numeric fingerprint of a piece of text. The model reads a string and returns a vector, a fixed-length list of numbers, positioned so that texts with similar meaning land close together and unrelated texts land far apart. Once your text lives as vectors, “find the most relevant document” becomes “find the nearest vector”, which databases do quickly and at scale. Embeddings are the substrate underneath semantic search, retrieval-augmented generation, clustering, deduplication and classification.

The pilot models are specialized on the European construction (AEC) domain, with German as its deepest-trained language today. See Models for the full spec table.

Because every vector is L2-normalized, cosine similarity is just a dot product, and you can compare two vectors by multiplying and summing. If your store wants inner product, you can use it directly.

/v1/embeddings is OpenAI-compatible, so the OpenAI SDKs work unchanged — set the base_url and pass a flinq model id (required; see Models).

curl https://api.flinq.ai/v1/embeddings \
-H "Authorization: Bearer flq_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"model": "flinq-pilot-otter",
"input": ["Stahlbetonfertigteildecke d = 20 cm", "Bewehrungsanschluss BSt 500"],
"dimensions": 512
}'

The response mirrors the OpenAI layout: data[i].embedding is the L2-normalized vector for input[i], and usage carries the billed token count.

ParameterTypeRequiredDefaultDescription
modelstringyesPilot model id (flinq-pilot-otter or flinq-pilot-wombat). Unknown ids return 404 with the list of available models; discover them via GET /v1/models.
inputstring or string[]yesText(s) to embed. The per-request cap is per model: 2048 inputs (otter) / 256 (wombat); over the cap returns 422. Each text is truncated at 512 tokens — longer texts are cut silently, so chunk long documents yourself.
dimensionsintegerno1024Matryoshka output size: 1024, 768, 512, 256 or 128. The server truncates the native vector to the first N components and re-normalizes. Smaller = cheaper storage and faster ANN at a small quality cost. Same price — billing counts input tokens, not output size.
encoding_formatstringno"float"Accepted for OpenAI compatibility; only "float" (JSON number arrays) is currently served.

Headers. Authorization: Bearer flq_... (required). Optionally send an Idempotency-Key header: if you retry a request with the same key (e.g. after a network timeout), the charge is deduplicated — you are never billed twice for the same logical request.

Response fields.

FieldTypeDescription
data[i].indexintegerPosition of this vector in your input array — order is always preserved.
data[i].embeddingfloat[]L2-normalized vector (dimensions long). Cosine similarity = plain dot product.
modelstringThe model that actually served the request — always exactly the id you sent.
usage.total_tokensintegerBilled tokens, counted server-side with the model’s own tokenizer (not whitespace).

Billing. tokens(input) × EUR 0.40 / 1M. A request rejected before inference (unknown model, over the input cap, bad schema) costs nothing.

The model is trained so that the first N components of the 1024-dim vector remain a faithful, self-contained embedding on their own. That is the Matryoshka property: nest a smaller vector inside the larger one. Request dimensions of 768, 512, 256 or 128 and flinq truncates to that prefix and re-normalizes.

The tradeoff is concrete. A 256-dim vector is a quarter of the storage and roughly a quarter of the nearest-neighbor work of a 1024-dim vector, for a small drop in retrieval quality. You pick the point on that curve that fits your index budget and latency target, without re-embedding your corpus.

General-purpose embedding APIs are trained on broad web text. On construction language they fail in two specific, repeatable ways.

German builds long compounds: Stahlbetonfertigteildecke, Dämmerungsschalter, Bewehrungsanschluss. A generic tokenizer shreds these into subword fragments and the model averages them into a vague blur, losing the precise object the compound names. flinq is tuned on this vocabulary, so the compound resolves to the thing it actually denotes rather than to a smeared average of its parts.

In construction, a single token is the difference between right and wrong. DN 100 and DN 150 are different pipe diameters. C20/25 and C25/30 are different concrete strength classes. XC4 is a specific exposure class. Generic models treat these as near-identical because they look alike as strings, and they confidently return the wrong one. flinq is trained to keep these distinctions sharp. For the cases where lexical precision must be absolute, the hybrid search endpoint adds a BM25 leg that anchors on the exact code or unit.