> ## Documentation Index
> Fetch the complete documentation index at: https://velt.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Ask Memory

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

**x-velt-api-key** `string` *required*

Your API key.

**x-velt-auth-token** `string` *required*

Your [Auth Token](https://velt.dev/docs/security/auth-tokens.md).

# Body

#### Params

**data** `object` *required*

**properties**

**question** `string` *required*

Non-empty natural-language question.

**organizationId** `string`

Narrow to one organization. `orgId` is accepted as an alias.

**documentId** `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.

**documentIds** `string[]`

Narrow to a set of documents. 1 to 25 document ids, each non-empty. Same rules as on [Search Judgments](https://velt.dev/docs/api-reference/rest-apis/v2/memory/search.md): 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.

**filters** `object`

Same shape as the [Search Judgments](https://velt.dev/docs/api-reference/rest-apis/v2/memory/search.md) filters, including the `decision` values and the `dateRange` bounds. `annotationId` requires `organizationId`.

**filters.excludeDocumentIds** `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`](https://velt.dev/docs/api-reference/rest-apis/v2/memory/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.

**recencyDays** `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

```JSON theme={null}
{
  "data": {
    "question": "How do we handle marketing copy that makes medical claims?"
  }
}
```

#### Ask across a set of documents

```JSON theme={null}
{
  "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

```JSON theme={null}
{
  "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`.

```JSON theme={null}
{
  "error": {
    "message": "ERROR_MESSAGE",
    "status": "INVALID_ARGUMENT",
    "details": {
      "issues": [
        { "code": "invalid_type", "path": ["question"], "message": "question is required" }
      ]
    }
  }
}
```

```js theme={null}
{
  "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
  }
}
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.