Context & facts
Get facts
Read the typed facts Korely extracted from your memories, deterministically, with no model call. Filter by entity or predicate family, and travel back in time with 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 | , | Filter to one end user. When omitted, facts are returned across all end users (no end-user scoping). |
agent_id | string | , | Optional agent-namespace filter. |
subject | string | , | Match the subject side of the triple only. |
entity | string | , | Match the subject or the object side, every fact mentioning this entity. |
predicate | string | , | Filter by exact predicate (e.g. works_at). |
predicate_family | string | , | Filter by predicate family (e.g. employment), expanded at the SQL level to every predicate in the family. |
include_invalidated | boolean | false | When true, also include superseded facts. They carry invalid_at and invalidated_by so you can trace the supersede chain. |
as_of | string | , | 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. |
limit | integer | 50 | Page size. Range 1-200. |
offset | integer | 0 | Pagination offset. Minimum 0. |
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=employment" \ --data-urlencode "limit=50"Response
200 OK. A page of typed facts plus the total matching count
(before paging).
{ "facts": [ { "id": "fct_a1", "subject": "Giulia", "subject_type": "person", "predicate": "works_at", "predicate_raw": "works at", "object": "Acme Corp", "object_is_literal": false, "predicate_family": "employment", "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_8f2c1a", "created_at": "2026-03-01T09:14:22+00:00" } ], "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, e.g. fct_a1. |
facts[].subject | string | The subject of the triple. |
facts[].subject_type | string | The inferred type of the subject, e.g. person. |
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. employment. |
facts[].confidence | number | Extraction confidence, 0-1. |
facts[].user_id / facts[].agent_id | string · null | The scope the fact belongs to (null if unscoped). |
facts[].valid_from | string | ISO 8601, when the fact became true (bi-temporal valid time). |
facts[].invalid_at | string · null | ISO 8601, when the fact was superseded, or null if still valid. |
facts[].invalidated_by | string · null | The id of the fact that superseded this one, or null. |
facts[].source_memory_id | string | The memory this fact was extracted from. |
facts[].created_at | string | ISO 8601, when the fact row was written. |
total | integer | Total facts matching the filters, before limit / offset paging. |
Errors
| Status | Code | Cause |
|---|---|---|
401 | invalid_key | Missing or invalid Authorization header. Detail: Invalid or missing API key; response carries WWW-Authenticate: Bearer. |
403 | forbidden | The API key lacks the memories:read scope. Detail: API key missing required scope(s): memories:read. |
422 | invalid_as_of | as_of is not a parseable ISO date or datetime. Detail: as_of must be an ISO date (2026-06-01) or datetime. 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. Detail: Rate limit exceeded (... per ...). Retry shortly.; response carries Retry-After and X-RateLimit-* headers. |
429 | quota_exceeded | Monthly query quota (plus 10% grace) exhausted. Structured detail: {"code":"quota_exceeded","message":"Monthly query limit reached (...). Upgrade for more."}. |
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. Superseded facts are excluded by default. Pass
include_invalidated=trueto surface them, they carryinvalid_atandinvalidated_byso you can walk the chain. - Entity vs subject.
entitymatches the subject or the object side;subjectmatches only the subject.predicate_familyis expanded at the SQL level to every predicate in that family. - Scope. When
user_idis omitted there is no end-user scoping, facts are returned across all your end users. - 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.