Every record carries both event time and ingest time. Why two axes are non-negotiable.

Bi-temporal Model

Every record except Events carries four time fields:

| Field | Meaning | |---|---| | valid_from | First moment in the world when the claim is true | | valid_to | First moment when the claim ceases to be true (exclusive). null = open-ended | | recorded_from | First moment CortexDB learned the claim | | recorded_to | First moment CortexDB superseded its own record (exclusive). null = current |

Events have just two: observed_at and recorded_at. Events are atomic in time and never superseded.

Why both axes

The question "what did the system believe about Acme on April 15 when looked at from May 1?" requires:

recorded_from ≤ May 1   AND   valid_from ≤ Apr 15 < valid_to

Single-axis systems can answer one or the other, never both. This is why Zep and Mem0 can't reconstruct historical model state — they don't track when they learned a thing.

Temporal queries

Pass temporal: { ... } to /v1/recall, /v1/answer, and the layer-read endpoints:

{
  "temporal": {
    "as_of":          "2026-05-01T00:00:00Z",
    "valid_during":   { "from": "2026-04-01", "to": "2026-04-30" },
    "natural":        "last 30 days",
    "reference_date": "2026-05-15T00:00:00Z"
  }
}

| Field | Semantics | |---|---| | as_of | Clips both axes: recorded_* ≤ as_of AND valid_from ≤ as_of < valid_to | | valid_during | Window on the world-time axis | | recorded_during | Window on the ingest-time axis | | natural | Parsed phrase (last week, this quarter, fiscal Q3, ...) | | reference_date | Anchor for natural phrases; default = request time |

as_of and include_superseded apply conjunctively — as_of clips both axes; include_superseded=true additionally returns historical versions whose recorded_to ≤ as_of.

Supersession chains

When a new fact comes in about a (subject, predicate) already on file, the older fact's valid_to (and possibly recorded_to) is closed. The chain is preserved — query it with GET /v1/facts/timeline:

{
  "subject":   { "id": "ent_acme_corp" },
  "predicate": "deal_stage",
  "timeline": [
    { "value": "poc",    "valid_from": "...",            "valid_to": "2026-04-10T..." },
    { "value": "close",  "valid_from": "2026-04-10T...", "valid_to": "2026-05-13T..." },
    { "value": "signed", "valid_from": "2026-05-13T...", "valid_to": null }
  ]
}

This is also what powers the "why do you think that?" trail on beliefs — supersession chains carry forward as evidence.

Natural-language parsing

Defaults shipped: today, yesterday, last week, this quarter, etc. Register tenant-specific phrases (e.g., "fiscal Q3", "holiday freeze") via POST /v1/temporal/phrases.