Getting started with the AskVault API
What you can build with the AskVault API
The AskVault REST API exposes the same RAG pipeline that powers the AskVault widget, WhatsApp, Telegram, and live chat. With one HTTP endpoint you can build a custom chat interface, embed AI search inside your own product, drive an internal helpdesk bot, or pipe answers into Slack, Discord, or a customer-success dashboard.
Every API response is grounded in the documents you've indexed in your workspace. If the answer isn't in your knowledge base, you get a graceful fallback message and an empty (or weakly scored) sources array: check sources[].relevance_score to route those queries to a human. POST /v1/query does not return a confidence field; see reading confidence from the API for the field that does carry it.
There are two endpoints. POST /v1/query returns a synchronous JSON response. POST /v1/query/stream streams the response as Server-Sent Events. Streaming shows the first words as soon as they are written, which suits live chat interfaces.
Before you start
You need three things to make your first API call:
- An AskVault workspace with content indexed. Sign up at askvault.co/signup on the Free plan (no credit card required) and run the onboarding wizard to crawl a website or upload a PDF. Pages become available to the API as they're indexed.
- An API key in the format
ak_xxx. Generate one under Channels > REST API. - Any HTTP client.
curl, Postman, the Pythonrequestslibrary, or whatever you already use.
A Free workspace (50 messages/month, 1 workspace) and does not include API access. Upgrade to Starter (2,000 messages/month) or above to unlock /v1/query for this workspace. See pricing for the full plan and channel breakdown.
Generate an API key
- Open Channels > REST API.
- Click Generate Secret Key. New keys are named automatically (API Key 1, API Key 2 and so on).
- Every key gets 60 requests a minute and 1,000 a day. Support can raise a key's limits.
- The key (
ak_followed by 64 hex characters) is shown once in a banner above the key list. Copy it now. AskVault stores only a SHA-256 hash; we can't recover the original.
Treat API keys like passwords. Store them in environment variables (ASKVAULT_API_KEY), not in source code. Rotate them every quarter. If a key leaks, revoke it immediately with the Revoke button on its row under Channels > REST API.
Your first request
Send your first chat query. Replace ak_xxx with your real API key. The key already identifies the workspace, so no workspace ID is needed.
curl -X POST https://api.askvault.co/v1/query \-H "Authorization: Bearer ak_xxx" \-H "Content-Type: application/json" \-d '{ "query": "How do I reset my password?", "top_k": 5}'import os, requests
response = requests.post( "https://api.askvault.co/v1/query", headers={ "Authorization": f"Bearer {os.environ['ASKVAULT_API_KEY']}", "Content-Type": "application/json", }, json={ "query": "How do I reset my password?", "top_k": 5, }, timeout=15,)response.raise_for_status()print(response.json())const response = 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: "How do I reset my password?", top_k: 5,}),});const data = await response.json();console.log(data);A successful response looks like this:
{ "answer": "To reset your password, go to askvault.co/forgot-password, enter your email, and click the reset link we send you. The link expires in 60 minutes.", "sources": [ { "document_name": "Password reset flow", "chunk_text": "Visit /forgot-password, enter your email...", "url": "https://docs.askvault.co/account/password-reset/", "relevance_score": 0.94 } ], "tokens_used": 187, "query_id": "8f14e45f-ceea-4e7a-a2d2-2f6c1b8a9f10", "conversation_id": "1c9e6679-7425-40de-944b-e07fc1f90ae7"}The sources array is what makes AskVault answers verifiable. Every claim in answer traces back to a chunk_text you indexed. Store the query_id in your logs. If a customer ever complains about an answer, the query_id and the sources array let you match it to what was retrieved.
Stream responses with SSE
For real-time UX (typing-effect chat interfaces, low-perceived-latency interactions), use the streaming endpoint. It uses Server-Sent Events over HTTP.
const response = await fetch("https://api.askvault.co/v1/query/stream", { method: "POST", headers: { "Authorization": `Bearer ${process.env.ASKVAULT_API_KEY}`, "Content-Type": "application/json", }, body: JSON.stringify({ query: "How does pricing work?" }),});
const reader = response.body.getReader();const decoder = new TextDecoder();
while (true) { const { value, done } = await reader.read(); if (done) break; const chunk = decoder.decode(value); for (const line of chunk.split("\n")) { if (line.startsWith("data: ")) { const event = JSON.parse(line.slice(6)); if (event.error || event.suppressed) continue; // error frame, or a person is handling it if (!event.done) process.stdout.write(event.token || ""); else console.log("\nSources:", (event.sources ?? []).map(s => s.document_name)); } }}Each data: line has a token field (partial text) and a done boolean. The final event has done: true and includes the full sources array. Full SSE schema is in the streaming reference.
Request parameters
The workspace is identified by the API key, so no workspace_id is needed in the request body.
| Parameter | 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 8) |
session_id | string | No | Per-end-user session identifier (max 200 chars). Isolates conversation history per end user when building multi-tenant consumers. |
conversation_id | string | No | Continue a specific multi-turn conversation. Pass the conversation_id from a prior response. Rolling out: until it is on for your workspace, the conversation is chosen by session_id, so send that too. |
Rate limits
Every API key defaults to 60 requests/minute and 1,000 requests/day. Support can raise a key's limits up to 1,000 requests/minute and 100,000/day, independent of plan tier. API access itself requires the Starter plan or above.
When you exceed the limit you get HTTP 429 Too Many Requests with a message naming the limit. There are no rate-limit headers or Retry-After, so back off with increasing delays, then retry. Full reference: rate limits per plan.
Authentication errors
Check the table below for the most common failures. Each row lists the fix.
| Status | Meaning | Fix |
|---|---|---|
| 401 | Missing or malformed Authorization header | Header must be exactly Bearer ak_xxx. No "Token" or "Key" prefix. |
| 401 | Invalid or revoked API key | The key was deleted or never existed. Generate a new one in the dashboard. |
| 403 | Plan does not include the API | API access needs Starter or above. |
| 404 | Conversation or workspace not found | The conversation_id does not belong to this workspace, or the key's workspace was deleted. |
Every error response includes a JSON body with detail describing the problem. Log it for debugging, but never show raw error bodies to end users.
FAQ
How is API usage billed?
Each /v1/query and /v1/query/stream request that returns a successful answer counts as 1 message against your plan's monthly quota. Failed requests (4xx/5xx) don't count. Indexing operations (uploading documents, crawling URLs) are billed separately by content volume in MB.
Can I use the API from a browser?
Not directly. The API key would be exposed in client-side code. For browser usage, either proxy through your own backend, or use the embeddable widget which authenticates with a public workspace token plus per-domain rate limiting.
How do I support multiple end users?
Pass a unique session_id per end user on every call. AskVault keeps each session_id on its own conversation thread, so one user never sees another's history. Rate limits are still counted per API key. Continuing a conversation by conversation_id alone is rolling out; until it is on for your workspace, calls without a session_id share one conversation.
What's the maximum message length?
4,000 characters. Longer queries are rejected with 422. For document analysis ("summarize this 50-page PDF"), upload the document to the knowledge base instead. The agent reads it via retrieval, not as a raw prompt.
Does the API have an SDK?
Official JavaScript and Python clients are on the roadmap. Until they ship, call the REST API directly; see POST /v1/query for the request and response fields.
Related guides
These pages cover authentication, the query endpoints, rate limits, and errors in more depth.
- API authentication: the Bearer ak_xxx flow in depth
- POST /v1/query reference
- POST /v1/query/stream and SSE event types
- Rate limits per plan
- Error codes and recovery
- Webhooks: receive events when conversations happen
- How AskVault grounds answers in your content (RAG explained)