CortexDB Docs
Getting Started

Python Quickstart

Get from zero to a working stratified pack in under 5 minutes with the Python SDK.

Self-hosting? Skip the signup below

The recommended way to run CortexDB is to host it yourself. Against a self-hosted dev server (started with CORTEX_INSECURE_NO_AUTH=1) you need no token — construct the client with api_url="http://localhost:3141", actor="user:local", and jump to step 4. On a keyed server pass bearer="<your CORTEX_API_KEY>". The signup flow below is for the managed cloud.

1. Install

pip install cortexdbai
PackageName
PyPI packagecortexdbai
Python importcortexdb.v1

Requires Python 3.10+ (current release: 0.11.2). The HTTP dependencies (requests, httpx) are installed automatically with the package.

2. Sign up — no email, no card

The fastest way to get a working token is one anonymous POST. No form, no email, no redirect.

import requests
r = requests.post("https://api-v1.cortexdb.ai/v1/auth/signup", json={}).json()
TOKEN = r["token"]      # PASETO v4 bearer (7-day TTL on the free tier)
ACTOR = r["user_id"]    # e.g. "user:u_019e..."
SCOPE = r["scope"]      # your default scope path
print(r["expires_at"])  # ISO 8601; renew before this

If you already have a permanent CortexDB account, your IdP issues PASETO tokens the same way — substitute its URL for /v1/auth/signup. The CLI command cortexdb auth tokens mint is the operator-side equivalent.

3. Open a client

from cortexdb.v1 import V1Client

client = V1Client(
    api_url="https://api-v1.cortexdb.ai",
    actor=ACTOR,
    bearer=TOKEN,
)

print(client.whoami()["effective_capabilities"])

api_url defaults to http://localhost:3141 (a locally running server) as of cortexdbai 0.11.0 (it was 3142 in ≤0.10.0). Pass the cloud URL explicitly, as above, when using the hosted platform.

4. Capture an experience

result = client.experience(
    scope=SCOPE,
    text="Just got off a call with Priya at Acme. They upgraded to 200 seats.",
    role="user",
    observed_at="2026-05-16T10:42:00Z",
    idempotency_key="alice-chat-001",
)
print(result["event_id"])  # "evt_01HX..."
print(result["status"])    # "captured"

The SDK infers modality — pass role= and the SDK builds the right envelope. There is no modality= parameter on experience().

Returns 202 Accepted as soon as the WAL append succeeds. Pass wait="indexed" to block until BM25 + HNSW indexes have the event (30 s ceiling). wait is sent as ?wait=indexed and works from every SDK and from raw REST; for longer waits use GET /v1/lifecycle/stream?event_id=evt_… (see Lifecycle).

5. Recall a stratified pack

pack = client.recall(
    scope=SCOPE,
    view="holistic",
    query="What did we decide about Acme's renewal?",
    include=["events", "beliefs", "facts", "episodes"],
    budgets={"max_tokens": 4000},
    diagnostics="none",   # free-tier tokens don't hold diagnostics.read
)

print(pack.get("context_block", ""))
for fact in pack["layers"].get("facts", []):
    print(fact["predicate"], "=", fact["object"]["value"])

Free-tier capabilities. diagnostics="summary"/"full" require the diagnostics.read capability, which the free-tier token doesn't include — pass diagnostics="none" on the free tier.

Views. Free-tier tokens hold scope.read.local, scope.read.holistic, and scope.read.descend, so view="holistic" works out of the box. The accepted recall views are raw, granular (alias local), holistic, descend, lineage, structuredlocal is accepted and normalizes to granular.

6. Recall + LLM in one call

answer = client.answer(
    scope=SCOPE,
    question="Did Acme renew?",
    view="holistic",
    temporal={"natural": "last 30 days"},
    diagnostics="none",
)

print(answer["answer"])
for c in answer["citations"]:
    print(f"  {c['marker']}{c['layer']}:{c['id']}")

answer() is natural-language Q&A with full citations back to the events that supported the answer — build your UI around this.

7. Inspect why a belief exists

Facts populate within ~5–30 s of a write (LLM-extracted; requires enrichment configured — on a bare self-hosted instance the Facts/Beliefs layers stay empty, see Self-hosting defaults). Beliefs and Understanding are synthesized async (minutes+). Use client.facts(scope=…) as a smoke-test that extraction is running.

beliefs = client.beliefs(scope=SCOPE)
if beliefs["items"]:
    top = beliefs["items"][0]
    trail = client.belief_why(top["id"])   # belief items key their id as `id`, not `belief_id`
    print(trail["narrative"])

What's next

Async variant

from cortexdb.v1 import AsyncV1Client

async with AsyncV1Client(
    api_url="https://api-v1.cortexdb.ai",
    actor=ACTOR,
    bearer=TOKEN,
) as client:
    pack = await client.recall(scope=SCOPE, view="holistic", diagnostics="none")

On this page