> ## Documentation Index
> Fetch the complete documentation index at: https://docs.memory.anonalabs.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Searching Over Time

> Date your memories, filter and rank by event time, and reproduce a past answer.

Memory that only answers "what is true now" can't answer "what did we think in
June", and can't tell a fact from last week apart from one from last year. This
guide covers the time controls Anona exposes, which one to reach for, and where
the edge is.

## Two clocks, not one

Every memory carries two independent times. Almost every confusion about
temporal search comes from conflating them.

| | Set by | Returned as | Meaning |
| - | - | - | - |
| **Event time** | `timestamp` on `record` | `timestamp` | When the thing happened. |
| **Event window** | a date written in the memory's own text | `occurred_start` / `occurred_end` | The span that text described, when it described one. |
| **Record time** | the system, at write | `created_at` | When you told us about it. |

The `timestamp` you send comes back as `timestamp` — it is **not** copied into
`occurred_start`. Those two fill only from a date the memory's text itself names,
and are `null` otherwise, which is the common case and not a gap in the data.

For a memory written as the conversation happens they're the same instant. They
diverge the moment you import history: a note about last June, uploaded today,
happened in June and was recorded today.

## Dating a memory

Pass `timestamp` (ISO 8601) on `record` or on any item in `record/batch`:

```python Python theme={null}
client.record(
    space_id="support",
    content="The Q3 launch slipped to October.",
    timestamp="2026-06-01T00:00:00Z",
)
```

```typescript TypeScript theme={null}
await client.record({
  spaceId: "support",
  content: "The Q3 launch slipped to October.",
  timestamp: "2026-06-01T00:00:00Z",
});
```

```bash cURL theme={null}
curl -X POST https://api.anonalabs.com/v1/record \
  -H "Authorization: Bearer anona_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "space_id": "support",
    "content": "The Q3 launch slipped to October.",
    "timestamp": "2026-06-01T00:00:00Z"
  }'
```

Omit it and it defaults to now. Dating imported memories is worth the effort:
ranking is recency-aware, so an undated backfill arrives looking uniformly
fresh and competes with genuinely recent memories.

## Reproducing a past answer

`as_of` drops every memory **recorded** after an instant, so retrieval answers
from what the space knew at that moment:

```bash cURL theme={null}
curl -X POST https://api.anonalabs.com/v1/retrieve \
  -H "Authorization: Bearer anona_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "space_id": "support",
    "query": "what plan is this customer on?",
    "as_of": "2026-06-01T00:00:00Z"
  }'
```

```python Python theme={null}
results = client.retrieve(
    space_id="support",
    query="what plan is this customer on?",
    as_of="2026-06-01T00:00:00Z",
)
```

```typescript TypeScript theme={null}
const results = await anona.retrieve({
  spaceId: "support",
  query: "what plan is this customer on?",
  asOf: "2026-06-01T00:00:00Z",
});
```

This is the one to reach for when auditing a decision ("the agent told the
customer X on June 1st, what was it working from?") or when regression-testing
retrieval against a frozen corpus while new memories keep arriving.

> [!NOTE]
>
> Under `as_of`, retrieval skips its graph-expansion pass and answers from
> semantic, keyword and temporal retrieval only. Expansion follows entity links
> without a time bound, so it could pull in a memory recorded after the cutoff:
> a wrong answer for point-in-time recall, not a ranking artifact. An `as_of`
> search is therefore slightly narrower than the same search without it.

## Moving "now"

`query_timestamp` changes the instant that recency scoring and relative dates in
the query are measured against. It **re-ranks and never removes**, which is the
whole difference from `as_of`:

```bash cURL theme={null}
curl -X POST https://api.anonalabs.com/v1/retrieve \
  -H "Authorization: Bearer anona_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "space_id": "support",
    "query": "what changed last quarter?",
    "query_timestamp": "2026-06-01T00:00:00Z"
  }'
```

```python Python theme={null}
results = client.retrieve(
    space_id="support",
    query="what changed last quarter?",
    query_timestamp="2026-06-01T00:00:00Z",
)
```

```typescript TypeScript theme={null}
const results = await anona.retrieve({
  spaceId: "support",
  query: "what changed last quarter?",
  queryTimestamp: "2026-06-01T00:00:00Z",
});
```

Here "last quarter" resolves against June 1st rather than today, and memories
near that date rank higher. A memory recorded last week can still come back.
If you need it excluded, that's `as_of`.

Reach for `query_timestamp` when the query text itself contains a relative date,
or when replaying a historical conversation and you want period-appropriate
memories to surface without hiding anything.

## Which one

| You want | Use |
| - | - |
| Date a memory to when the event happened | `timestamp` on `record` |
| Memories about things that **happened** in a window | `occurred_after` / `occurred_before` |
| What did the space know at time T | `as_of` |
| Resolve "last June" / "two weeks ago" in the query | `query_timestamp` |
| Rank older-but-time-relevant memories higher | `query_timestamp` |
| Exclude memories recorded after a cutoff | `as_of` |

All of these take an ISO 8601 instant and are rejected as `422` before the
search runs if malformed, so a typo never costs a charged call. They compose
with each other and with scoping and tags.

## Filtering on event time

`occurred_after` and `occurred_before` keep only memories describing something
that **happened** inside the window — the filter `as_of` is not:

```bash cURL theme={null}
curl -X POST https://api.anonalabs.com/v1/retrieve \
  -H "Authorization: Bearer anona_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "space_id": "support",
    "query": "what shipped?",
    "occurred_after": "2026-06-01T00:00:00Z",
    "occurred_before": "2026-07-01T00:00:00Z"
  }'
```

```python Python theme={null}
results = client.retrieve(
    space_id="support",
    query="what shipped?",
    occurred_after="2026-06-01T00:00:00Z",
    occurred_before="2026-07-01T00:00:00Z",
)
```

```typescript TypeScript theme={null}
const results = await anona.retrieve({
  spaceId: "support",
  query: "what shipped?",
  occurredAfter: "2026-06-01T00:00:00Z",
  occurredBefore: "2026-07-01T00:00:00Z",
});
```

A memory matches on its `occurred_start` / `occurred_end` window when its text
named a date, and **falls back to `timestamp`** when it did not — so a dated
import matches a June window even though nothing in its text says June. An
event spanning either edge counts as inside. Details and edge cases:
[Filtering on event time](https://docs.memory.anonalabs.com/api-reference/retrieve.md#filtering-on-event-time).

This is what makes a dated bulk import addressable: every item was *recorded*
today whatever `timestamp` it carries, so `as_of` can't separate the periods —
`occurred_after` / `occurred_before` can.

Two techniques still worth knowing alongside the filter:

1. **Tag by period at write time.** `tags: ["2026-Q2"]` on import, then
   `tags: ["2026-Q2"], tags_match: "all_strict"` on retrieve — an exact filter
   that also works for periods that aren't calendar windows (a sprint, a
   campaign).
2. **Put the period in the query text.** Retrieval parses relative and absolute
   dates in the query and has a dedicated temporal retrieval arm, so
   "what happened in June 2026" is a meaningfully better query than "what
   happened".

## Related

* [Record](https://docs.memory.anonalabs.com/api-reference/memories.md): `timestamp` on write
* [Retrieve](https://docs.memory.anonalabs.com/api-reference/retrieve.md#searching-over-time): `as_of` and `query_timestamp`
* [Bulk import](https://docs.memory.anonalabs.com/guides/bulk-import-webhooks.md): dating a backfill
* [Tuning recall](https://docs.memory.anonalabs.com/guides/tuning-recall.md): the non-temporal knobs


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.