POST /v1/query, the chat query endpoint reference
Endpoint
POST https://api.askvault.co/v1/querySynchronous JSON response. For streaming, use POST /v1/query/stream instead.
Authentication: Authorization: Bearer ak_xxx. See authentication.
Minimal request
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?"}'import requests, osr = requests.post( "https://api.askvault.co/v1/query", headers={"Authorization": f"Bearer {os.environ['ASKVAULT_API_KEY']}"}, json={"query": "What is your refund policy?"}, timeout=15,)print(r.json())const r = await fetch("https://api.askvault.co/v1/query", {method: "POST",headers: { "Authorization": `Bearer ${process.env.ASKVAULT_API_KEY}`, "Content-Type": "application/json",},body: JSON.stringify({ query: "What is your refund policy?" }),});console.log(await r.json());Request parameters
The workspace is bound to the API key at creation time, so there is no workspace_id in the body.
| Field | Type | Required | Description |
|---|---|---|---|
query | string | Yes | The user's question. 1 to 4,000 characters. |
top_k | integer | No | Number of context chunks to retrieve. 1 to 20. Default 5. Higher values use more tokens. |
session_id | string | No | Per-end-user session identifier (max 200 chars). Use this to separate conversation history for each of your end users when building a multi-tenant API consumer. |
conversation_id | string | No | Continue a specific multi-turn conversation. Pass the conversation_id from a prior response. |
Response schema
{ "answer": "Refunds are available within 30 days of purchase. Submit a request at acme.co/refunds with your order number.", "sources": [ { "document_name": "Refund policy", "chunk_text": "Refunds are available within 30 days of purchase...", "url": "https://acme.co/policies/refunds", "relevance_score": 0.94 } ], "tokens_used": 187, "query_id": "msg_5b45ff_xxx", "conversation_id": "conv_5b45ff_xxx"}| Field | Type | Description |
|---|---|---|
answer | string | The grounded answer text. |
sources | array | The document chunks retrieved to ground the answer. Sorted by relevance_score descending. |
sources[].document_name | string | Name of the source document. |
sources[].chunk_text | string | The retrieved passage (up to 300 characters). Every claim in answer traces back to one of these. |
sources[].url | string | URL of the source page, if available. null for uploaded files without a URL. |
sources[].relevance_score | number | Cosine similarity score 0–1. Higher is more relevant. |
tokens_used | integer | Total tokens consumed (input + output). |
query_id | string | Unique ID for this query. Store in your logs for debugging. |
conversation_id | string | The conversation ID. Pass this back in subsequent queries to continue the conversation. |
Conversation continuity
Pass the conversation_id from the previous response to continue a multi-turn conversation. Send it back like this:
{ "query": "Can I get a refund on a sale item?", "conversation_id": "conv_5b45ff_xxx"}AskVault loads prior turns of the conversation as context for the new query. The retrieval and answer both factor in the conversation history.
To start a fresh conversation, omit conversation_id. AskVault creates a new one and returns it.
HTTP status codes
| Status | Meaning |
|---|---|
| 200 | Query processed successfully. Response body is JSON. |
| 400 | Malformed request. Missing required field or invalid value. |
| 401 | Missing or invalid API key. |
| 403 | API key doesn't have access to the requested workspace. |
| 404 | Workspace not found. |
| 422 | Validation error. The body parsed but a field violates a constraint. |
| 429 | Rate limit exceeded. Check Retry-After header. |
| 500 | Server error. Retry with exponential backoff. |
| 503 | Service temporarily unavailable. Retry. |
Every error response includes a JSON body with a detail field describing the problem:
{ "detail": "query is required" }Log detail for debugging; never show raw error bodies to end users.
Performance
Latency depends on whether the workspace cache is warm. Typical ranges for a standard workspace:
- Cold workspace, first request: 800 to 1,500 ms
- Warm workspace: 400 to 900 ms
- Workspace with hybrid retrieval enabled (higher tier): 600 to 1,200 ms
If you need sub-300 ms first-token-latency for live UX, switch to the streaming endpoint.
Common pitfalls
422 Unprocessable Entity on every request. The request body is using message instead of query. The required field is query.
Empty sources array on every query. Your workspace has no indexed content. Check Knowledge Hub.
Bot answers from training data instead of your content. The workspace knowledge base is the content source. Open Knowledge Hub, verify content is indexed, and re-test.
Conversation context doesn't carry across turns. You're not passing the conversation_id from the previous response. Round-trip it.
Latency >2 seconds consistently. Workspace is cold. Pre-warm with a noop query at app start.
Related guides
- Getting started with the AskVault API
- API authentication
- POST /v1/query/stream
- Rate limits per plan
- Error codes
- Webhooks