POST /v1/query endpoint
Endpoint
POST https://api.askvault.co/v1/queryAuthorization 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.
sourcescontains up totop_kretrieved chunks. Each carries thedocument_nameit came from, the exactchunk_text, arelevance_score, and the pageurl:urlisnullfor uploaded files and for older chunks stored without one.query_ididentifies this answer. Log it: it is what support needs to trace a specific reply.conversation_idisnullwhen the query did not start or continue a conversation.
Example
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 auserobject. - 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
| Code | Meaning | Action |
|---|---|---|
| 200 | Success | Use answer |
| 401 | API key missing, malformed, or revoked | Check the Bearer token |
| 402 | Message 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 |
| 403 | Your plan does not include API access | Upgrade to Starter or above |
| 404 | The key's workspace or owner no longer exists, or (once rolled out) the conversation_id is not one of your workspace's API conversations | Create a new key, or drop the conversation_id to start a new conversation |
| 422 | Malformed JSON, or a field failed validation | Check the JSON, query length and top_k range |
| 429 | Per-key rate limit hit, or your monthly message quota is used up | Read detail: back off on a rate limit; a quota block does not clear by retrying |
| 500 | Server error | Retry 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: emptysourcesplus 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
sourcesand 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.