# Rerank

Order a list of documents from most to least relevant to a query. Use it as the second stage of search: fetch candidates with embeddings or keyword search, then rerank the best few. The request and response follow the Cohere and Jina rerank style, since OpenAI has no rerank API.

`POST /v1/rerank`

Only rerank models are served here. Calling it with a chat model returns `400`. List the current rerank models with a public call that needs no key:

```bash
curl "https://kenari.id/v1/models?modality=rerank"
```

A plain `GET /v1/models` does not list embedding, rerank, moderation or System One models. It does list chat, image, speech, transcription and video models. The examples below use `bge-reranker-base`. Swap in any id the call above returns. Prices are on [Models and pricing](/en/docs/models).

## Request

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `model` | string | yes | A rerank model id. |
| `query` | string | yes | What relevance is measured against. Up to 8,192 bytes. |
| `documents` | array of strings | yes | The documents to rank. Up to 100, each up to 8,192 bytes and a non-empty string, and up to 512 KiB in total. |
| `top_n` | integer | no | Return only the best `n` results. From 1 up to the number of documents. Default: all documents. |
| `return_documents` | boolean | no | Include each document's text in its result. Default: `false`. |

## Response

`results` holds one entry per returned document, best match first. Each entry has `index`, the position of the document in the `documents` array you sent, and `relevance_score`. A higher score means a closer match. `document` is an object with a `text` field and appears only when `return_documents` is `true`. `usage` reports the input tokens.

```json
{
  "object": "list",
  "model": "bge-reranker-base",
  "results": [
    { "index": 2, "relevance_score": 0.91 },
    { "index": 0, "relevance_score": 0.42 }
  ],
  "usage": { "prompt_tokens": 24, "total_tokens": 24 }
}
```

## Examples

### curl

```bash
curl https://kenari.id/v1/rerank \
  -H "Authorization: Bearer $KENARI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "bge-reranker-base",
    "query": "spicy fried rice recipe",
    "documents": [
      "how to brew iced coffee",
      "growing chili peppers in a pot",
      "spicy home-style fried rice recipe"
    ],
    "top_n": 2
  }'
```

### Python

The OpenAI SDK has no rerank method, so use `requests`.

```python
import os
import requests

resp = requests.post(
    "https://kenari.id/v1/rerank",
    headers={"Authorization": f"Bearer {os.environ['KENARI_API_KEY']}"},
    json={
        "model": "bge-reranker-base",
        "query": "spicy fried rice recipe",
        "documents": [
            "how to brew iced coffee",
            "growing chili peppers in a pot",
            "spicy home-style fried rice recipe",
        ],
        "top_n": 2,
    },
)
print(resp.json()["results"])
```

### JavaScript

```js
const resp = await fetch("https://kenari.id/v1/rerank", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.KENARI_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    model: "bge-reranker-base",
    query: "spicy fried rice recipe",
    documents: [
      "how to brew iced coffee",
      "growing chili peppers in a pot",
      "spicy home-style fried rice recipe",
    ],
    top_n: 2,
  }),
});
const { results } = await resp.json();
```

## Billing

Rerank is billed per input token, estimated from the query plus every document. The estimate is the charge, and the `usage` in the response is for display only. See [How billing works](/en/docs/billing) for how the reservation and price dimensions work.

## Errors

Size limits are checked first. A request over a limit fails with `400` before any charge.

| Status | Code | When |
| --- | --- | --- |
| 400 | `bad_request` | `model` is unknown or is not a rerank model, `query` or `documents` is missing or empty, a limit is exceeded, or `top_n` is not an integer between 1 and the number of documents. |
| 400 | `model_not_found` | The model is listed but no provider serves it right now. Retry later. |

See [Errors](/en/docs/errors) for the shared codes, such as `insufficient_balance` and `all_providers_failed`.

## See also

- [Embeddings](/en/docs/embeddings)
- [Models and pricing](/en/docs/models)
- [How billing works](/en/docs/billing)
