Skip to content

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).