API Reference
Overview
Call Korely over HTTP: one key in a header, JSON in and out. This page lists the routes and what they share.
Base URL: https://api.korely.ai. Memories and facts are
stored on Korely's servers in Helsinki. The project's region
decides which model reads their text to write the facts: global
(the default) uses a model from Google, outside the EU; eu uses
Scaleway in Paris
(see Data governance).
Quick start
You need an API key:
Quickstart: get a free API key shows how.
Replace kor_live_... with yours. The call changes none of your data.
curl https://api.korely.ai/v1/ping \ -H "Authorization: Bearer kor_live_..."A working key answers 200:
{ "ok": true, "tier": "hobby", "region": "eu-hel1", "processing_region": "global", "scopes": ["memories:read", "memories:write"]} tier is the name of your plan: hobby, developer, team or scale.
scopes is the list of the key's permissions (the API calls them scopes).
No 200? A 401 means the key is missing or wrong:
copy it again. Any other status is listed in Errors.
Terms
The Glossary defines the words used across the docs. These are the ones this page relies on: Cloud and Self-hosted, SDK, confined key, end user, agent_id, run_id, write, read, rate limit and webhook. This page adds these:
- Route: one HTTP method and path, such as
GET /v1/ping. regionandprocessing_region: in the ping answer,regionnames the server that answered (eu-hel1, in Helsinki).processing_regionis the region of the key's project,euorglobal, which decides the model provider that receives your text: Scaleway in Paris foreu, Google (outside the EU) forglobal.- Batch: one
POST /v1/batchcall with up to 500 memories. Korely queues it, answers202, and stores the memories in the background. - Event: a write's processing state (
processing,readyorerror), as List events returns it. expected_updated_at: an optional field of a memoryPATCH: theupdated_atyou last read. If the memory changed since, the edit is refused.degraded: true: aGET /v1/contextanswer with a part missing, such as the memories.degraded_partsnames the part.
Reference
Address and keys
All customer routes are under /v1. The dashboard, the web app for your account, has its own
administration API (/admin/*), not part of this API.
Every /v1 request carries Authorization: Bearer kor_live_...,
except POST /v1/agents/init, which creates an account and its first
key (see Sign up as an agent). Create more keys
in the dashboard.
Keep the key on your server. A full key (memories:read and
memories:write) reads and writes all memory in its project; a
read-only key (memories:read) reads it all. A
confined key reaches only its end users.
Routes
The route pages below are still to be reviewed. Until then, check details against the Core operations guides, which are more recent: Add, Search, Get context, Update, Delete and Forget a user.
| Page | Route |
|---|---|
| Core memory operations | |
| Add a memory | POST /v1/memories |
| Search memories | POST /v1/memories/search |
| List memories | GET /v1/memories |
| Get a memory | GET /v1/memories/{memory_id} |
| Update a memory | PATCH /v1/memories/{memory_id} |
| Delete a memory | DELETE /v1/memories/{memory_id} |
| Memory history | GET /v1/memories/{memory_id}/history |
| Context & facts | |
| Get context | GET /v1/context |
| Get facts | GET /v1/facts |
| Write a fact | POST /v1/facts |
| Close a fact | POST /v1/facts/{fact_id}/forget |
| Correct a fact | PATCH /v1/facts/{fact_id} |
| Get profile | GET /v1/profile |
| Users & agents | |
| List users | GET /v1/users |
| Forget a user | DELETE /v1/users/{end_user}/memories |
| Declare a name | POST /v1/users/{end_user}/names |
| List agents | GET /v1/agents |
| Delete an agent | DELETE /v1/agents/{agent_id} |
| Audit log | GET /v1/audit |
| Delete the account | DELETE /v1/account |
| Sign up as an agent | POST /v1/agents/init |
| Batch & status | |
| Batch import | POST /v1/batch |
| Batch status | GET /v1/batch/{job_id} |
| List events | GET /v1/events |
| Ping | GET /v1/ping |
The interactive playground shows each route's request and response. It reads the OpenAPI file published on this site, which can lag behind the latest release.
Scoping
Three optional strings that you choose scope a memory. Filters combine with AND.
| Field | Identifies | Example |
|---|---|---|
user_id | An end user. Unlimited on every plan. | "customer-4812" |
agent_id | One of your apps or agents. Each name counts toward your plan's agents. | "support-bot" |
run_id | One session or conversation. | "chat-2026-06-17-a" |
On writes, user_id and agent_id:
- take 1 to 255 characters;
- contain no
/and no control characters; - are not
.or..; - do not start with
erased:, which Korely uses to mark erased end users.
run_id takes 1 to 255 characters. In paths, {end_user} is the user_id.
Errors
An error returns its HTTP status and a JSON body with three fields.
Branch on code. message is a sentence for people; its
wording may change. detail holds the same sentence, except on a
422, where it lists the fields that failed.
{ "detail": "Memory not found", "code": "not_found", "message": "Memory not found"}| Status | Code | When |
|---|---|---|
400 | bad_request | The body is not JSON in UTF-8. |
401 | invalid_key | The header is missing or malformed, or no live key matches it. |
403 | forbidden | The key lacks a permission the route needs, or is confined and the request leaves its end users. |
404 | not_found | No such resource or path. A resource of another project also answers 404. |
408 | request_timeout | The body did not arrive within 30 seconds. See Details. |
409 | stale_write | A PATCH with an expected_updated_at older than the memory: another write landed first. Read it again. |
409 | fact_not_current | PATCH /v1/facts/{fact_id} on a fact no longer current. current_fact_id, at the top of the body, names the current one, or is null. |
409 | conflict | POST /v1/users/{end_user}/names with a name declared for somebody else. |
413 | payload_too_large | The body is too large. See Details. |
422 | invalid_request | A missing, malformed or unknown field, malformed JSON, or a NUL byte in a text. message names the first field. |
429 | quota_exceeded | The month's writes or reads are used up. detail carries limit, used and resets_at (00:00 UTC on the 1st). |
429 | agent_cap_exceeded | A new agent_id would pass your plan's number of agents. detail carries limit and used. |
429 | rate_limit_exceeded | Too many requests in the current minute, hour or day. |
500 | internal_error | Our failure. Retry; tell us if it persists. |
503 | unavailable | The server could not finish in time: another request had locked the data, the database did not answer, or the server was busy. |
503 | search_unavailable | A search could not embed its question, or waited 20 seconds for its turn. Not an empty result. GET /v1/context answers degraded: true instead. |
503 | model_unavailable | A model that a fact write needs gave no usable answer. |
503 | service_paused | Cloud only. POST /v1/facts or PATCH /v1/facts/{fact_id} while the daily safety stop is on: it pauses all calls to the models once the day's model budget is used up. Retry after an hour. |
The Retry-After header:
- is sent with
rate_limit_exceeded,unavailable(5 seconds),search_unavailable(5 seconds) andservice_paused(3600 seconds); - is not sent with
quota_exceeded,agent_cap_exceededormodel_unavailable.
Rate limits and quotas
The rate limit caps requests per minute, hour and day for your
whole account: all keys, REST and MCP share it. Past it you get
429 rate_limit_exceeded; Retry-After says when that window
resets. A request the limit refuses is not counted. Every other call counts,
GET /v1/ping included.
The monthly quota caps writes and reads, by plan. You can go 10%
over the monthly figure; past that, 429 quota_exceeded: wait for resets_at.
A quota.warning webhook
fires when the month's writes cross 80%.
An add or a PATCH of a memory counts one write per
6,000 characters of text. POST /v1/facts,
a PATCH of a fact and declaring a name count one each. A batch counts
whole when Korely queues it. If it does not fit in the writes left this month, it is refused.
Hobby allows 60 requests per minute, 1,000 per hour and 10,000 per day; Pricing has every plan.
No response has X-RateLimit-* headers or says how many calls are left.
Versioning
Korely is versioned by release number: the changelog shows the current release and what each one changes.
From 1.0, nothing published is removed without a 2.0: an endpoint, a field or an error code of a 1.x release stays in every 1.x release.
Details
- No idempotency. A retried write can store the memory twice and count two writes. An
Idempotency-Keyheader is ignored. - Pages of results. Lists of memories, facts, users and agents take
limit(default 50, at most 200) andoffset, and answertotal. - Slow bodies. A body has 30 seconds to arrive, or 120 for a batch over 2 MiB. Later,
408 request_timeout. - Size limits. On the Cloud, a body over 1 MB (80 MB for a batch) gets a
413with no JSON body, so check the status, not the body. Self-hosted and smaller bodies meet the API's own limit:413 payload_too_largeover 2,097,152 bytes (78,245,152 for a batch), or when the body holds too many separate text values. - Waits. A request waits up to 5 seconds for locked data before
503 unavailable; forgetting a user or deleting an agent waits up to 60. - Self-hosted. Quotas, the agent cap,
quota.warning, sign-up limits,service_paused,POST /v1/agents/initandDELETE /v1/accountexist only on the Cloud. The rate limit is off by default.