Skip to content

Rerank

POST /v1/rerank takes a query and a list of candidate documents and returns them reordered by relevance, each with a score. Use it as the precision stage at the end of a retrieval pipeline: a fast first stage (vector search, BM25 or your existing store) pulls a top-k pool, then /v1/rerank sharpens the ordering of that pool before you show results or feed them to a generator.

The current reranker is a bi-encoder. It embeds the query and each candidate independently and scores them by cosine similarity, returning the ranked list truncated to top_k. Because the candidates can be embedded ahead of time, this is cheap and fast, which makes it a practical refinement pass over a top-k pool.

A bi-encoder scores the query and the document separately, so it cannot model fine-grained interactions between specific query and document tokens. A cross-encoder, which reads the query and document together in a single pass, captures those interactions and is the stronger reranker. A cross-encoder reranker is on the roadmap. We would rather state that plainly than overclaim the current stage.

/v1/rerank is a flinq-native endpoint, called with a plain HTTP client. model is required.

curl https://api.flinq.ai/v1/rerank \
-H "Authorization: Bearer flq_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"model": "flinq-pilot-wombat",
"query": "Stahlbetondecke d = 20 cm, C25/30, XC1",
"documents": [
"Ortbetondecke Stahlbeton, Dicke 20 cm, Beton C25/30, Expositionsklasse XC1",
"Filigrandecke Stahlbeton, Elementdicke 5 cm, statisch mitwirkend",
"Trapezblechdecke verzinkt, Stützweite 3,0 m"
],
"top_k": 3
}'
{
"object": "rerank",
"model": "flinq-pilot-wombat",
"data": [
{
"index": 0,
"relevance_score": 0.8421,
"text": "Ortbetondecke Stahlbeton, Dicke 20 cm, Beton C25/30, Expositionsklasse XC1"
},
{
"index": 1,
"relevance_score": 0.6133,
"text": "Filigrandecke Stahlbeton, Elementdicke 5 cm, statisch mitwirkend"
},
{
"index": 2,
"relevance_score": 0.2987,
"text": "Trapezblechdecke verzinkt, Stützweite 3,0 m"
}
],
"usage": { "prompt_tokens": 71, "total_tokens": 71 }
}

Each hit keeps the original index into your documents array, a relevance_score (cosine similarity, higher is more relevant), and the text.

ParameterTypeRequiredDefaultDescription
modelstringyesPilot model id. Unknown ids return 404.
querystringyesThe query the pool is scored against, truncated at 512 tokens.
documentsstring[]yesCandidate pool from your first retrieval stage. Per-model cap: 2048 (otter) / 256 (wombat). Typical rerank pools are 20–200 documents.
top_kintegernoallHow many of the reranked hits to return. Omit it to get the full pool reordered.
dimensionsintegerno1024Matryoshka slice to score on (1024/768/512/256/128). Useful to match the slice your index retrieves on.

Headers. Authorization: Bearer flq_... (required); Idempotency-Key (optional) deduplicates the charge on retries.

Response fields.

FieldTypeDescription
data[i].indexintegerPosition of the hit in your documents array — map results back through this, not through text.
data[i].relevance_scorefloatCosine similarity of query and document (higher = more relevant). Comparable across requests of the same model; not comparable across models.
data[i].textstringThe document text, echoed back.
usage.total_tokensintegerBilled tokens, Voyage formula (below).

Billing. Rerank uses the Voyage formula: tokens(query) × len(documents) + Σ tokens(documents), at EUR 0.40 / 1M. The query is charged once per candidate, so a long query against a large pool is the expensive shape — keep queries tight, pools pre-filtered.