Knowledge Search API

Open in CMS

The Knowledge Search API lets your own systems search an agent's knowledge and get back the matching chunks of its documents, websites, and videos. There is no AI-generated answer and no reranking: you send a query, Qlar finds the nearest chunks, and you decide what to do with them.

Use it when the knowledge your agent already holds is needed somewhere else, for example:

  • Your own RAG pipeline or chatbot. Your application asks Qlar for the relevant chunks and writes the answer with its own model.
  • An internal search box. An intranet or help-centre page shows the passages that match what an employee typed, with links to the source documents.
  • An AI agent built outside Qlar. An agent on another platform calls the API as a retrieval tool, so it reads from the same knowledge base as your Qlar agent.

The API searches the same knowledge the agent uses in its conversations. Anything you add, deactivate, or delete in Knowledge (in the CMS or through Document Integration) is reflected in the results.

In the Teach Your Agent example, Atlas holds Kirana Group's SOPs. Kirana's intranet has a search box for staff. Instead of building a second index, the intranet server sends each search to Atlas's Knowledge Search API and lists the passages it gets back, including SOP-FIN-007 "Project and Capex Approval Policy".


Before you start

  • Service agents only. The Knowledge Search API is available for service agents. A personal agent cannot switch it on. See Personal vs Service Agents if you are not sure which kind your agent is.
  • Who can turn it on. Agent contributors and organization Owners and Admins.
  • Off by default. Every agent starts with the API switched off. Nothing can call it until someone switches it on and creates a key.
  • The agent needs knowledge. Add documents, websites, or videos first. See Teach Your Agent.
  • If some of the knowledge is confidential, read Knowledge Permissions first. The API uses the same permission codes.

Turn on the API and create a key

In the CMS, open Channels β†’ Search API in your agent's sidebar. The page has three tabs: Access, Permissions, and Log.

  1. On the Access tab, switch on Allow search through the API. The page shows the endpoint for this agent and a ready-to-run cURL example.

  2. The agent has two key slots, Primary and Secondary. In one of them, create a key and fill in:

    FieldWhat to enter
    NameA label that tells you which system uses the key, for example Kirana intranet search. Up to 80 characters.
    Expiry7, 14, 30, 90, 180, or 365 days, or never. After that date the key stops working.
  3. Create the key and copy it right away. The full key (it starts with qks_) is shown only once. Qlar stores only a fingerprint of it, so neither you nor Qlar support can see it again later. Afterwards the page shows only the last four characters and the expiry date.

  4. Store the key in your server's secret store (for example a vault or an environment variable on the server that calls the API).

Keys for this API have no scopes: every key can search, and searching is all it can do.

Replace or revoke a key

  • Lost a key? You cannot view it again. Create a new key in the same slot. The new key replaces the old one immediately, so any system still using the old key starts getting 401 errors.
  • Revoke a key to stop it at once, for example when it may have leaked or a system is retired. A revoked key cannot be turned back on; create a new one when you need access again.
  • Switch the API off to stop all keys of the agent at once. Switching it on again brings back the keys that are still valid.

Rotate a key without downtime

The two slots exist so you can change keys without interrupting your system:

  1. Your system uses the Primary key.
  2. Create a key in the Secondary slot.
  3. Move your clients to the Secondary key and check that their searches succeed (the search log shows which key each call used).
  4. Revoke the Primary key.

Next time, do the same in the other direction. Combined with an expiry, this keeps every key short-lived.

Keys used by other agents

Another agent you manage can search this agent's knowledge through External Knowledge. When it adds this agent as a provider, Qlar makes a key for it automatically. These keys do not use the Primary or Secondary slot: they are listed under Used by other agents on the Access tab, with the name of the agent that uses each one. Revoke one to stop that agent searching here; its contributors can make a new key later. The enforced permissions, the log, the rate limits, and the 1 credit per search apply to those searches like any other.


Request

POST https://api.qlar.ai/dialog/api/knowledge-search/v1/agents/{agentId}/search
X-Api-Key: qks_...
Content-Type: application/json

The endpoint, with your agent ID filled in, is shown ready to copy on the Access tab. The examples on this page use two shell variables, so the key never appears in the command itself:

export QLAR_SEARCH_URL="https://api.qlar.ai/dialog/api/knowledge-search/v1/agents/YOUR_AGENT_ID/search"
export QLAR_SEARCH_KEY="qks_..."   # load it from your secret store

Body:

FieldRequiredDescription
queryYesThe text to search for, 1 to 1,000 characters. Write it the way a person would ask, for example Who approves capex above USD 50,000?.
permissionsNoPermission codes of the person you are searching for, as an array of strings. At most 50 codes, each at most 100 characters. See Permissions.
limitNoThe most chunks to return, 1 to 20. Default: 5.

