New to Memory? Start with the Overview for what Memory is, how judgments and knowledge sources work, and the core concepts this guide builds on.
Prerequisites & authentication
Base URL All endpoints are underhttps://api.velt.dev/v2/.
Required headers
| Header | Description |
|---|---|
x-velt-api-key | Your workspace API key. |
x-velt-auth-token | A short-lived auth token. See Auth Tokens. |
content-type | application/json |
data; success comes back under result, errors under error:
Build your first integration
You’ll do the full loop: add knowledge → ask a question → search decisions → get a suggestion.Step 1: Add a knowledge source
Knowledge ingestion is asynchronous and multimodal. Supported file types: PDF, CSV, Excel (.xlsx), and plain text.
There are two ways to submit a file:
- Inline (up to 5 MB): base64-encode it and send it directly.
- By reference (up to 30 MB): request an upload URL, PUT the bytes there, then ingest by reference.
sourceId:
completed, inspect what was extracted:
/knowledge/search does a semantic search over the content of the files you’ve ingested. Omit sourceId to search the whole workspace knowledge base, or narrow to one or more sources:
sourceId is optional and may be a single id or an array of 2 to 30 ids (fanned out then merged); score is the cosine distance (lower = more relevant). This endpoint is workspace-scoped (no organizationId/documentId). Full request shapes: Ingest Knowledge, Get Ingest Status, List Extracted Rules, List Knowledge Sources, and Search Knowledge Base.
Large or binary files (up to 30 MB): call Get Upload URL with
{ mimeType, fileSize, fileName }, PUT the raw bytes to the returned uploadUrl, then call ingest with { "source": "fileRef", "fileRef": "<the gs:// URI>", "mimeType": "..." }.Step 2: Ask a question
Ask Memory a natural-language question. The answer is grounded in your judgments + knowledge, and comes with citations and a confidence score:If Memory has no relevant context,
ask returns an empty answer ("") with confidence: 0 rather than inventing one. Treat that as “nothing learned about this yet”; it’s expected for brand-new workspaces.Step 3: Search past decisions
When you want the underlying records rather than a synthesized answer, usesearch:
actionUser), and a similarity score. Two handy overrides:
- Recent activity: add
"recencyDays": 7to get the last week’s decisions instead of a semantic match. - One thread: add
"filters": { "annotationId": "<id>" }with anorganizationIdto read a single comment thread chronologically.
Step 4: Get a suggestion
Ask Memory what it would recommend for a new item, grounded in precedent:primary is the best-grounded recommendation; conflict is populated when the evidence is split, so you can surface “reviewers disagree here.” Full request shape: Suggest Decision.
Going further
Short pointers to the rest of the surface. Field-level detail lives in the REST API Reference.- Filters & date ranges: narrow
search/ask/judgments/querybydecision,judgeType(human/agent),contentType,reviewerId, ordateRange({ start, end }, ISO-8601 or epoch ms). - Recency-true mode: set
recencyDays(1 to 365) onsearch/askto get the most-recent activity instead of a semantic match, which is ideal for digests. - Scopes: pass
organizationId(anddocumentId) to narrow reads;documentIdrequiresorganizationId. - Structured listing vs. semantic search: use
judgments/querywhen you want to list decisions by metadata (no embedding) instead of ranking by similarity. - Insights: pull a reviewer’s behavioral profile (
profiles/get), detected patterns (patterns/get), and workspace stats (stats/get). - Alerts: list proactive alerts, dismiss or mark them actioned, and tune generation via
alerts/config/update(enabled,maxAlertsPerWeek,enabledAlertTypes,severityThreshold). - Knowledge lifecycle:
updatere-runs the pipeline and bumps a source’s version;downloadreturns the canonical markdown;deletehard-removes a source and its derived chunks/rules (blocked while a source is still processing or has dedup dependents);knowledge/searchsemantic-searches the ingested file content (optionally narrowed bysourceId).
Errors & troubleshooting
Errors use the standard envelope with a gRPC-style status:| Code | Meaning |
|---|---|
INVALID_ARGUMENT | Request failed validation. |
UNAUTHENTICATED | Missing/invalid x-velt-auth-token. |
NOT_FOUND | Unknown sourceId. |
FAILED_PRECONDITION | e.g. deleting a source that’s still processing or has dedup dependents. |
RESOURCE_EXHAUSTED | Rate limit, or the outstanding-upload quota on upload-url; back off and retry. |
INVALID_ARGUMENT):
- Using
filters.annotationIdwithoutorganizationId; the annotation lookup needs an org. - Passing
documentIdwithoutorganizationId. - A
dateRangewhosestartis afterend. - An unsupported file type, or an inline file that decodes to more than 5 MB (use
upload-urlfor larger files).
Limitations
- Ingestion is asynchronous:
ingestreturnsstatus: "processing"; pollingest-statusfor the terminal state. A duplicate upload (dedupOfset in the status) reports the winning source’s status, so it can stayprocessinguntil the original finishes;completedalways means “safe to download”. - File limits: inline up to 5 MB, by-reference up to 30 MB; PDF / CSV / XLSX / plain text only.
- Judgments are read-only via this API: they’re created from review activity, not written directly.
- New workspaces start empty:
askreturns an empty answer andsuggest/insights stay sparse until enough review history exists.

