Quickstart¶
Five minutes. At the end you will have stored four memories and retrieved the two that matter for a specific question, with the scores that put them there.
These snippets are tested
Every request and every response body on this page is produced by
docs-site/examples/verify_quickstart.py, which runs against the real
application. If the API changes, that script fails before this page ships.
1. Get an API key¶
Sign up at app.venkai.fr, then Settings → API keys → Create. The raw key is shown once.
curl -sX POST https://api.venkai.fr/api/auth/register \
-H 'Content-Type: application/json' \
-d '{"email":"you@example.com","password":"a-real-password","organization":"Acme"}' \
-c cookies.txt
curl -sX POST https://api.venkai.fr/api/auth/api-keys \
-H 'Content-Type: application/json' \
-b cookies.txt \
-d '{"label":"quickstart","environment":"production"}'
Either way you get:
{
"id": "key_b8f08563afb5",
"org_id": "org_1f200d429c50",
"label": "quickstart",
"environment": "production",
"api_key": "vk_live_EXAMPLE_KEY_NOT_A_REAL_CREDENTIAL_0000000000"
}
The raw key is returned exactly once
Only its hash is stored. Lose it and you rotate it — you cannot read it back. Keep it out of source control; see Configuration.
2. Configure¶
Check you can reach the service:
This is a readiness probe: it opens a database connection and runs
SELECT 1. A 503 means the API is up but its store is not.
3. Create a project¶
You do not have to. Writing to a project key that does not exist creates it.
billing-service below is a key you choose; keep it stable, because agents
carry it hard-coded.
4. Store memories¶
curl -sX POST https://api.venkai.fr/api/memory \
-H "Authorization: Bearer $VENKAI_API_KEY" \
-H 'Content-Type: application/json' \
-d '{
"project_id": "billing-service",
"agent_id": "planner",
"type": "decision",
"importance": 0.9,
"content": "We use Postgres, not MongoDB, because the ranking query needs joins.",
"metadata": {"ticket": "ARCH-14"}
}'
{
"id": "ctx_cc55e4a7bbc5",
"org_id": "org_1f200d429c50",
"project_id": "billing-service",
"agent_key": "planner",
"type": "decision",
"content": "We use Postgres, not MongoDB, because the ranking query needs joins.",
"confidence": 0.8,
"importance": 0.9,
"access_count": 0,
"last_accessed_at": null,
"created_at": 1787007131.3763673,
"updated_at": 1787007131.3763673,
"metadata": {"ticket": "ARCH-14"},
"embedding": [0.0, 0.0, 0.0, 0.30151134457776363, "… 128 floats in total"]
}
The write response includes the raw embedding vector
Only the write path returns it. Every read path (GET /api/context/…,
…/relevant) strips it before responding. Ignore the field; it is an
internal artefact and its length depends on your provider.
Add three more so ranking has something to do:
for m in \
'{"type":"constraint","importance":0.8,"content":"The retrieval endpoint must answer in under 200 ms at p95."}' \
'{"type":"fact","importance":0.4,"content":"The staging environment is rebuilt from scratch every Sunday night."}' \
'{"type":"preference","importance":0.2,"content":"The team writes commit messages in English."}' ; do
curl -sX POST https://api.venkai.fr/api/memory \
-H "Authorization: Bearer $VENKAI_API_KEY" -H 'Content-Type: application/json' \
-d "$(echo "$m" | python -c 'import json,sys; d=json.load(sys.stdin); d.update(project_id="billing-service", agent_id="planner"); print(json.dumps(d))')" \
-o /dev/null -w '%{http_code}\n'
done
Valid types are fact, decision, preference, event, constraint,
relationship. Anything else is a 422 — the API will not guess.
5. Retrieve the relevant context¶
curl -sG https://api.venkai.fr/api/context/billing-service/relevant \
-H "Authorization: Bearer $VENKAI_API_KEY" \
--data-urlencode 'query=which database did we pick' \
--data-urlencode 'limit=2'
{
"project_id": "billing-service",
"query": "which database did we pick",
"memories": [
{
"id": "ctx_cc55e4a7bbc5",
"type": "decision",
"content": "We use Postgres, not MongoDB, because the ranking query needs joins.",
"importance": 0.9,
"access_count": 0,
"created_at": 1787007131.3763673,
"metadata": {"ticket": "ARCH-14"},
"score": 0.4789,
"similarity": 0.1348,
"justification": "semantic similarity 0.13 (HashingEmbeddingProvider, 128d)"
},
{ "…": "second result" }
]
}
Four memories in, two out. That is the whole product.
Note the low similarity
0.13 for an obviously on-topic memory is not a bug — it is the default
hashing provider, which measures token overlap in disguise, not meaning.
The decision still won because importance (0.9) and recency carry
60 % of the score. For real semantic matching, switch the provider:
Embeddings.
6. Inject it into an agent¶
import os, requests
BASE = os.environ["VENKAI_BASE_URL"]
H = {"Authorization": f"Bearer {os.environ['VENKAI_API_KEY']}"}
def venkai_context(project: str, task: str, limit: int = 5) -> str:
r = requests.get(f"{BASE}/api/context/{project}/relevant",
headers=H, params={"query": task, "limit": limit}, timeout=10)
r.raise_for_status()
memories = r.json()["memories"]
if not memories:
return ""
lines = [f"- [{m['type']}] {m['content']}" for m in memories]
return "What this project already established:\n" + "\n".join(lines)
task = "add a new billing plan"
prompt = f"{venkai_context('billing-service', task)}\n\nTask: {task}"
limit is your context budget. It is a number you set, not one that grows with
the age of the project.
Next¶
- First context and First retrieval — the same flow, one concept at a time.
- Add Venkai to an agent — where the two calls go in a real loop.
- Context selection — why
limitis the interesting parameter.