Ask Memory
curl --request POST \
--url https://api.velt.dev/v2/memory/ask \
--header 'Content-Type: application/json' \
--header 'x-velt-api-key: <x-velt-api-key>' \
--header 'x-velt-auth-token: <x-velt-auth-token>' \
--data '
{
"data": {
"question": "<string>",
"organizationId": "<string>",
"documentId": "<string>",
"documentIds": [
"<string>"
],
"filters": {},
"filters.excludeDocumentIds": [
"<string>"
],
"recencyDays": 123
}
}
'import requests
url = "https://api.velt.dev/v2/memory/ask"
payload = { "data": {
"question": "<string>",
"organizationId": "<string>",
"documentId": "<string>",
"documentIds": ["<string>"],
"filters": {},
"filters.excludeDocumentIds": ["<string>"],
"recencyDays": 123
} }
headers = {
"x-velt-api-key": "<x-velt-api-key>",
"x-velt-auth-token": "<x-velt-auth-token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'x-velt-api-key': '<x-velt-api-key>',
'x-velt-auth-token': '<x-velt-auth-token>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
data: {
question: '<string>',
organizationId: '<string>',
documentId: '<string>',
documentIds: ['<string>'],
filters: {},
'filters.excludeDocumentIds': ['<string>'],
recencyDays: 123
}
})
};
fetch('https://api.velt.dev/v2/memory/ask', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.velt.dev/v2/memory/ask",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'data' => [
'question' => '<string>',
'organizationId' => '<string>',
'documentId' => '<string>',
'documentIds' => [
'<string>'
],
'filters' => [
],
'filters.excludeDocumentIds' => [
'<string>'
],
'recencyDays' => 123
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-velt-api-key: <x-velt-api-key>",
"x-velt-auth-token: <x-velt-auth-token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.velt.dev/v2/memory/ask"
payload := strings.NewReader("{\n \"data\": {\n \"question\": \"<string>\",\n \"organizationId\": \"<string>\",\n \"documentId\": \"<string>\",\n \"documentIds\": [\n \"<string>\"\n ],\n \"filters\": {},\n \"filters.excludeDocumentIds\": [\n \"<string>\"\n ],\n \"recencyDays\": 123\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-velt-api-key", "<x-velt-api-key>")
req.Header.Add("x-velt-auth-token", "<x-velt-auth-token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.velt.dev/v2/memory/ask")
.header("x-velt-api-key", "<x-velt-api-key>")
.header("x-velt-auth-token", "<x-velt-auth-token>")
.header("Content-Type", "application/json")
.body("{\n \"data\": {\n \"question\": \"<string>\",\n \"organizationId\": \"<string>\",\n \"documentId\": \"<string>\",\n \"documentIds\": [\n \"<string>\"\n ],\n \"filters\": {},\n \"filters.excludeDocumentIds\": [\n \"<string>\"\n ],\n \"recencyDays\": 123\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.velt.dev/v2/memory/ask")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-velt-api-key"] = '<x-velt-api-key>'
request["x-velt-auth-token"] = '<x-velt-auth-token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"data\": {\n \"question\": \"<string>\",\n \"organizationId\": \"<string>\",\n \"documentId\": \"<string>\",\n \"documentIds\": [\n \"<string>\"\n ],\n \"filters\": {},\n \"filters.excludeDocumentIds\": [\n \"<string>\"\n ],\n \"recencyDays\": 123\n }\n}"
response = http.request(request)
puts response.read_body{
"result": {
"answer": "Reviewers consistently reject copy that makes medical claims without a citation...",
"citations": [
{ "recordId": "act_8f3...", "snippet": "Claim 'clinically proven' lacks a citation." }
],
"confidence": 0.74,
"recordsSearched": 18
}
}
Search and Ask
Ask Memory
POST
/
v2
/
memory
/
ask
Ask Memory
curl --request POST \
--url https://api.velt.dev/v2/memory/ask \
--header 'Content-Type: application/json' \
--header 'x-velt-api-key: <x-velt-api-key>' \
--header 'x-velt-auth-token: <x-velt-auth-token>' \
--data '
{
"data": {
"question": "<string>",
"organizationId": "<string>",
"documentId": "<string>",
"documentIds": [
"<string>"
],
"filters": {},
"filters.excludeDocumentIds": [
"<string>"
],
"recencyDays": 123
}
}
'import requests
url = "https://api.velt.dev/v2/memory/ask"
payload = { "data": {
"question": "<string>",
"organizationId": "<string>",
"documentId": "<string>",
"documentIds": ["<string>"],
"filters": {},
"filters.excludeDocumentIds": ["<string>"],
"recencyDays": 123
} }
headers = {
"x-velt-api-key": "<x-velt-api-key>",
"x-velt-auth-token": "<x-velt-auth-token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'x-velt-api-key': '<x-velt-api-key>',
'x-velt-auth-token': '<x-velt-auth-token>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
data: {
question: '<string>',
organizationId: '<string>',
documentId: '<string>',
documentIds: ['<string>'],
filters: {},
'filters.excludeDocumentIds': ['<string>'],
recencyDays: 123
}
})
};
fetch('https://api.velt.dev/v2/memory/ask', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.velt.dev/v2/memory/ask",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'data' => [
'question' => '<string>',
'organizationId' => '<string>',
'documentId' => '<string>',
'documentIds' => [
'<string>'
],
'filters' => [
],
'filters.excludeDocumentIds' => [
'<string>'
],
'recencyDays' => 123
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-velt-api-key: <x-velt-api-key>",
"x-velt-auth-token: <x-velt-auth-token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.velt.dev/v2/memory/ask"
payload := strings.NewReader("{\n \"data\": {\n \"question\": \"<string>\",\n \"organizationId\": \"<string>\",\n \"documentId\": \"<string>\",\n \"documentIds\": [\n \"<string>\"\n ],\n \"filters\": {},\n \"filters.excludeDocumentIds\": [\n \"<string>\"\n ],\n \"recencyDays\": 123\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-velt-api-key", "<x-velt-api-key>")
req.Header.Add("x-velt-auth-token", "<x-velt-auth-token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.velt.dev/v2/memory/ask")
.header("x-velt-api-key", "<x-velt-api-key>")
.header("x-velt-auth-token", "<x-velt-auth-token>")
.header("Content-Type", "application/json")
.body("{\n \"data\": {\n \"question\": \"<string>\",\n \"organizationId\": \"<string>\",\n \"documentId\": \"<string>\",\n \"documentIds\": [\n \"<string>\"\n ],\n \"filters\": {},\n \"filters.excludeDocumentIds\": [\n \"<string>\"\n ],\n \"recencyDays\": 123\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.velt.dev/v2/memory/ask")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-velt-api-key"] = '<x-velt-api-key>'
request["x-velt-auth-token"] = '<x-velt-auth-token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"data\": {\n \"question\": \"<string>\",\n \"organizationId\": \"<string>\",\n \"documentId\": \"<string>\",\n \"documentIds\": [\n \"<string>\"\n ],\n \"filters\": {},\n \"filters.excludeDocumentIds\": [\n \"<string>\"\n ],\n \"recencyDays\": 123\n }\n}"
response = http.request(request)
puts response.read_body{
"result": {
"answer": "Reviewers consistently reject copy that makes medical claims without a citation...",
"citations": [
{ "recordId": "act_8f3...", "snippet": "Claim 'clinically proven' lacks a citation." }
],
"confidence": 0.74,
"recordsSearched": 18
}
}
Use this API to ask a natural-language question over your Memory. The answer is grounded in your judgments and ingested knowledge, and comes with citations and a confidence score. When retrieval finds no relevant context,
answer is an empty string with confidence: 0 rather than an invented answer; treat that as “Memory has nothing to say about this yet.”
Endpoint
POST https://api.velt.dev/v2/memory/ask
Headers
string
required
Your API key.
string
required
Your Auth Token.
Body
Params
object
required
Show properties
Show properties
string
required
Non-empty natural-language question.
string
Narrow to one organization.
orgId is accepted as an alias.string
Narrow to one document. Only applied when
organizationId is also set. Without organizationId, documentId is ignored and the question runs across the whole workspace. docId is accepted as an alias.string[]
Narrow to a set of documents. 1 to 25 document ids, each non-empty. Same rules as on Search Judgments: it needs
organizationId, documentId wins when you send both, ids are trimmed and deduplicated on the server, and the 25 cap applies to the list you send, before deduplication.A question scoped this way reads only those documents. When none of them holds any activity, answer comes back empty instead of falling back to workspace-wide patterns.It also scopes ingested knowledge: the per-document tier of retrieval runs once for each id you list. Detected patterns, reviewer profiles, and alerts stay workspace-wide, because they carry no per-document origin.object
Same shape as the Search Judgments filters, including the
decision values and the dateRange bounds. annotationId requires organizationId.string[]
Leave out judgments belonging to specific documents. 1 to 20 ids, each non-empty. An empty array is rejected. Pass either the document id you sent to Velt or the id a Memory response returned; both forms match.This narrows the judgments the answer is built from. It does not narrow the workspace-level context
ask also reads, because reviewer profiles, detected patterns, and alerts are aggregates that carry no per-document origin. An answer can still reflect an excluded document through those aggregates.Detected patterns enter that context only when they carry reviewer evidence. A topic pattern with confidence below 0.1, or with category set to no-data or uncategorized, is still returned by patterns/get but is left out of the answer. When two topic patterns share a topic, ask reads the apiKey-scoped one, or the one with the higher sourceCount when both have the same scope.integer
1 to 365. Recency-true retrieval instead of vector search. Returns activity from the last
recencyDays complete UTC days. The window ends at the start of the current UTC day, so activity later in the current UTC day is not returned. Overrides filters.dateRange. If filters.annotationId is also set, the annotation shortcut wins and recencyDays is ignored.Example Requests
Ask a policy question
{
"data": {
"question": "How do we handle marketing copy that makes medical claims?"
}
}
Ask across a set of documents
{
"data": {
"question": "What did reviewers push back on in these documents?",
"organizationId": "org_eu",
"documentIds": ["checkout-flow-v3", "homepage-redesign"]
}
}
Response
answer is the grounded answer (an empty string when there is no grounding context). citations are the records the model reports it drew on. They are returned as-is and are not verified against the retrieved set, so treat a recordId as a hint and handle the case where it does not resolve. confidence is 0 when the answer is empty. recordsSearched is the number of judgment records put in front of the model.
Success Response
{
"result": {
"answer": "Reviewers consistently reject copy that makes medical claims without a citation...",
"citations": [
{ "recordId": "act_8f3...", "snippet": "Claim 'clinically proven' lacks a citation." }
],
"confidence": 0.74,
"recordsSearched": 18
}
}
Failure Response
On a validation error,details.issues lists every failing field, not just the one in message.
{
"error": {
"message": "ERROR_MESSAGE",
"status": "INVALID_ARGUMENT",
"details": {
"issues": [
{ "code": "invalid_type", "path": ["question"], "message": "question is required" }
]
}
}
}
{
"result": {
"answer": "Reviewers consistently reject copy that makes medical claims without a citation...",
"citations": [
{ "recordId": "act_8f3...", "snippet": "Claim 'clinically proven' lacks a citation." }
],
"confidence": 0.74,
"recordsSearched": 18
}
}
Was this page helpful?

