API authentication, the Bearer ak_xxx flow
The header
Every request to /v1/* requires this header:
Authorization: Bearer ak_yourkeyhereNo Token, Key, or other prefix. The literal word Bearer, a single space, then the full key including the ak_ prefix. Missing or malformed headers return HTTP 401 Unauthorized.
Key format and lifecycle
API keys are ak_ followed by 64 hexadecimal characters of random data. The key does not contain your workspace ID; AskVault looks the workspace up from the key.
Lifecycle:
- Generated under Channels > REST API with Generate Secret Key. Shown to you once.
- Stored server-side only as SHA-256 hash. The original key is never recoverable.
- Active until you revoke it, or until the expiry date you chose when you generated it.
- Revoked with the Revoke button on its row under Channels > REST API, then confirming. Effective immediately; subsequent requests with the revoked key return 401.
Lost keys can't be recovered. Generate a new one and revoke the old one.
Expiry and access level
When you click Generate Secret Key you choose two things next to the button. The dashboard sets them only when a key is generated.
- Expiry. Never expires (the default), 30 days, 90 days or 1 year. From that date every authenticated
/v1/*request and every workspace MCP call made with the key returnsHTTP 401with{"detail": "API key has expired."}. To keep an integration running, generate its next key and rotate before the date. - Access. Full access (the default) can call every authenticated
/v1/*endpoint. Ask questions only can call/v1/query,/v1/query/stream,/v1/agent/askand/v1/agent/capabilities, and both workspace MCP tools. On/v1/agent/escalate,/v1/agent/csatand/v1/agent/resolveit returnsHTTP 403with{"detail": "This API key can only ask questions. Use a key with full access."}. That refusal does not count against the key's rate limit.
Ask questions only is not read-only. A question sent to /v1/agent/ask is stored as a conversation, and the AI can still hand that conversation to a person, as it can in any chat.
Each key's row shows its access, its expiry (or Expired) and the date it was last used on any /v1/* endpoint or the workspace MCP server.
Per-key rate limits
API access itself requires the Starter plan or above: Free-plan workspaces can't generate API
keys or call /v1/*.
Every key has independent per-minute and per-day rate limits. New keys default to 60 requests/minute and 1,000/day. Support can raise a key's limits up to 1,000/minute and 100,000/day, independent of your plan tier; changing them is not in the dashboard yet. Useful if you have one key powering a customer-facing app and want to cap that key's usage independently of internal use.
When you exceed the cap you get HTTP 429 Too Many Requests with a message naming the limit. No rate-limit headers or Retry-After are sent, so back off with increasing delays, then retry.
Generate a key
In the AskVault dashboard:
- Open Channels > REST API.
- Click Generate Secret Key.
- Every key gets 60 requests a minute and 1,000 a day; support can raise them.
The key list has four columns: Name, Secret Key, Created and Actions. New keys are named automatically (API Key 1, API Key 2 and so on), and the Secret Key column only ever shows the start of a key.
The full key (ak_...) is shown once, in a banner above the list. Copy it now. Store it somewhere safe (a secrets manager, environment variable, or password manager). After you close the dialog there's no way to retrieve the original.
We recommend creating separate keys per environment (production, staging, development) and per consumer (your backend, your mobile app, your CRM integration). Tight scoping makes revocation safer if one key leaks.
Test your key
The simplest verification request:
curl -X POST https://api.askvault.co/v1/query \-H "Authorization: Bearer ak_xxx" \-H "Content-Type: application/json" \-d '{"query":"test"}'import requestsr = requests.post("https://api.askvault.co/v1/query", headers={"Authorization": "Bearer ak_xxx"}, json={"query": "test"})print(r.status_code, r.json())const r = await fetch("https://api.askvault.co/v1/query", {method: "POST",headers: { "Authorization": "Bearer ak_xxx", "Content-Type": "application/json" },body: JSON.stringify({ query: "test" }),});console.log(r.status, await r.json());Status 200 with a JSON answer field means auth works. Status 401 means the key is wrong.
Rotation
Best practice: rotate keys every quarter, or immediately after any leak suspicion.
The rotation flow:
- Generate a new key. Names are automatic (API Key 1, API Key 2 and so on), so note in your own records which key is used where.
- Update your production secrets to use the new key.
- Deploy.
- Once you've verified the new key works in production for at least 24 hours, revoke the old key.
- Confirm nothing is still using the old key before you revoke it. Each key's row under Channels > REST API shows the date it was last used; there is no per-key usage count, so check your own request logs for anything still sending the old key.
Zero-downtime rotation. The two keys both work during the overlap window.
Security recommendations
Three things matter most:
- Never commit keys to source control. Use environment variables (
ASKVAULT_API_KEY) or a secrets manager (AWS Secrets Manager, HashiCorp Vault, Doppler). - Don't expose keys to the browser. Even an Ask questions only key can read your knowledge and start conversations. If you need browser-side calls, use the widget channel which authenticates with a public workspace token plus per-domain rate limiting, or proxy through your backend.
- Monitor for anomalies. The dashboard has no per-key usage view, so watch your own request logs for sudden spikes. Unexpected traffic often signals a leaked key.
Common pitfalls
401 on every request. Header is malformed. Double-check that it's Authorization: Bearer ak_xxx with the right spacing and no quotes around the value.
Worked yesterday, fails today. The key was revoked, its expiry date passed (the body says API key has expired.), or the workspace was deleted. A key generated with Never expires does not expire on its own. Check the key list under Channels > REST API.
Works locally, fails in production. Different environment variables. Confirm production has the right ASKVAULT_API_KEY and that it matches a current active key.
Same key works for some endpoints but not others. A 403 on /v1/agent/escalate, /v1/agent/csat or /v1/agent/resolve means the key was generated with Ask questions only; use a full-access key for those. A 401 on some endpoints and not others means you're sending different headers per endpoint. Debug your HTTP client.
FAQ
Can a single key cover multiple workspaces?
No. Each key is bound to one workspace at creation. To call multiple workspaces, generate separate keys per workspace.
Can I use the same key from multiple machines?
Yes. Keys are not tied to specific machines or IPs. The same key can be in use from your backend, your CI, your mobile app, and your laptop simultaneously. Rate limits aggregate across all callers using that key.
Can I limit what a key can do?
Yes, when you generate it. Choose Ask questions only and the key can ask and read capabilities but gets 403 on escalate, csat and resolve. It is not read-only: questions it sends are stored as conversations and can be handed to a person. Finer per-endpoint scopes are not available.
Can a key expire?
Yes. Choose 30 days, 90 days or 1 year when you generate it. After that date the key gets 401 with API key has expired. on every authenticated /v1/* endpoint and on the workspace MCP server.
What happens to in-flight requests when I revoke a key?
In-flight requests complete normally. New requests after revocation return 401 immediately.
Are there OAuth or JWT options?
The Bearer-key flow is the only one for /v1/*. There is no OAuth option.
Related guides
- Getting started with the AskVault API
- POST /v1/query reference
- Rate limits per plan
- Error codes
- Webhooks