Bi-temporal queries: as_of, valid_during, recorded_during, plus natural-language phrases.

Temporal Queries

Time is a first-class dimension in CortexDB. Every derived record carries four time fields (valid_from, valid_to, recorded_from, recorded_to), and every read endpoint accepts a temporal block that clips both axes.

For the full model, see Bi-temporal Model.

On /v1/recall and /v1/answer

pack = client.recall(
    scope="org:acme/dept:eng",
    query="What database are we using for payments?",
    view="holistic",
    temporal={
        "as_of":          "2026-04-15T00:00:00Z",   # both axes ≤ this instant
        "natural":        "last 30 days",             # parsed against reference_date
        "reference_date": "2026-05-16T00:00:00Z",
    },
)
FieldEffect
as_ofClips both axes — recorded_* ≤ as_of AND valid_from ≤ as_of < valid_to
valid_during[start, end] two-element array on the world-time axis (RFC 3339 datetimes or date-only strings; a date-only end is inclusive)
recorded_during[start, end] two-element array on the ingest-time axis
naturalPhrase like "last week", "this quarter", "fiscal Q3" (register custom phrases via /v1/temporal/phrases)
reference_dateAnchor for natural; defaults to request time

On layer reads

GET /v1/events accepts since (ISO-8601), and GET /v1/facts accepts as_of, min_confidence, and include_superseded:

# Events observed since March 1
events = client.events(
    scope="org:acme/dept:eng",
    since="2026-03-01T00:00:00Z",
    limit=200,
)

The Python SDK's client.facts() exposes subject / predicate only, so pass the temporal parameters over REST:

import requests, os
H = {"Authorization": f"Bearer {os.environ['CORTEX_TOKEN']}", "X-Cortex-Actor": os.environ["CORTEX_ACTOR"]}

# Facts as the system saw them on April 15
facts = requests.get(
    "https://api-v1.cortexdb.ai/v1/facts",
    headers=H,
    params={
        "scope": "org:acme/dept:eng",
        "subject": "ent_payments_service",
        "as_of": "2026-04-15T00:00:00Z",
        "include_superseded": "false",   # only the value that was current then
    },
).json()

The supersession chain

GET /v1/facts/timeline?subject=…&predicate=… returns every value the system has held for that (subject, predicate) pair, with the validity window for each:

timeline = requests.get(
    "https://api-v1.cortexdb.ai/v1/facts/timeline",
    headers=H,
    params={"subject": "ent_payments_service", "predicate": "database"},
).json()

for row in timeline["timeline"]:
    print(f"  {row['value']:>12}  valid {row['valid_from']} → {row['valid_to'] or 'now'}")
       postgres  valid 2024-01-01T00:00:00Z → 2026-03-15T10:00:00Z
    cockroachdb  valid 2026-03-15T10:00:00Z → now

This is what lets you ask "What database did we use for payments before the migration?" — pass as_of set to the day before the migration and the right value comes back.

Why two axes

Single-axis systems can answer either "what was true at time T" or "what did the system know at time T", but not both. CortexDB tracks valid_* (world time) and recorded_* (ingest time) independently, so you can reconstruct historical model statewhat did the system believe about X on April 15, as observed from May 1?

Custom temporal phrases

Register tenant-specific phrases via POST /v1/temporal/phrases:

import requests, os
requests.post(
    "https://api-v1.cortexdb.ai/v1/temporal/phrases",
    headers={"Authorization": f"Bearer {os.environ['CORTEX_TOKEN']}", "X-Cortex-Actor": os.environ["CORTEX_ACTOR"], "Content-Type": "application/json"},
    json={
        "name":        "fiscal_q3",
        "pattern":     "fiscal Q3",
        "resolves_to": {"valid_during": ["2026-07-01", "2026-10-01"]},
    },
)

Then temporal: {"natural": "fiscal Q3"} on recall/answer is parsed against that window.