| name | hindsight-memory-api |
| description | Store, retrieve, and reflect on agentic memories via the Hindsight API. Use for persistent cross-session memory — conversation history, fact recall, memory-grounded answers, per-user memory banks. Triggers: remember: , retain/recall/reflect, agent memory, or storing document knowledge in a searchable memory store.
|
Hindsight Memory API — Agent Operations Guide
Base URL: https://hindsight.vectorize.io
Auth: Authorization: YOUR_API_KEY header on every request
OpenAPI spec: https://hindsight.vectorize.io/openapi.json
You are an agent calling this API directly. Use curl via bash for most
operations. For complex tasks (file ingestion, batch processing), write a
short JIT Python script and run it.
If no API key has been provided, ask the user: "What's your Hindsight API key?"
Agent Workflow
Think of memory as a three-verb loop:
| Verb | When to use |
|---|
| Retain | After learning something worth keeping — new facts, preferences, decisions, completed tasks |
| Recall | Before answering a question — pull relevant context from stored memory |
| Reflect | When synthesis is needed — Hindsight's LLM answers the question using stored memory (saves you a separate LLM call) |
Typical session flow:
- User message arrives → Recall relevant memories to ground your response
- After responding → Retain anything new and worth remembering
- For "what do you know about X?" type questions → Reflect directly
Quick Reference — Curl Examples
Replace $BANK, $KEY, and query text as appropriate.
Retain (store new memories)
curl -s -X POST "https://hindsight.vectorize.io/v1/default/banks/$BANK/memories" \
-H "authorization: $KEY" \
-H "content-type: application/json" \
-d '{
"items": [{
"content": "The user prefers dark mode and uses Neovim as their editor.",
"context": "user preferences",
"document_id": "prefs_001",
"tags": ["preferences"]
}],
"async": false
}'
Recall (semantic search)
curl -s -X POST "https://hindsight.vectorize.io/v1/default/banks/$BANK/memories/recall" \
-H "authorization: $KEY" \
-H "content-type: application/json" \
-d '{
"query": "What editor does the user prefer?",
"budget": "mid",
"max_tokens": 2048
}'
Reflect (memory-grounded Q&A — Hindsight answers for you)
curl -s -X POST "https://hindsight.vectorize.io/v1/default/banks/$BANK/reflect" \
-H "authorization: $KEY" \
-H "content-type: application/json" \
-d '{
"query": "Summarize what you know about the user'\''s technical preferences.",
"budget": "mid"
}'
List banks (find existing bank IDs)
curl -s "https://hindsight.vectorize.io/v1/default/banks" \
-H "authorization: $KEY"
Create or update a bank
curl -s -X PUT "https://hindsight.vectorize.io/v1/default/banks/$BANK" \
-H "authorization: $KEY" \
-H "content-type: application/json" \
-d '{
"reflect_mission": "You are a personal assistant. Use stored memories to give personalized, helpful answers.",
"retain_mission": "Focus on preferences, decisions, and action items. Ignore pleasantries.",
"retain_extraction_mode": "concise"
}'
Core Concepts
| Concept | What it is |
|---|
| Bank | Top-level memory container. One per user or agent. Has a bank_id, optional reflect_mission, and configuration. |
| Memory unit | An extracted fact. Type: world (factual knowledge), experience (conversations/actions), observation (synthesized via consolidation). |
| Document | Source item passed to retain. Tracked for upsert: re-retaining with the same document_id replaces old facts. |
| Entity | Named thing (person, org, place) auto-extracted and linked across memories. |
| Mental model | A living document auto-generated by a reflect query — stays current after consolidation. |
| Directive | Hard rule injected into LLM prompts during reflect, to steer behavior. |
| Consolidation | Async background process that distills raw memories into observations and refreshes mental models. |
| Tag | String label for scoping/filtering across memory banks. |
Retain — Detailed
curl -s -X POST "https://hindsight.vectorize.io/v1/default/banks/$BANK/memories" \
-H "authorization: $KEY" \
-H "content-type: application/json" \
-d '{
"items": [{
"content": "Alice said she prefers TypeScript over JavaScript for large projects after being burned by runtime type errors.",
"context": "preferences conversation",
"document_id": "chat_session_2024_01_15",
"timestamp": "2024-01-15T10:30:00Z",
"tags": ["preferences", "tech"]
}],
"async": false
}'
Key fields:
| Field | Notes |
|---|
content | Text to extract facts from. Can be a full conversation turn or document excerpt. |
context | Human-readable label for the context (e.g., "work meeting", "onboarding"). |
document_id | Enables upsert: re-retaining the same document_id replaces old memories from that document. Use stable IDs for things you'll update. |
timestamp | ISO timestamp of when the event occurred (defaults to now). |
tags | Labels for filtering in recall/reflect. Useful for scoping to specific users or topics. |
async | false (default) = wait for extraction. true = return operation_id and continue. |
Upsert pattern: Pass a stable document_id for any content you might update later. Re-ingesting with the same ID automatically removes old facts.
Recall — Detailed
The response contains a results array of memory units:
{
"results": [
{
"id": "abc123",
"text": "Alice prefers TypeScript for large projects",
"type": "world",
"entities": ["Alice"],
"context": "preferences conversation",
"occurred_start": "2024-01-15T10:30:00Z"
}
]
}
Key query fields:
| Field | Default | Notes |
|---|
query | required | Natural language question or topic |
types | ["world","experience"] | Add "observation" for synthesized facts |
budget | "mid" | "low" = fast/cheap, "mid" = balanced, "high" = thorough |
max_tokens | 4096 | Controls result volume |
query_timestamp | null | Temporal anchor for time-relative queries |
tags + tags_match | — | Scope to tagged memories (see tag filtering below) |
include.entities | — | Include entity states (people, orgs, etc.) in response |
Reflect — Detailed
Reflect runs an internal agent loop: it searches memories, then uses an LLM to synthesize an answer. Use it when you want Hindsight to do the synthesis rather than doing it yourself.
Optional: structured output
curl -s -X POST "https://hindsight.vectorize.io/v1/default/banks/$BANK/reflect" \
-H "authorization: $KEY" \
-H "content-type: application/json" \
-d '{
"query": "What are the user'\''s technical preferences?",
"budget": "mid",
"include": { "facts": {} },
"response_schema": {
"type": "object",
"properties": {
"summary": { "type": "string" },
"preferences": { "type": "array", "items": { "type": "string" } }
},
"required": ["summary", "preferences"]
}
}'
Response:
{
"text": "The user strongly prefers TypeScript...",
"structured_output": { "summary": "...", "preferences": ["TypeScript"] },
"based_on": { "memories": [{ "id": "abc123", "text": "...", "type": "world" }] },
"usage": { "input_tokens": 1500, "output_tokens": 300, "total_tokens": 1800 }
}
Key fields:
| Field | Default | Notes |
|---|
budget | "low" | Reflect default is low; use mid/high for complex questions |
response_schema | null | JSON Schema for structured output |
include.facts | — | Include based_on evidence (what memories were used) |
fact_types | all | Restrict: world, experience, observation |
exclude_mental_models | false | Skip mental models from influencing the answer |
Bank Configuration
Fine-grained config update:
curl -s -X PATCH "https://hindsight.vectorize.io/v1/default/banks/$BANK/config" \
-H "authorization: $KEY" \
-H "content-type: application/json" \
-d '{
"updates": {
"llm_model": "claude-sonnet-4-5",
"enable_observations": true,
"observations_mission": "Synthesize stable facts about the user'\''s skills, preferences, and ongoing projects."
}
}'
Read resolved config (global → tenant → bank):
curl -s "https://hindsight.vectorize.io/v1/default/banks/$BANK/config" \
-H "authorization: $KEY"
Mental Models
Living documents auto-generated from a reflect query and kept current after consolidation. Use for entity profiles, project summaries, recurring topics.
curl -s -X POST "https://hindsight.vectorize.io/v1/default/banks/$BANK/mental-models" \
-H "authorization: $KEY" \
-H "content-type: application/json" \
-d '{
"name": "User Tech Preferences",
"source_query": "What are the user'\''s programming language preferences, tool choices, and technical opinions?",
"tags": ["preferences"],
"max_tokens": 1024,
"trigger": { "refresh_after_consolidation": true }
}'
curl -s "https://hindsight.vectorize.io/v1/default/banks/$BANK/mental-models?detail=content" \
-H "authorization: $KEY"
curl -s -X POST "https://hindsight.vectorize.io/v1/default/banks/$BANK/mental-models/$MODEL_ID/refresh" \
-H "authorization: $KEY"
Content is generated asynchronously. Poll the returned operation_id to check when it's ready.
Directives
Hard rules injected into reflect prompts. Enforce output formats, personas, or behavioral constraints.
curl -s -X POST "https://hindsight.vectorize.io/v1/default/banks/$BANK/directives" \
-H "authorization: $KEY" \
-H "content-type: application/json" \
-d '{
"name": "always-cite-sources",
"content": "Always cite the specific memory that informs each claim.",
"priority": 10,
"is_active": true
}'
Higher priority = injected first. Disable without deleting: PATCH with "is_active": false.
File Ingestion
For ingesting PDFs, DOCX, images, audio, etc., write a short Python script — multipart/form-data is awkward in curl:
import requests, sys
bank, key, *files = sys.argv[1:]
url = f"https://hindsight.vectorize.io/v1/default/banks/{bank}/files/retain"
headers = {"authorization": key}
file_handles = [("files", (f, open(f, "rb"))) for f in files]
data = {"request": '{"async": true}'}
resp = requests.post(url, headers=headers, files=file_handles, data=data)
print(resp.json())
Run it: python ingest.py $BANK $KEY document.pdf notes.docx
Returns operation_ids. Poll for completion (see Async Operations below).
Async Operations
Any endpoint can return an operation_id when async: true. Poll for status:
curl -s "https://hindsight.vectorize.io/v1/default/banks/$BANK/operations/$OP_ID" \
-H "authorization: $KEY"
Statuses: pending, completed, failed. Note: completed operations are removed from storage, so a 404 after a short wait means it finished successfully.
curl -s -X POST "https://hindsight.vectorize.io/v1/default/banks/$BANK/operations/$OP_ID/retry" \
-H "authorization: $KEY"
curl -s -X DELETE "https://hindsight.vectorize.io/v1/default/banks/$BANK/operations/$OP_ID" \
-H "authorization: $KEY"
Tag Filtering Reference
tags_match value | Behavior |
|---|
any | OR match, includes untagged memories |
all | AND match, includes untagged memories |
any_strict | OR match, excludes untagged memories |
all_strict | AND match, excludes untagged memories |
For complex filtering, use tag_groups:
{
"tag_groups": [
{ "or": [
{ "tags": ["user:alice"], "match": "any_strict" },
{ "tags": ["shared"], "match": "any_strict" }
]}
]
}
Monitoring & Health
curl -s "https://hindsight.vectorize.io/health"
curl -s "https://hindsight.vectorize.io/version"
curl -s "https://hindsight.vectorize.io/v1/default/banks/$BANK/stats" \
-H "authorization: $KEY"
Deprecations to Avoid
| Avoid | Use instead |
|---|
GET/PUT /banks/{id}/profile | GET/PUT /banks/{id} or PATCH /banks/{id}/config |
POST /banks/{id}/background | PUT /banks/{id} with reflect_mission |
disposition fields on bank upsert | PATCH /banks/{id}/config |
document_tags on retain | Per-item tags |
context field on reflect | Include in the query string |
Entity regenerate endpoint | Mental models |