Memory¶
Memory is the concept; context is the stored row. This page is about the write path: what happens between your POST and the row landing.
What happens on a write¶
sequenceDiagram
autonumber
participant A as Agent
participant API as Venkai API
participant E as Embedding provider
participant DB as Store
A->>API: POST /api/memory
API->>API: validate type ∈ 6 allowed values
Note over API: unknown type → 422, no row written
API->>API: resolve project key (create if absent)
API->>E: embed(content)
E-->>API: vector (128-d or 384-d)
API->>DB: INSERT context + embedding_json
DB-->>API: row
API-->>A: 200 + row (incl. raw embedding)
Everything is synchronous. There is no queue and no background embedding job: when the response arrives, the memory is fully written and immediately retrievable. The cost is that your write latency includes one embedding computation.
Write endpoints¶
POST /api/memory and POST /api/context are the same handler with the
same request body and the same response. Both accept:
{
"project_id": "billing-service",
"agent_id": "planner",
"content": "…",
"type": "decision",
"metadata": {},
"confidence": 0.8,
"importance": 0.5
}
Only project_id, agent_id and content are required.
Constraints that bite¶
| Rule | Consequence |
|---|---|
content is 1–8000 characters |
Longer → 422. Split it, or store a summary. |
type must be one of six |
Anything else → 422. No fallback. |
importance and confidence are 0–1 |
Out of range → 422. |
| The project key is created silently on write | A typo creates a second, empty project. Retrieval from it returns nothing and no error. |
That last one is the sharp edge. POST to billing-servce succeeds and
creates a project; the subsequent GET .../relevant on billing-service
returns an empty list. Pin the key in a constant.
Writing memories worth retrieving¶
The embedding comes from content and nothing else. Three habits follow.
Write the statement, not a pointer.
- "DB decision — see ARCH-14"
+ "We use Postgres, not MongoDB, because the ranking query needs joins."
One claim per memory. A memory is retrieved or not, whole. A paragraph covering four subjects gets pulled in for all four, and burns budget three times out of four.
Include the reason in a decision. "We use Postgres" tells a future agent
what; "…because the ranking query needs joins" tells it whether the decision
still holds when the constraint changes.
Deduplication¶
There is none. Writing the same sentence twice creates two rows, both retrievable, both consuming budget.
If your agent writes on every loop iteration, deduplicate before the POST —
GET .../relevant with your candidate text as the query and a high similarity
threshold is a workable check, or keep a local set of already-written hashes
for the session.
Planned — server-side dedup and redundancy-aware selection are not implemented.
Updating¶
curl -sX PATCH https://api.venkai.fr/api/context/ctx_cc55e4a7bbc5 \
-H "Authorization: Bearer $VENKAI_API_KEY" \
-H 'Content-Type: application/json' \
-d '{"content":"We use Postgres. Reversed 2026-08: MongoDB is out for good."}'
Changing content recomputes the embedding and records a version. An edited
memory ranks on its new text — an important correctness property, and one
that was not always true; see Persistence.
There is no delete endpoint for a single memory. You can supersede it with a
PATCH, or delete the whole organization (DELETE /api/organization).
Related¶
- Retrieval — how it comes back out
- Persistence — versions and embedding lifecycle
- Memory API — endpoint reference