Korely

Get Started

Platform Overview

A managed memory layer for AI agents.

Your agent sends Korely a sentence from a conversation, for example "Anna moved to Milan on 1 March". Korely stores it and turns it into a readable fact: Anna lives in Milan, since 1 March.

Later, in any session, your agent asks a question and gets back the facts that answer it, as text it can put straight into its prompt. This page describes Korely Cloud, which we run for you. You can also install Korely on your own computer: its code is on GitHub under the Apache License 2.0.

A first call

Install the package and set your Korely Cloud key. The Quickstart shows how to get one.

Terminal window
pip install korely-memory
export KORELY_API_KEY=kor_live_... # your Korely Cloud key

The facts need about ten seconds to appear after add(), so wait a moment before you read them.

import time
from korely_memory import Korely
korely = Korely() # reads KORELY_API_KEY from the environment
korely.add("Anna moved to Milan on 1 March.", user_id="anna-42")
time.sleep(10) # the facts are extracted in the background
ctx = korely.get_context(query="Where does Anna live?", user_id="anna-42")
print(ctx.context) # a block of text, ready for your prompt

add() answers at once with status: "processing". A model extracts the facts in the background, usually within about ten seconds. Then get_context() returns a block like this:

Illustrative example, not a real response
## Known facts
- Anna lives_in Milan (since 2026-03-01)
## Relevant memories
- [2026-03-05] Anna moved to Milan on 1 March.

If the block is empty, the facts may not be ready yet (about ten seconds) or the memory produced none. Read the facts with get_facts, which lists what Korely stored for a user. Check facts there before you rely on them. In Node.js the method is getContext().

flowchart LR
  A([Your agent]) -->|add| K[Korely]
  K --> E[Make memory searchable]
  K --> F[Facts<br/>valid_from / invalid_at]
  A -->|get_context| R[Assemble current facts<br/>+ relevant memories]
  F -.-> R
  E -.-> R
  R --> P([Block for your prompt])
add() starts the pipeline; the facts arrive a few seconds later. get_context assembles current facts and relevant memories into a block for your prompt.

Words you will meet

  • Memory and fact. A memory is the text you send with add(). A fact is a short statement a model extracts from it, as (subject, predicate, object). In "Anna lives in Milan" (stored as Anna lives_in Milan), the subject is Anna, the predicate is lives_in, the object is Milan.
  • Bi-temporal. A fact carries two clocks. The first says when it was true in the world: valid_from when it started, invalid_at when it stopped. The second says when Korely learned it. Anna moved on 1 March and you told Korely on 5 March: the first clock says 1 March, the second says 5 March. In the facts the API returns, the second clock is created_at (when Korely learned the fact) and closed_known_at (when Korely learned it had ended; null while the fact is open).
  • as_of and known_as_of. One date for each clock. as_of goes on the fact reads, such as get_facts(), and shows the facts as they were true in the world on that date. known_as_of goes on get_context() and shows what Korely knew on that date. For Anna, as_of of 1 March gives Milan. known_as_of of 3 March does not, because Korely learned of the move on 5 March.
  • Project and region. A project is a separate space for your memories, with its own keys. Your data is stored on Korely's servers in Helsinki, whatever the region. The project's region decides which model reads your text to write the facts: global (the default) uses a model from Google, outside the EU; eu uses Scaleway in Paris.
  • End user and agent_id. The end user is the person your agent talks to, identified by a user_id you choose. agent_id is the name of the agent that writes or reads. A write needs a user_id or an agent_id (why). Without a filter, an end user's memory is shared across your agents, so a newer fact from one agent can close a fact written by another. Closed facts stay in the history: add include_invalidated=true to see them.

What you get

  • Continuity, nothing to host. Memories and facts persist per end user, so your agent stops asking the same question twice. We run the database.
  • Current truth, with history. When a later memory gives a new value, such as a new city, the old fact is closed with invalid_at, not deleted.
  • Four ways in, one key. The SDK (Python and Node), the CLI, the REST API, and Korely MCP, which lets tools such as Claude or Cursor call Korely without code, accept the same kor_live_ Cloud key. Creating keys or listing projects needs a key with admin permission. Never give an admin key to an agent.
  • Reads without a language model. get_context() returns up to ten current facts, then the most relevant memories, within a token budget (800 tokens by default; a token is the unit a model reads). search() returns the best-matching memories, each with a score and a snippet. Neither calls a language model. Your question is turned into numbers (an embedding) on our own server, and matching is a database query. See Get context.
  • An entity graph. Ask for everything known about one name, such as "Anna". Every fact points back to the memory that stated it. See The graph.
  • Facts you can fix. Correct or forget a fact through the API or the Korely dashboard (the web app for your account), or erase an end user with one call (delete_all, deleteAll in Node). See how to review, correct and forget facts.
  • Where data is stored, and who reads it. Data is stored on Korely's servers in Helsinki (Hetzner), on every plan and in both regions. The text of a memory is read by a model from Google, outside the EU, in the default global region, and by Scaleway in Paris in the eu region. See Data governance.

Choose your path

Start with the Quickstart, then Core operations, Memory model, and Surfaces.