Search API Quickstart
What is the Search API
The KIRHA Search API takes a question in plain language, picks the provider tools that can answer it, runs them and returns their output, with an optional summary.
You can call it over HTTP or through the kirha TypeScript SDK. There are two ways to use it:
- Auto mode: send a query, get the data and a summary back in one call.
- Plan mode: get the plan first, check the providers and the cost, then run it.
KIRHA searches every vertical by default. Pass focus with a vertical slug to restrict a search to one domain.
Authentication
All Search API requests need an API key. Create one at app.kirha.com/api-keys.
Pass it when you create the client:
import { Kirha } from "kirha";
const kirha = new Kirha({ apiKey: process.env.KIRHA_API_KEY });Send it in the Authorization header. The Bearer prefix is optional:
Authorization: Bearer <your_api_key>Send it in the Authorization header:
import os
import requests
headers = {"Authorization": f"Bearer {os.environ['KIRHA_API_KEY']}"}Auto mode (recommended)
Send a query and get a summary written from the providers' real-time data.
const result = await kirha.search("What does the boxed warning on Ozempic say?", {
summarization: true,
includeData: false,
});
console.log(result.summary);curl -X POST "https://api.kirha.com/search/v1" \
-H "Authorization: Bearer <your_api_key>" \
-H "Content-Type: application/json" \
-d '{
"query": "What does the boxed warning on Ozempic say?",
"summarization": { "enable": true },
"include_raw_data": false
}'response = requests.post(
"https://api.kirha.com/search/v1",
headers=headers,
json={
"query": "What does the boxed warning on Ozempic say?",
"summarization": {"enable": True},
"include_raw_data": False,
},
)
print(response.json()["summary"]){
"id": "search_jSwK63zp3B9ZUe4Qqjj6P",
"summary": "## Boxed Warning on Ozempic (Semaglutide)\n\nThe boxed warning on Ozempic states:\n\n### **WARNING: RISK OF THYROID C-CELL TUMORS**\n\n- In rodents, semaglutide causes **dose-dependent and treatment-duration-dependent thyroid C-cell tumors** at clinically relevant exposures...",
"usage": { "estimated": 1, "consumed": 1 },
"account": { "balance": 396870, "balance_timestamp": "2026-10-12T14:28:39.745Z" }
}Plan, review and execute
Get the plan of which providers will be queried and what it will cost, then run it.
Get a plan for your query
const plan = await kirha.plan(
"Find engineers working at companies behind the latest patents in Machine Learning",
);
console.log(plan.id); // "search_xUVm7HF80ZLjy0varLYGr"
console.log(plan.steps); // the planned tool callscurl -X POST "https://api.kirha.com/search/v1/plan" \
-H "Authorization: Bearer <your_api_key>" \
-H "Content-Type: application/json" \
-d '{
"query": "Find engineers working at companies behind the latest patents in Machine Learning"
}'plan = requests.post(
"https://api.kirha.com/search/v1/plan",
headers=headers,
json={
"query": "Find engineers working at companies behind the latest patents in Machine Learning",
},
).json()
print(plan["id"], plan["usage"]["estimated"])Review the plan: the providers it calls, the parameters and the estimated cost. A step can take its input from an earlier step's output ($fromStep).
{
"id": "search_xUVm7HF80ZLjy0varLYGr",
"status": "pending_confirmation",
"steps": [
{
"id": "step_a2VPR4SrIKnL3rgArRLJ1",
"status": "pending",
"tool_name": "lens_searchPatents",
"parameters": {
"query": "machine learning",
"sort": "date_published_desc",
"size": 10
},
"reasoning": "Retrieve the most recently published patents in Machine Learning to identify the companies (applicants) behind them."
},
{
"id": "step_n7kYe3li0DNaY0m6gjMA2",
"status": "pending",
"tool_name": "apollo_searchCompany",
"parameters": {
"companyName": {
"$fromTemplateString": "{0}",
"$values": [
{
"$fromStep": "step_a2VPR4SrIKnL3rgArRLJ1",
"$outputKey": "patents.0.applicants.0"
}
]
},
"limit": 1
},
"reasoning": "Resolve the first applicant from the latest ML patent to an Apollo company profile to get its domain for people search."
}
],
"usage": { "estimated": 34, "consumed": 0 },
"account": { "balance": 396870, "balance_timestamp": "2026-10-12T14:28:25.137Z" }
}Execute the plan with the id you got back
const result = await plan.execute({
summarization: { instruction: "Answer as a table with columns: Name, Title, Company" },
includeData: false,
});
console.log(result.summary);curl -X POST "https://api.kirha.com/search/v1/plan/run" \
-H "Authorization: Bearer <your_api_key>" \
-H "Content-Type: application/json" \
-d '{
"id": "search_xUVm7HF80ZLjy0varLYGr",
"summarization": {
"enable": true,
"instruction": "Answer as a table with columns: Name, Title, Company"
},
"include_raw_data": false
}'result = requests.post(
"https://api.kirha.com/search/v1/plan/run",
headers=headers,
json={
"id": plan["id"],
"summarization": {
"enable": True,
"instruction": "Answer as a table with columns: Name, Title, Company",
},
"include_raw_data": False,
},
).json()
print(result["summary"]){
"id": "search_xUVm7HF80ZLjy0varLYGr",
"summary": "Based on the latest Machine Learning patents published on **2026-10-08**, here are the companies behind them and the inventors listed on those patents:\n\n| Name | Title | Company |\n|------|-------|---------|\n| Declan Patrick Kelly | Inventor | Koninklijke Philips N.V. |\n| Rim Helaoui | Inventor | Koninklijke Philips N.V. |\n...",
"usage": { "estimated": 34, "consumed": 19 },
"account": { "balance": 396851, "balance_timestamp": "2026-10-12T14:29:01.783Z" }
}Configuration options
Summarization
Set summarization to add a summary of the results, written after the tools run. Add an instruction to shape it: a format, a language, the fields to keep.
const result = await kirha.search("Summarize latest NVIDIA earning calls", {
summarization: { instruction: "Use bullet points and keep the figures" },
includeData: false,
});curl -X POST "https://api.kirha.com/search/v1" \
-H "Authorization: Bearer <your_api_key>" \
-H "Content-Type: application/json" \
-d '{
"query": "Summarize latest NVIDIA earning calls",
"summarization": {
"enable": true,
"instruction": "Use bullet points and keep the figures"
},
"include_raw_data": false
}'response = requests.post(
"https://api.kirha.com/search/v1",
headers=headers,
json={
"query": "Summarize latest NVIDIA earning calls",
"summarization": {
"enable": True,
"instruction": "Use bullet points and keep the figures",
},
"include_raw_data": False,
},
)Raw data and focus
By default, the response includes each tool's output in raw_data. Set includeData to false (include_raw_data over HTTP) to leave it out. Raw data is structured for LLMs and carries context, timestamps and URLs.
This example also sets focus to search only the crypto vertical, and include_planning to get the plan the search ran.
const result = await kirha.search("List top 10 stablecoins yield on Ethereum", {
focus: "crypto",
includePlanning: true,
});
console.log(result.data);curl -X POST "https://api.kirha.com/search/v1" \
-H "Authorization: Bearer <your_api_key>" \
-H "Content-Type: application/json" \
-d '{
"query": "List top 10 stablecoins yield on Ethereum",
"focus": "crypto",
"include_planning": true
}'response = requests.post(
"https://api.kirha.com/search/v1",
headers=headers,
json={
"query": "List top 10 stablecoins yield on Ethereum",
"focus": "crypto",
"include_planning": True,
},
)
print(response.json()["raw_data"]){
"id": "search_V24SOmoi6YoVZh1nKyhKt",
"raw_data": [
{
"step_id": "step_pDbq1Nq64hJhownlUW2xc",
"tool_name": "defillama_searchYieldPools",
"parameters": {
"chain": "Ethereum",
"stablecoin": true,
"limit": 10,
"sortBy": "apy:desc"
},
"output": {
"context": "DeFi yield pools",
"pools": [
{
"project": "curve-dex",
"symbol": "IDAI-IUSDC-IUSDT",
"chain": "Ethereum",
"apy": 132.72,
"apyMean30d": 146.31726,
"tvlUsd": 1974553,
"exposure": "multi",
"ilRisk": "no",
"stablecoin": true
}
]
}
}
],
"planning": {
"status": "success",
"steps": [
{
"id": "step_pDbq1Nq64hJhownlUW2xc",
"status": "done",
"tool_name": "defillama_searchYieldPools",
"parameters": { "chain": "Ethereum", "stablecoin": true, "limit": 10, "sortBy": "apy:desc" },
"reasoning": "Fetch the top 10 stablecoin yield pools on Ethereum sorted by APY descending to give the user the highest-yielding stablecoin opportunities."
}
]
},
"usage": { "estimated": 5, "consumed": 5 },
"account": { "balance": 396871, "balance_timestamp": "2026-10-12T14:28:23.228Z" }
}Planning runtime
planning_runtime picks the planner. standard is the default and the more accurate one. fast answers sooner but is less accurate. /search/v1/plan/run ignores it, since the plan is already made.
import { Kirha, PlanningRuntime } from "kirha";
const result = await kirha.search("How to stream AI responses in Next.js using the latest AI SDK?", {
planningRuntime: PlanningRuntime.Fast,
});curl -X POST "https://api.kirha.com/search/v1" \
-H "Authorization: Bearer <your_api_key>" \
-H "Content-Type: application/json" \
-d '{
"query": "How to stream AI responses in Next.js using the latest AI SDK?",
"planning_runtime": "fast"
}'response = requests.post(
"https://api.kirha.com/search/v1",
headers=headers,
json={
"query": "How to stream AI responses in Next.js using the latest AI SDK?",
"planning_runtime": "fast",
},
)Timeout
A plan stays executable for 5 minutes after it is created. That leaves time for an agent to reason about it, for a human to review it, or to top up credits. After 5 minutes the plan expires (400 CONVERSATION_TURN_TIMEOUT) and you need a new one. A plan runs once.
Rate limits
/search/v1 and /search/v1/plan/run share a limit of 20 requests per minute per organization. /search/v1/plan has its own limit of 20 per minute. Over the limit, the API answers 429 with a Retry-After header. For a higher quota, write to developers@kirha.com with your use case.
API Reference
/search/v1
Prop
Type
/search/v1/plan
Prop
Type
/search/v1/plan/run
Prop
Type