Korely

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.

GET /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.

ParameterTypeDefaultDescription
user_idstring, Filter to one end user. When omitted, facts are returned across all end users (no end-user scoping).
agent_idstring, Optional agent-namespace filter.
subjectstring, Match the subject side of the triple only.
entitystring, Match the subject or the object side, every fact mentioning this entity.
predicatestring, Filter by exact predicate (e.g. works_at).
predicate_familystring, Filter by predicate family (e.g. employment), expanded at the SQL level to every predicate in the family.
include_invalidatedbooleanfalseWhen true, also include superseded facts. They carry invalid_at and invalidated_by so you can trace the supersede chain.
as_ofstring, 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.
limitinteger50Page size. Range 1-200.
offsetinteger0Pagination offset. Minimum 0.

Example request

Terminal window
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
}
FieldTypeDescription
factsarray<object>The page of serialized facts. Each item carries the fields below.
facts[].idstringThe fact id, e.g. fct_a1.
facts[].subjectstringThe subject of the triple.
facts[].subject_typestringThe inferred type of the subject, e.g. person.
facts[].predicatestringThe normalized predicate, e.g. works_at.
facts[].predicate_rawstringThe predicate as it appeared in the source text, e.g. works at.
facts[].objectstringThe object of the triple.
facts[].object_is_literalbooleantrue when the object is a literal value rather than an entity.
facts[].predicate_familystringThe family the predicate belongs to, e.g. employment.
facts[].confidencenumberExtraction confidence, 0-1.
facts[].user_id / facts[].agent_idstring · nullThe scope the fact belongs to (null if unscoped).
facts[].valid_fromstringISO 8601, when the fact became true (bi-temporal valid time).
facts[].invalid_atstring · nullISO 8601, when the fact was superseded, or null if still valid.
facts[].invalidated_bystring · nullThe id of the fact that superseded this one, or null.
facts[].source_memory_idstringThe memory this fact was extracted from.
facts[].created_atstringISO 8601, when the fact row was written.
totalintegerTotal facts matching the filters, before limit / offset paging.

Errors

StatusCodeCause
401invalid_keyMissing or invalid Authorization header. Detail: Invalid or missing API key; response carries WWW-Authenticate: Bearer.
403forbiddenThe API key lacks the memories:read scope. Detail: API key missing required scope(s): memories:read.
422invalid_as_ofas_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.
429rate_limit_exceededPer-tier minute / hour / day request limit exceeded. Detail: Rate limit exceeded (... per ...). Retry shortly.; response carries Retry-After and X-RateLimit-* headers.
429quota_exceededMonthly 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_of accepts 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=true to surface them, they carry invalid_at and invalidated_by so you can walk the chain.
  • Entity vs subject. entity matches the subject or the object side; subject matches only the subject. predicate_family is expanded at the SQL level to every predicate in that family.
  • Scope. When user_id is omitted there is no end-user scoping, facts are returned across all your end users.
  • Paging. limit defaults to 50 (range 1-200), offset defaults to 0. total reflects the full match count before paging.

Related