Rerank API
Reorders candidate documents by relevance to a query. The model (KURE-Reranker-nano) is a cross-encoder that reads the query and each document together, so it separates real answers from look-alike traps better than embedding similarity. Typically you use it to rerank the top tens of results from a first-stage retriever (KURE-v3, KURE-Sparse, BM25, …).
Authentication and limits are the same as the Embeddings API.
Rerank documents
POST https://kure.kullm.ai/api/v1/rerankRequest body
| Parameter | Type | Required | Description |
|---|---|---|---|
model | string | Yes | kure-reranker-nano, or the snapshot kure-reranker-nano-20261016 (Model IDs and versions) |
query | string | Yes | The search query. Must not be empty. |
documents | string[] | Yes | Documents to rank. At most 100, no empty strings. |
top_n | integer | No | Return only the top N. Defaults to all documents. |
return_documents | boolean | No | Include each document's text in the results. Defaults to false. |
A query–document pair can be up to 8,192 tokens in total. Longer pairs are truncated (longest part first) and scored, not rejected.
Response
{
"id": "rerank-59b5073b…",
"model": "kure-reranker-nano-20261016",
"results": [
{ "index": 1, "relevance_score": 0.9996, "document": { "text": "고려대학교는 서울특별시 성북구 안암로 145에 있다." } },
{ "index": 2, "relevance_score": 0.0073, "document": { "text": "연세대학교는 서울특별시 서대문구 연세로 50에 있다." } }
],
"usage": { "total_tokens": 73 }
}resultsare sorted byrelevance_score, highest first.indexis the position indocuments.relevance_scoreis a relevance probability between 0 and 1 (the sigmoid of the model score). It is on the same scale for every query, so you can set a threshold, for example dropping anything below 0.5.documentis present only whenreturn_documentsistrue.usage.total_tokenssums the tokens of every query–document pair. The query is counted once per document (a 20-token query with 100 documents is 2,000 tokens for the query alone). This is what the rate limit charges.
Example
# pip install requests
import os
import requests
res = requests.post(
"https://kure.kullm.ai/api/v1/rerank",
headers={"Authorization": f"Bearer {os.environ['KURE_API_KEY']}"},
json={
"model": "kure-reranker-nano",
"query": "고려대학교는 어디에 있나요?",
"documents": [
"김치찌개는 김치와 돼지고기를 넣어 끓인다.",
"고려대학교는 서울특별시 성북구 안암로 145에 있다.",
"연세대학교는 서울특별시 서대문구 연세로 50에 있다.",
],
"top_n": 2,
"return_documents": True,
},
)
res.raise_for_status()
for r in res.json()["results"]:
print(f"{r['relevance_score']:.4f} {r['document']['text']}")In a search pipeline
Retrieve broadly first (top 20–100), rerank, and keep only the top few. The first stage can be KURE-v3 embeddings, KURE-Sparse, or both combined in hybrid search.
import os
import numpy as np
import requests
from openai import OpenAI
API = "https://kure.kullm.ai/api/v1"
KEY = os.environ["KURE_API_KEY"]
client = OpenAI(base_url=API, api_key=KEY)
def embed(texts, input_type):
vecs = []
for i in range(0, len(texts), 8): # at most 8 per request
res = client.embeddings.create(
model="kure-v3", input=texts[i : i + 8], dimensions=1024, extra_body={"input_type": input_type}
)
vecs += [d.embedding for d in res.data]
return np.array(vecs)
docs = [...] # your documents
doc_vecs = embed(docs, "document") # precompute and store in your vector DB
def search(query, k=50, n=5):
scores = doc_vecs @ embed([query], "query")[0]
candidates = [docs[i] for i in np.argsort(-scores)[:k]] # first-stage top k
res = requests.post(
f"{API}/rerank",
headers={"Authorization": f"Bearer {KEY}"},
json={"model": "kure-reranker-nano", "query": query, "documents": candidates, "top_n": n},
)
res.raise_for_status()
return [(r["relevance_score"], candidates[r["index"]]) for r in res.json()["results"]]- More candidates means fewer missed answers but more tokens and time. Start with 20–50 and tune.
- For more than 100 candidates, split them across requests and merge by
relevance_score; scores are comparable across requests. - Compare the reranker with KURE-v3 similarity side by side in the playground.
