Context & facts
Get facts
Read the typed facts Korely extracted from your memories, deterministically, with no model call. Filter by entity or predicate family, travel back in time with as_of, and ask what the store knew on a date with known_as_of.
/v1/facts
SDK: korely.get_facts(...). This is a pure SQL filter-and-sort
over the facts extracted from your memories, no embeddings, no LLM, fully
deterministic. Every fact is a typed (subject, predicate, object)
triple with bi-temporal validity, so you can ask "what was true on this date"
with as_of.
Authentication
HTTP header, required: Authorization: Bearer kor_live_.... The key must carry the memories:read scope.
Query parameters
All parameters are optional. With none set, you get the most recent valid facts across all your end users.
| Parameter | Type | Default | Description |
|---|---|---|---|
user_id | string | None | Filter to one end user. When omitted, facts are returned across all end users the key can read (every end user of the project, or the confined key's own). |
agent_id | string | None | Optional agent-namespace filter. |
subject | string | None | Match the subject side of the triple only. Exact and case-insensitive on the subject's current name: a former name (an alias) finds the same entity. An alias belongs to the end user and agent whose memory stated it, so across end users each fact is matched under what its own end user means by the name: if Maria's Acme is now Globex and Luca's Acme is still Acme, subject=Acme without user_id returns both. |
entity | string | None | Match the subject or the object side, every fact mentioning this entity. Same matching as subject. |
predicate | string | None | Filter by one predicate (e.g. works_at). Normalized like a written predicate (works at becomes works_at). A fact matches when it is stored under that form, or under the relation the phrase names in the learned vocabulary of that fact's own end user. |
predicate_family | string | None | Filter by predicate family: one of preferences, people, places, work, ownership, health, financial, events, identity, other. Case-insensitive; an unknown family returns an empty list, not an error. Matches the family stored on each fact, decided once per relation when the vocabulary learns it. |
include_invalidated | boolean | false | When true, also include facts that are no longer true. They carry invalid_at and invalidated_by so you can trace the supersede chain. Ignored when as_of is set. |
as_of | string | None | ISO date or datetime, point-in-time validity. Returns the facts that were valid at that instant. A naive value is coerced to UTC; a bare date (2026-06-01) means midnight. |
known_as_of | string | None | ISO date or datetime, what the store knew then: the facts it had learned by that moment, each with the end it had learned by then, true at as_of (by default, at known_as_of itself). An end learned later is not shown. With include_invalidated=true and no as_of, every fact learned by then, ended or not. Parsed like as_of. |
limit | integer | 50 | Page size. Range 1-200. |
offset | integer | 0 | Pagination offset. Minimum 0. At most 9223372036854775807 (2^63-1); a larger one answers 422. |
exclude_sessions | boolean | false | Leave out the facts that only work sessions state: the memories written with kind: "session", what a coding assistant's hooks save. A fact that a note states too stays in. See Work sessions. |
Example request
curl -G https://api.korely.ai/v1/facts \ -H "Authorization: Bearer kor_live_..." \ --data-urlencode "user_id=customer-giulia-4812" \ --data-urlencode "predicate_family=work" \ --data-urlencode "limit=50"What the store knew on a date
as_of asks what was true on a date, as the store knows it now.
known_as_of asks what the store knew on that date. A customer
who moved on 1 September, told on 5 October:
curl -G https://api.korely.ai/v1/facts \ -H "Authorization: Bearer kor_live_..." \ --data-urlencode "user_id=customer-4812" \ --data-urlencode "known_as_of=2026-09-20"# the old address: on 20 September the move was not told yetSee Temporal facts for the two clocks and their limits.
Response
200 OK. A page of typed facts plus the total matching count
(before paging).
{ "facts": [ { "id": "fct_3b9e1d7a5c2f4e8a9d6b0c1f7a2e4d85", "subject": "Giulia", "subject_type": "person", "predicate": "works_at", "predicate_raw": "works at", "object": "Acme Corp", "object_is_literal": false, "predicate_family": "work", "confidence": 0.92, "user_id": "customer-giulia-4812", "agent_id": "support-bot", "valid_from": "2026-03-01T00:00:00+00:00", "invalid_at": null, "invalidated_by": null, "source_memory_id": "mem_8f2c1a0b9d3e4f5a6b7c8d9e0f1a2b3c", "created_at": "2026-03-01T09:14:22+00:00", "closed_known_at": null, "subject_canonical": "Giulia", "object_canonical": "Acme Corp", "tense": "current", "last_confirmed_at": "2026-05-12T16:40:03+00:00", "observation_count": 2, "source_memory_ids": ["mem_8f2c1a0b9d3e4f5a6b7c8d9e0f1a2b3c", "mem_41d0e7a2b3c4d5e6f708192a3b4c5d6e"] } ], "total": 1}| Field | Type | Description |
|---|---|---|
facts | array<object> | The page of serialized facts. Each item carries the fields below. |
facts[].id | string | The fact id (fct_ and 32 hex characters). |
facts[].subject | string | The subject of the triple. |
facts[].subject_type | string | From extraction: person, organization, product, place, concept, event or unknown. On a fact written with POST /v1/facts, what the caller sent. |
facts[].predicate | string | The normalized predicate, e.g. works_at. |
facts[].predicate_raw | string | The predicate as it appeared in the source text, e.g. works at. |
facts[].object | string | The object of the triple. |
facts[].object_is_literal | boolean | true when the object is a literal value rather than an entity. |
facts[].predicate_family | string | The family the predicate belongs to, e.g. work. |
facts[].confidence | number · null | Extraction confidence, 0-1, rounded to three decimals. |
facts[].user_id / facts[].agent_id | string · null | The scope the fact belongs to (null if unscoped). |
facts[].valid_from | string · null | ISO 8601, when the fact became true (bi-temporal valid time). |
facts[].invalid_at | string · null | ISO 8601, when the fact stopped, or will stop, being true: a contradiction, a correction, a forget or a past write. null while it is open; a future value is a known end date, and the fact is true until then. |
facts[].invalidated_by | string · null | The id of the fact that superseded this one, or null. |
facts[].source_memory_id | string · null | The memory this fact was first extracted from; null for a fact written directly with POST /v1/facts. |
facts[].created_at | string · null | ISO 8601, when the store learned the fact. |
facts[].closed_known_at | string · null | ISO 8601, when the store learned the fact had ended. null while it is open, and with known_as_of when the end was learned after that date. |
facts[].subject_canonical | string | The subject's current name after aliases (subject keeps the words as written). |
facts[].object_canonical | string | The object's current name after aliases. |
facts[].tense | string | current, past or planned, as the text or the writer said it. |
facts[].last_confirmed_at | string · null | ISO 8601, the latest time the fact was stated, by a memory or a direct write (when it was never restated, when it was first stated). |
facts[].observation_count | integer | How many times the fact was asserted, by memories or by direct writes. Above 1 it was reconfirmed, not duplicated. |
facts[].source_memory_ids | array<string> | Every mem_ id that asserts the fact. |
total | integer | Total facts matching the filters, before limit / offset paging. |
Errors
| Status | Code | Cause |
|---|---|---|
401 | invalid_key | Missing or invalid Authorization header. Message: Invalid or missing API key: ..., then what is wrong; response carries WWW-Authenticate: Bearer. |
403 | forbidden | The API key lacks the memories:read scope. Message: API key missing required scope(s): memories:read; or the key is confined to some end users and user_id names another one. |
422 | invalid_request | as_of or known_as_of is not a parseable ISO date or datetime. Message: as_of must be an ISO date (2026-06-01) or datetime, with the name of the parameter you sent; as_of or known_as_of is outside the moments that can be stored (as_of is outside the moments that can be stored: from 0001-01-02 to 9999-12-30, in UTC, with the name of the parameter you sent); user_id or agent_id is empty, over 255 characters or holds a NUL byte; subject, predicate or predicate_family is over 200 characters, entity over 500, or any holds a NUL byte. A standard validation 422 is also returned if limit or offset falls outside its range. |
429 | rate_limit_exceeded | Per-tier minute / hour / day request limit exceeded. Message: Rate limit exceeded (<limit>/<unit>): try again in <n> s; the response carries a Retry-After header. |
429 | quota_exceeded | Monthly query quota (plus 10% grace) exhausted. The body carries code and message at the top level ("Monthly query limit reached: ... queries on the ... plan this month, plus a 10% grace. It starts again on ..."), and detail holds code, message, limit (the plan's figure), used and resets_at (00:00 UTC on the 1st). No Retry-After: read detail.resets_at. |
Notes
- Deterministic. No model or LLM call, a pure SQL filter and sort. The same query returns the same facts every time.
- Travel through time.
as_ofaccepts an ISO date (2026-06-01→ midnight) or a full datetime; naive values are coerced to UTC. It returns the facts that were valid at that instant. - Supersede, not delete. Facts that are no longer true are excluded by default: a fact is current while
valid_fromis not in the future andinvalid_atisnullor still ahead. Passinclude_invalidated=trueto surface the others, they carryinvalid_atandinvalidated_byso you can walk the chain. - What the store knew.
known_as_ofreads the second clock:created_at, when the store learned a fact, andclosed_known_at, when it learned the fact had ended. Use it to see what an agent could have known when it decided. Aclosed_known_atof a fact closed before service version 0.1.26 (11 October 2026) is an estimate. - Order. Without
as_oforknown_as_of, the most recently confirmed first (last_confirmed_at, elsevalid_from, descending); with either, byvalid_fromdescending. - Entity vs subject.
entitymatches the subject or the object side;subjectmatches only the subject.predicate_familymatches the family stored on each fact. - Scope. When
user_idis omitted, facts are returned across all end users the key can read (every end user of the project, or the confined key's own). - Paging.
limitdefaults to 50 (range 1-200),offsetdefaults to 0.totalreflects the full match count before paging.
Related
- Get context, the assembled recall block, facts and memories in one call.
- Write a fact, add a typed triple directly.
- SDK reference, the
get_factsmethod and its arguments.