Example request:

curl -X POST "$QLAR_SEARCH_URL" \
  -H "X-Api-Key: $QLAR_SEARCH_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "Who approves capex above USD 50,000?",
    "permissions": ["FINANCE"],
    "limit": 3
  }'

A missing, wrong, expired, or revoked key, an agent whose API is switched off, a personal agent, and an unknown agent all get the same 401 unauthorized answer. This is on purpose: the API does not reveal which agents exist or why a key was refused.


Response

{
  "results": [
    {
      "chunkCode": "SOP-FIN-007-0004",
      "contentId": "5b7f0e2a-1c3d-4e8f-9a6b-2d4c8e0f1a3b",
      "title": "Project and Capex Approval Policy",
      "section": "3. Approval limits",
      "text": "Capital expenditure above USD 50,000 requires approval from the Finance Controller and the Head of Operations before a purchase order is raised.",
      "distance": 0.1842
    },
    {
      "chunkCode": "SOP-FIN-007-0005",
      "contentId": "5b7f0e2a-1c3d-4e8f-9a6b-2d4c8e0f1a3b",
      "title": "Project and Capex Approval Policy",
      "section": "4. Emergency purchases",
      "text": "In an emergency, the Head of Operations may approve up to USD 75,000; the Finance Controller signs off within two working days.",
      "distance": 0.2617
    }
  ],
  "route": "platform",
  "creditsCharged": 1
}
FieldDescription
resultsThe matching chunks, nearest first. Empty when nothing is close enough; that is a normal answer, not an error.
results[].chunkCodeThe chunk's code. You can look it up on Knowledge β†’ Chunks in the CMS.
results[].contentIdThe ID of the document, website, or video the chunk belongs to.
results[].titleThe title of that content.
results[].sectionThe section of the content the chunk comes from, when known.
results[].textThe chunk's text.
results[].distanceHow far the chunk is from the query. Smaller means closer. See Distance and limit.
routeWhose embedding model served the search: platform (Qlar's) or own (your organization's own model).
creditsChargedCredits this search cost: 1 or 0. See Billing.

Permissions

Permission codes work the same way as in the agent's conversations: content without a code can be found by every search, and content with codes is found only when the search carries one of them. See Knowledge Permissions.

Every search carries two sets of codes:

  • Enforced permissions. Codes you pick on the Permissions tab, from the agent's own permission list. They are added to every search, whether or not the caller sends any.
  • The caller's permissions. The codes in the request's permissions field.

The search uses both together: caller βˆͺ enforced. A caller can open more content by sending more codes, but never less than the enforced codes allow.

The caller is responsible for its codes. Qlar does not know who the person behind a search is: it trusts the codes the key holder sends. Anyone with the key can send any code, including codes for confidential content. Your server must check who its user is and send only the codes that user is entitled to, for example by mapping your own roles or groups to permission codes.

Examples:

  • Leave Enforced permissions empty and send no codes: the search finds only content without codes.
  • Enforce GENERAL: every search also finds content tagged GENERAL, without your system having to send it.
  • Kirana's intranet sends FINANCE only for employees in the finance group. Everyone else gets results from untagged SOPs only.

When the agent has no permission codes yet, the Permissions tab links to Users β†’ Permissions, where you create them.


Distance and limit

Each result has a distance between the query and the chunk. Smaller means a closer match. Distances come from the embedding model that served the search, so values from Qlar's model (route: platform) and from your organization's own model (route: own) are not on the same scale. Compare distances within one response, or between searches on the same route, not across routes.

The search finds chunks the same way the agent does in its conversations. It starts with the agent's Search tolerance and, when nothing is close enough, widens step by step by the Tolerance increment until it finds chunks or reaches the maximum. Both are set on Knowledge β†’ Retrieval; see Retrieval. Changing them changes the API's results too.

limit caps the number of chunks returned (1 to 20, default 5). Fewer can come back when fewer are close enough. If you pass the chunks to a model, start with 3 to 5: more chunks cost more tokens in your own model and can add loosely related text.

The query is turned into an embedding (by Qlar's embedding model on the platform index, or by your organization's own model). No language model and no reranker are used, which keeps searches fast and cheap.


Billing

SituationCredits
The search ran on Qlar's embedding (route: platform)1 credit per search
The search ran on your organization's own embedding model and key (route: own; see Knowledge Search on Your Own Model)Free
The search ran but found nothingCharged the same as above (the search still ran)
The request was refused (any 4xx or 5xx answer)Free

