Rewrite queries
People rarely type the query that would actually find what they need — they type the vague version that's on their mind. This endpoint takes that rough question and rewrites it into a sharper, more searchable form before it ever reaches a search or retrieval step.
Run it online
Run this on our servers with your account. Free tools run in your browser; this one bills your KIT balance per the price above.
The gap between what people type and what they mean
A visitor types 'why is it slow' into a search box, meaning something much more specific — page load time, database latency, a particular feature lagging — but the search index has no way to guess which. rag.query_rewrite sits in front of that gap: it takes the underspecified question and produces a version with the missing context filled in or the ambiguity narrowed, so whatever searches or retrieves against it afterward has something worth matching.
What the request looks like
POST /rag/query-rewrite with the original question, and the task runs asynchronously — you get a task_id right away, and the rewritten query arrives afterward through a signed webhook call or a signed link valid for 24 hours. The output is a clearer, more searchable version of the same question, built to feed directly into a search index or a retrieval step rather than to be read by a person.
Query expansion isn't a new idea, but it's still an unsolved default
Information retrieval researchers have worked on the vocabulary mismatch problem for decades — the fact that a searcher's words and a document's words rarely line up exactly even when they mean the same thing — through techniques like adding synonyms or related terms to a query before running it. Most search boxes still ship with none of that: they run the raw string the user typed and call it done, which is why so many searches return nothing useful on the first try. Rewriting the query before searching addresses the mismatch at its source instead of hoping the underlying index will compensate.
Where it sits in a retrieval pipeline
This endpoint is a pre-processing step, not a final answer — it's meant to run before a search call, a retrieval-augmented answer, or any system that needs a well-formed query to work well. Because it's billed per request plus per query and runs async, it drops cleanly in front of a larger pipeline: a search box rewrites the query first, then passes the rewritten version to whatever retrieval or search system does the actual matching, all without a person in the loop.
What actually improves once queries are cleaned up
A downstream retrieval system built well can still return weak results if what it's given to search against is a vague three-word fragment; feed it a clearer, disambiguated query and the same retrieval logic returns noticeably more relevant matches. Teams that add this step in front of an existing search or RAG pipeline are typically fixing search quality without touching the retrieval system itself, since the fix happens one step earlier, at the question, not at the index.
What you can do with it
Cleaning up site search input
An e-commerce site rewrites a vague product search like 'warm jacket cheap' into a clearer query before running it against the catalog index.
Preprocessing for a RAG pipeline
A support tool rewrites a visitor's underspecified question before passing it into a retrieval step, improving which passages get retrieved.
Voice assistant query cleanup
A voice interface rewrites a spoken, informally phrased question into a well-formed search query before matching it against a knowledge base.
Multi-turn chat context resolution
A chat application rewrites a short follow-up question like 'and the other one?' into a self-contained, searchable query using prior context.
FAQ
How does the query rewriting API work?
POST the original question to /rag/query-rewrite, and receive the rewritten, more searchable version by webhook or a signed link valid for 24 hours.
Is the query expansion API free?
No, there is no free tier or trial; it costs $0.003 per request plus $0.0135 per query, and a failed task is never charged.
What's the difference between query rewriting and query expansion?
They're closely related; this endpoint clarifies and restructures the question, which often includes adding related terms, so it retrieves better against a search or RAG index.
Do I need this if I already have a search engine?
Often yes, because most search indexes match the raw query as typed and don't resolve vagueness themselves; rewriting the query first tends to improve results without changing the search system.
Can it use previous conversation context?
Yes, if you provide prior turns as context, it can resolve a vague follow-up question into a self-contained, searchable query.
Can I run this on a large batch of queries?
Yes, submit one async task per query and collect the rewritten versions by webhook as each completes.
Is this endpoint live?
Yes, /rag/query-rewrite is live and accepting production traffic now.
Is my query data stored afterward?
No, submitted queries and results are deleted after the retention window and are never used for training.
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, and soon from our app, email and Telegram.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/rag/query-rewrite \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"input":"…"}'const res = await fetch("https://api.kit.forhosting.com/rag/query-rewrite", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"input": "…"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/rag/query-rewrite",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"input": "…"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/rag/query-rewrite", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"input":"…"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"input":"…"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/rag/query-rewrite", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"input": "…"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "rag.query_rewrite",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Limits
max_chunks | 10000 |
max_tokens | 20000 |
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |
422 | task_failed | The task failed after 3 retries. You are never charged for it. |