Concepts
Projects
A project groups API keys and walls off the memories and facts those keys write.
Use one project per environment or product, such as Staging and Production.
Your calls never name a project: Korely finds it from the key.
GET /v1/ping shows the project's
region (processing_region),
never its name.
This page is for developers who run several environments or products on one account.
Terms
The Glossary defines the words used across the docs. These are the ones this page relies on.
- Default project: the project every account starts with, and where a key goes when you do not choose one.
- Admin key: a key with the
adminpermission. It can manage projects and keys. - Move: putting an existing key into another project of the account.
- Archive: hiding a project without deleting what it holds.
Quick start
You need a Korely account: Quickstart
gets you one, free. Install with pip install korely-memory (Python 3.9 or later)
or npm install korely-memory (Node.js 18 or later). Checked
with SDK 0.1.28 (Python) and 0.1.17 (Node.js).
In the dashboard, create two projects, Staging and Production, on the
Projects page. On the API Keys page,
create one key in each: a new key goes to the project picked in the
switcher at the top left. Export them as KORELY_STAGING_KEY
and KORELY_PRODUCTION_KEY.
The code saves one memory with the staging key, then runs the same search with each key for one end user.
import osfrom korely_memory import Korely
staging = Korely(api_key=os.environ["KORELY_STAGING_KEY"])production = Korely(api_key=os.environ["KORELY_PRODUCTION_KEY"])
staging.add("Prefers email follow-ups.", user_id="test-user-1")
for name, korely in {"staging": staging, "production": production}.items(): hits = korely.search("email follow-ups", user_id="test-user-1") print(name, [hit.snippet for hit in hits])The staging search lists the memory. The production search does not: the staging memory is not visible to the production key.
If production lists it too, both keys are in the same project, most
often Default: the API Keys page lists each key under its project. If
staging lists nothing, check that both calls use the same
user_id (case counts).
What a project isolates
Every memory and fact carries the project of the key that wrote it. On
/v1, a key reads and changes memories and facts only in its
own project, except DELETE /v1/account: with
confirm=true it erases the whole account with any key that can
write, whatever its project (see
Delete the account).
Forgetting or correcting a fact of another project answers
404, as for an id that does not exist.
An admin key can also manage projects and keys outside the dashboard
and reach every project's data. On /v1 it stays in its own
project. Keep admin keys out of anything your agents run.
The wall holds only between different projects, and not for DELETE /v1/account. Watch three cases:
- Keys in Default. Two keys created without choosing a project both go to Default and share one memory. Pick the project when you create each key.
- Deleting a project. Unless you erase them, its memories and facts move into Default (see Delete a project).
- Webhooks. A webhook endpoint is an address of yours that Korely calls when something happens, such as a new memory with its
user_id. Unless you bind it to one project, it receives the calls of every project.
Erasing an end user
The wall applies to erasing too.
DELETE /v1/users/{end_user}/memories works in the
key's project only. If the same end user lives in several projects,
call it once per project, with that project's key.
The region of a project
Each project has a region, eu or global. Your data
is stored on Korely's servers in Helsinki in both. The region decides which
model reads the project's memories to write the facts: global
(the default) uses a model from Google, outside the EU; eu
uses Scaleway in Paris.
Data governance lists the model of each region and where it runs.
- The region belongs to the project, not to the key. A key moved to a project with another region has its next writes read there.
- You set it on the Projects page, at creation or later. Default and new projects start as
global, unless an agent created the account and chose a region. - A change applies to the next memories, including those still waiting for their facts. Facts already written stay as they are.
- To read a new memory, the model also gets that end user's earlier memories and facts as context. After a change, that context goes to the company that runs the new region's model.
Give staging and production the same region, or staging uses a different model than production.
Project, agent_id and end user
| Concept | What it is | Set where |
|---|---|---|
| Project | Keys and the wall around the data they write: one environment or product. | Dashboard |
agent_id | A name you choose for the app that writes. It does not belong to a key and counts toward your plan's agent limit. | Each call |
user_id | The end user your app serves. Unlimited on every plan. | Each call |
The memory of an end user is shared by every agent of the project.
Create and manage projects
A dashboard login creates projects and keys, and so does an admin key.
An account that an agent created with POST /v1/agents/init,
without the dashboard, has neither. It has only Default until you sign in
to the dashboard and paste the key on the Account page
(how to link the key to a dashboard login).
Move a key
On the API Keys page you can move a key to another project. From its next call it reads and writes there and no longer sees the old project; what it wrote before stays behind. Everything that still uses the key moves with it.
To promote staging, do not move its key: put a new Production key in the environment variable your production app reads.
Archive a project
Archiving is refused while the project holds a live key, one neither revoked nor expired. An archived project accepts no new keys. Default can be neither archived nor deleted.
Only an admin key undoes an archive (unarchive_project in
the Python SDK); the dashboard cannot.
Delete a project
- Its keys move to Default and keep working. A connected app, an app such as Claude or ChatGPT that you connected to Korely with OAuth (a sign-in standard), is disconnected and must connect again.
- By default its memories and facts move to Default.
- Its webhook endpoints are deleted.
- If you choose to erase, memories and facts are deleted for good. Each end user is erased as in Forget a user, and a confined key whose end users were all erased is revoked. Encrypted backups keep a copy for up to 35 days.
What the whole account shares
Staging and production share one pool of writes, one of reads, and the same per-minute, per-hour and per-day rate limits.
The agent limit counts agent_id names across the account: a
name used in two projects takes one place, and the free Hobby
plan holds 2 names.
GET /v1/agents lists only the key's project, while
used counts the account: a key can list 3 names while
used says 7, because 4 names are used only in other projects.
Quotas, plan rate limits and the agent limit belong to the Cloud; a Self-hosted install counts none of them.
Reference
| Case | Limit or answer |
|---|---|
| Projects per account | 100, Default and archived ones included. Deleting a project frees a place; archiving does not. |
| API keys per account | 100 not revoked, across all projects. An expired key counts until you revoke it; the key of a connected app does not. |
| Past either limit | 409 too_many_projects or too_many_keys. Nothing else changes. |
Sending a project field on /v1 (calls do not take one) | 422 invalid_request. Nothing is written. |
Other refusals, all 409 | project_archived (a key into an archived project), project_has_live_keys, cannot_archive_default, cannot_delete_default, connected_app_key (moving a connected app's key). |
Details
- A read without
user_idcovers every end user of the key's project.
See also
- The memory model: memories, facts and the
run_idlabel, and how a key reads only the project it belongs to. - The knowledge graph: how typed facts are extracted from every
add()call and how you read them back. - Forget a user: erase one end user.
- API reference: every
/v1call.