creditsCharged in each response tells you what the search cost. Credits come from your organization's balance, like every other Qlar action; see How Credits Work. When the organization is out of credit, searches on Qlar's embedding are refused with 402 credit_exhausted.


Rate limits

LimitValue
Searches per key120 per minute
Searches per agent (all keys together)300 per minute
Failed authentications per agent20 per minute

A request over a limit gets 429 rate_limited with a Retry-After header holding the number of seconds to wait. Wait at least that long before you try again; do not retry in a tight loop. A system that keeps sending an old key can use up the failed-authentication limit and block other callers of the same agent for a minute, so fix a 401 instead of retrying it.


Errors

Errors use the HTTP status code and a JSON body with a machine-readable code and a human-readable message:

{
  "code": "invalid_request",
  "message": "query must be between 1 and 1000 characters."
}

Build your logic on code. The message can change and is meant for people.

HTTP statuscodeMeaning
400invalid_requestThe body is not valid, for example an empty or too long query, more than 50 permission codes, or a limit outside 1 to 20.
401unauthorizedThe key is missing, wrong, expired, or revoked, the API is switched off, the agent is a personal agent, or the agent does not exist.
402credit_exhaustedThe organization is out of credit. Top up, then search again.
403agent_limit_reachedThe agent has used up the monthly usage limit that the organization's admins set for it.
429rate_limitedA rate limit was exceeded. Wait for the number of seconds in Retry-After.
503index_not_readyThe organization only allows its own AI models, and its own knowledge index is not ready yet. Try again later.

Search log and retention

Every search call, successful or not, is recorded. Contributors see the log on the Log tab of Channels β†’ Search API, newest first, and can filter it by date and by outcome.

Recorded for each call
Time, outcome, HTTP status code, error code and message
Key slot, key name, and the key's last four characters
The query text, only when Store query text is on
The permission codes the caller sent, and the codes the search used (caller and enforced)
The limit, the number of results, the chunk codes returned, and the nearest distance
The route (Qlar's or your own embedding), credits charged, and duration
IP address and user agent of the caller

Click a row to see its chunk codes and permissions.

Above the log you choose:

  • Keep entries for: how long entries are kept, from the periods the page offers (90 days unless you change it). Shortening the period deletes the entries older than the new period when you save, and this cannot be undone. Lengthening it applies to new entries; entries already deleted do not come back.
  • Store query text: whether the log keeps what was searched for. It is on by default. Queries can contain personal or confidential information, so turn it off when you do not need them. When it is off, the log shows Not stored in place of the query.

The log never contains API keys or the text of the chunks returned.


Security best practices

  • Keep the key on a server. Call the API only from back-end code. Never put a key in a browser page, a mobile app, a desktop app you distribute, or a public repository: anyone who can read the code can use the key, and send any permission code with it.
  • Decide permissions on your server. Send only the codes the signed-in user is entitled to. Never take codes from the user's browser as they are.
  • Use enforced permissions for a floor, not a ceiling. They are added to every search; they cannot stop a caller from sending more codes.
  • Store the key as a secret. Use your vault or your platform's secret variables, not a config file checked into source control. Do not print the key in logs.
  • Set an expiry and rotate using the two slots, as described in Rotate a key without downtime.
  • Revoke at once on a leak. If a key may have been exposed, revoke it on the Access tab, create a new one, and check the search log for calls you do not recognise.
  • Switch the API off when you no longer use it.

Troubleshooting

SymptomWhat to check
Every call returns 401 unauthorizedCheck that the API is switched on, that the key is the full value starting with qks_, that it is sent in the X-Api-Key header, that it has not expired or been revoked (or replaced by a newer key in the same slot), and that the agent ID in the URL matches the agent of the key. The agent must also still be a service agent.
429 rate_limited even with a correct keyAnother system may be calling the same agent with an old key and using up the 20 failed authentications per minute. Check the search log for failed calls, fix that system, and wait a minute.
results is emptyCheck that the agent has active knowledge on the topic, that the content's permission codes are enforced or sent by the caller, and that Search tolerance on Retrieval is not too strict. Try the same question in Preview.
Confidential chunks appear for the wrong peopleYour system sends codes those people should not have, or an enforced code opens that content. Check the permissions in the log entry and on the Permissions tab.
402 credit_exhaustedTop up your organization's credit, or use your organization's own embedding model.
503 index_not_readyYour organization only allows its own models and the agent's index on your own embedding model is not ready yet (still rebuilding, or no Knowledge search model chosen). See Knowledge Search on Your Own Model.
The log shows Not stored for the queryStore query text is off. Turn it on above the log; it applies to new searches only.