Reference
Documentation
Qevra exposes a versioned REST API. This page documents what is live today and the conventions every future endpoint will follow.
Versioning
Every public endpoint is namespaced under a version segment, e.g. /api/v1/health. Breaking changes ship as a new version; the previous version keeps working.
Authentication
Every endpoint except /api/v1/health requires an API key. Create one under Dashboard → API Keys and send it as a bearer token. A key is scoped to exactly one workspace, which is how Qevra knows whose data a request concerns.
curl https://qevra.com/api/v1/me \
-H "Authorization: Bearer qevra_live_..."Keys take the form qevra_live_… or qevra_test_…. The environment is part of the key itself and cannot be reassigned later. Always send the key in the header, never in a query string, where it would be captured by access logs, browser history and referrer headers.
A key is shown once, at creation. Qevra stores only a SHA-256 digest, so a lost key has to be replaced rather than recovered. Missing and invalid credentials both answer 401 with an authentication_error.
Response shape
Successful responses return the resource directly, with no wrapper. Errors always return a single error object together with a request id. Every response also carries an x-qevra-request-id header — quote it when reporting a problem.
{
"status": "ok",
"service": "qevra",
"version": "v1"
}{
"error": {
"type": "invalid_request_error",
"code": "missing_field",
"message": "…"
},
"request_id": "req_…"
}Knowledge
Qevra answers from your content, so the content comes first. Send a document and it is split into overlapping fragments, embedded and stored against the workspace the key belongs to.
curl https://qevra.com/api/v1/knowledge \
-H "Authorization: Bearer qevra_live_..." \
-H "Content-Type: application/json" \
-d '{"title": "Refund policy", "content": "Customers may request a full refund within 30 days."}'Retrieval is semantic rather than keyword-based, and works across languages: a question in Italian will find the answer in an English document. Each match comes back with the fragment that produced it and how closely it matched, so you can see what an answer would have been grounded in.
curl https://qevra.com/api/v1/knowledge/search \
-H "Authorization: Bearer qevra_live_..." \
-H "Content-Type: application/json" \
-d '{"query": "Entro quanto posso chiedere un rimborso?"}'A key reaches its own workspace and nothing else. Retrieval filters by workspace before ranking, so one customer’s content can never surface in another’s results.
Resolving a request
Send the customer’s message and whatever you know about the situation. Qevra retrieves from your knowledge, answers only from what it found, and tells you when a human should take over.
curl https://qevra.com/api/v1/resolve \
-H "Authorization: Bearer qevra_live_..." \
-H "Content-Type: application/json" \
-d '{"message": "How long do I have to ask for a refund?", "external_user_id": "usr_42"}'{
"answer": "You may request a full refund within 30 days of purchase.",
"confidence": 0.38,
"escalation_required": false,
"escalation_reason": null,
"suggested_actions": [],
"sources": [{ "document_title": "Refund policy", "similarity": 0.38 }]
}Branch on escalation_required. When Qevra cannot support an answer, the answer is null and escalation_reason says why: no_knowledge, weak_retrieval, not_grounded or provider_failed. It does not guess, and an answer it cannot trace back to a retrieved fragment is never returned. A model outage escalates rather than failing the request, so an integration that handles escalation keeps working through one.
An answer costs $0.02, drawn from your prepaid balance. An escalation costs nothing, and neither does a call made with a qevra_test_ key — test keys run the identical path against the identical data, so you can build the whole integration before spending anything. A workspace with no credit left gets 402 insufficient_credit and no work is done.
Confidence measures how closely the cited fragments matched the question. It is not the model scoring itself — that number tracks how fluent an answer sounds, not whether it is right.
Teaching it the answer
When a human handles an escalation, send back what they said. It becomes a document in your knowledge base, and the next person asking gets the answer straight away.
curl https://qevra.com/api/v1/feedback \
-H "Authorization: Bearer qevra_live_..." \
-H "Content-Type: application/json" \
-d '{"request_id": "...", "verdict": "corrected", "corrected_answer": "..."}'Verdicts are approved, rejected or corrected, and each resolution takes exactly one. Only a correction becomes knowledge: an approved answer already came from your content, so re-indexing it would feed the system its own words back.
Anything other than an approval refunds what the answer cost, and the response says so in refunded. An answer you had to fix is not one we should be paid for.
Send approvals anyway. They are what tells you whether the confidence score means anything — the dashboard groups reviewed answers by confidence and shows how often a human agreed.
Available now
Liveness probe. Requires no authentication and does not touch the database.
Returns the workspace and key behind the credentials. Use it to confirm an integration authenticates correctly before writing any real calls.
Indexes a document. The text is chunked, embedded and stored against the key's workspace. Identical content is rejected rather than indexed twice.
Lists the documents a workspace has indexed.
Retrieves the fragments closest in meaning to a question, with their similarity scores.
Answers a support request from your indexed knowledge, or says a human is needed. Returns the fragments the answer was built on.
Records whether Qevra got it right. A corrected answer becomes a document the next question can be answered from.
Planned
Not yet availableThese endpoints are designed but not implemented. The shapes below may still change.
- GET/v1/usageThe ledger and balance over the API. Both already exist — this endpoint waits for someone who needs them outside the dashboard.