Skip to content
Try Free →

POST /v1/query endpoint

Last updated: · 4 min read

Endpoint

POST https://api.askvault.co/v1/query

Authorization header: Bearer ak_xxx.

Request body

{
"query": "What is your refund policy?",
"conversation_id": "conv_xxx",
"session_id": "user_123",
"top_k": 5
}

Fields:

  • query (required). The question, up to 4,000 characters.
  • conversation_id (optional). Continue a specific conversation.
  • session_id (optional). Per-end-user thread key, up to 200 characters. Use it to keep each of your own users' conversations separate under a single API key.
  • top_k (optional). How many knowledge chunks to retrieve, 1 to 20. Defaults to 8.

The workspace is resolved from your API key, so there is no workspace_id field.

Response

{
"answer": "Our refund policy allows refunds within 14 days...",
"sources": [
{
"document_name": "Refund Policy",
"chunk_text": "...",
"relevance_score": 0.92,
"url": "https://yoursite.co/refund-policy"
}
],
"tokens_used": 450,
"query_id": "msg_xxx",
"conversation_id": "conv_xxx"
}

Those five fields are the whole response body: there is no skills_fired and no latency_ms.

  • sources contains up to top_k retrieved chunks. Each carries the document_name it came from, the exact chunk_text, a relevance_score, and the page url: url is null for uploaded files and for older chunks stored without one.
  • query_id identifies this answer. Log it: it is what support needs to trace a specific reply.
  • conversation_id is null when the query did not start or continue a conversation.

Example

Terminal window
curl -X POST https://api.askvault.co/v1/query \
-H "Authorization: Bearer ak_xxx" \
-H "Content-Type: application/json" \
-d '{"query":"What is your refund policy?"}'

Returns the answer with its sources.

To stream tokens as they are generated, call POST /v1/query/stream: it takes the same request body. There is no stream flag on /v1/query.

Multi-turn conversations

Pass the same conversation_id across calls:

  • First call. No conversation_id; AskVault generates one.
  • Subsequent calls. Pass the returned conversation_id.
  • Context carries: the bot remembers earlier turns.

Identity-verified queries

/v1/query takes no identity parameter: it has no user object and no HMAC hash.

  • To attach an end-user (your own user id, email, name, plan), call POST /v1/agent/ask, which accepts a user object.
  • For in-browser visitors, identity verification is a widget feature. See identity verification.

Rate limits

Per API key:

  • 60 requests per minute default.
  • 1,000 requests per day default, counted over a 24-hour window that starts with the first request after the last reset.
  • To change a key's limits, contact support.

Rate-limited responses return HTTP 429. No Retry-After header is sent; read the detail message instead. It names the limit you hit: back off for up to a minute on the per-minute limit, and wait for the 24-hour window to roll on the per-day limit.

Errors

CodeMeaningAction
200SuccessUse answer
401API key missing, malformed, or revokedCheck the Bearer token
402Message credits exhausted (error_code: messages_exhausted) or the selected model is not on your plan (error_code: model_locked)Upgrade, buy a top-up, or pick another model
403Your plan does not include API accessUpgrade to Starter or above
404The key's workspace or owner no longer exists, or (once rolled out) the conversation_id is not one of your workspace's API conversationsCreate a new key, or drop the conversation_id to start a new conversation
422Malformed JSON, or a field failed validationCheck the JSON, query length and top_k range
429Per-key rate limit hit, or your monthly message quota is used upRead detail: back off on a rate limit; a quota block does not clear by retrying
500Server errorRetry with exponential backoff

A 429 does not always mean "retry later". When your monthly message quota is used up, /v1/query also returns 429, and retrying will not help until the quota resets or you upgrade.

See API errors for full code reference.

Latency

We don't publish latency percentiles for /v1/query yet. Response time depends mainly on the model your workspace uses, how much content is retrieved, and whether the question triggers skills. For chat interfaces, use /v1/query/stream so users see tokens as they arrive.

SDK availability

There are no official SDKs; use any HTTP client (curl, fetch, requests, etc.).

Limits

  • Query length. 4,000 characters.
  • Requests per key. The per-minute and per-day limits under Rate limits.
  • Messages per month. Set by your plan's message credits, shared with your other channels.

Common pitfalls

422 instead of 200. A field failed validation: for example an empty query, one longer than 4,000 characters, or a top_k outside 1 to 20.

401 despite a valid-looking key. The Authorization header must be exactly Bearer ak_...; anything else is rejected before the key is looked up. A revoked or deactivated key also returns 401.

Empty answer string. This is not a knowledge gap. A gap does not come back empty. An empty string means generation returned no text (a model or provider hiccup). Retry the call; if it repeats, check API errors and contact support with the query_id.

What a knowledge gap actually returns. Two different responses, depending on what retrieval found:

  • Nothing retrieved. With strict retrieval on (the default), the agent does not call the model at all. You get sources: [] and this exact answer: "I don't have that information in my knowledge base. Please rephrase your question or contact support for help." That is the response to look for when you want to detect a gap programmatically: empty sources plus that sentence. Fix it by adding the missing content, then re-query.
  • Something retrieved, but it doesn't fully cover the question. The agent answers from what was retrieved instead of returning the sentence above, so a partial answer can read like a complete one. Judge coverage from sources and their relevance scores, not from the answer's tone.

FAQ

How is this different from /v1/query/stream?

Streaming returns tokens as generated; useful for chat UIs. Standard endpoint returns full response at once.

Can I cache responses?

AskVault does not send ETag or other cache headers on /v1/query. The first question in a new conversation may be answered from AskVault's answer cache, which resets when you update your knowledge base. Cached answers are metered like any other answer. If you cache on your side, clear your cache when you update your knowledge base.

Does this count against my message quota?

Yes. A successful answer is metered like a message on any other channel: base models cost 1 message credit, premium models cost more. Requests rejected before an answer is generated (401, 403, 422, 429) are not charged.

Was this page helpful?