Korely

API Reference

Overview

One bearer header, JSON in and out, EU-hosted. The Python and Node SDKs cover these endpoints, the same call, three ways in.

Base URL: https://api.korely.ai. Every endpoint is under /v1. Requests and responses are JSON; data is stored in the EU. Prefer not to call HTTP directly? The Python and Node SDKs cover these endpoints (erasing a single memory with erase=true is REST only), and there's an interactive playground generated from the live spec.

Authentication

Every request carries an Authorization header with your secret key: Authorization: Bearer kor_live_.... The one exception is POST /v1/agents/init, which mints your first key. Keys are issued when you sign up as an agent. Keep the key server-side: a full key reads and writes all memory in its project, and a read-only one reads it all.

Terminal window
curl https://api.korely.ai/v1/ping \
-H "Authorization: Bearer kor_live_..."

Scoping

Three optional strings scope every memory. You choose the values, within the id rule (user_id and agent_id: 1 to 255 characters, no /, no control characters, not . or .., not starting with erased:; run_id: 1 to 255 characters); filters are additive (AND).

FieldIdentifiesExample
user_idYour end user. Unlimited on every tier."customer-giulia-4812"
agent_idYour application's namespace."support-bot"
run_idOne session or conversation."chat-2026-06-17-a"

Versioning

Korely is versioned by release number, today 0.2.1. Every release and what it changes is in the changelog.

Korely follows one rule from version 1.0: nothing published is removed without a 2.0: an endpoint, a field or an error code published in a 1.x release stays in every 1.x release.

Errors

Errors return the matching HTTP status and a JSON body with a stable code, a human message and detail (a sentence, an object with code and message, or on a validation 422 the list of fields that failed). A quota 429 carries limit, used and resets_at inside detail; a 409 fact_not_current also has current_fact_id at the top. Branch on code: the wording of message may change.

{
"detail": "Invalid or missing API key: no live key matches it (a revoked key stops at once); your keys are at https://agent.korely.ai/keys",
"code": "invalid_key",
"message": "Invalid or missing API key: no live key matches it (a revoked key stops at once); your keys are at https://agent.korely.ai/keys"
}
StatusCodeWhen
400confirmation_requiredDELETE /v1/account without confirm=true. Nothing is deleted.
401invalid_keyThe Authorization header is missing, malformed, or the key is revoked. The message starts with Invalid or missing API key: and says which: no Authorization: Bearer header, a string that is not a key, or a key that matches no live key (unknown and revoked answer the same). On Self-hosted, kor_live_ is the Cloud's prefix, so the install refuses every kor_live_ key, on REST, MCP and the admin API, and its message says that keys minted there begin with kor_self_.
403forbiddenThe key lacks the scope the endpoint requires (e.g. memories:write), or it is confined to some end users and the request names one outside its list.
403signup_disabledPOST /v1/agents/init while self-signup is closed.
404not_foundNo such resource in this workspace (also returned instead of 403, so membership isn't leaked).
405method_not_allowedThe HTTP method is not supported for this path.
408request_timeoutPOST /v1/batch only: a body larger than 2 MiB did not arrive whole within 120 seconds. Nothing was done; send it again, or in smaller batches.
409stale_writeexpected_updated_at on PATCH /v1/memories/{memory_id} doesn't match the current record, another write landed first.
409fact_not_currentPATCH /v1/facts/{fact_id} on a fact that is history (superseded, forgotten or ended). The body adds current_fact_id, the current fact to correct instead, or null when there is none. Nothing is written or counted.
409account_has_loginDELETE /v1/account on an account you sign in to: close it from the dashboard (Account, Close the account) instead.
409conflictPOST /v1/users/{end_user}/names with a name already declared for somebody else in that memory. Nothing changes.
413payload_too_largeThe request body is larger than the route takes: 2,097,152 bytes, or 78,245,152 for POST /v1/batch. Refused before the body is read, the key included; nothing was done. On the Cloud a body over 1 MB (80 MB for POST /v1/batch) is refused earlier with a bare 413, without this code.
422invalid_requestRequest validation failed: a missing field, a malformed value, a text with a NUL byte (on MCP the tool answers with an error: line instead), or a field the endpoint does not know. Request bodies refuse unknown fields (names are snake_case), except POST /v1/agents/init, which ignores them. message names the first offending field.
429quota_exceededMonthly write or query quota used up, 10% grace included. detail carries limit (the plan's figure, top-ups included), used and resets_at (00:00 UTC on the 1st). Carries no Retry-After: read resets_at. A batch refused for the quota carries the same three fields.
429agent_cap_exceededA new agent_id would take the account past its plan's named agents (names in queued batches count). Nothing is written. detail carries limit and used.
429rate_limit_exceededToo many requests in the current minute, hour or day. This one does carry Retry-After.
429signup_rate_limitedToo many new accounts from your network, or from everyone, in 24 hours. Carries Retry-After.
500internal_errorThe request failed on our side. Retry; if it keeps failing, tell us.
503unavailableThe request waited more than 5 seconds for another one working on the same data. Nothing is applied; it carries Retry-After: 5. An erasure waits up to 60 seconds before giving this answer.
503search_unavailableThe query could not be embedded: the embedding model did not answer, or your account already has four requests at the embedder (searches, context calls and the vectors of writes, running or waiting), or this one waited 20 seconds for its turn. Not an empty result; retry shortly. Other read paths are unaffected.
503model_unavailableA model a fact write needs gave no usable answer, or the service's daily model budget is spent (until 00:00 UTC, no Retry-After). Nothing is written; retry. POST and PATCH /v1/memories keep storing memories, and their facts are extracted after the pause.

Rate limits & quotas

Two limits, two meanings. A short-term rate limit (requests per minute, hour and day) returns 429 rate_limit_exceeded with a Retry-After header, back off and retry. A request the rate limit refuses does not count against it, and what you do signed in to the dashboard has a limit of its own, with the same ceilings, so it does not eat into your keys'. A monthly quota (memories written and queries per month, by tier) returns 429 quota_exceeded with no Retry-After and a detail that says limit, used and resets_at: a quota.warning webhook fires when the month's writes cross 80%, and past a +10% soft cap you get a clean error rather than a surprise invoice. An edit (PATCH of a memory or a fact) extracts again and counts like a write: a memory one write per 6,000 characters of its text, as an add, a fact one write. A batch whose memories do not fit in the writes left this month, the batches already queued included, is refused before anything is stored. Reads are far more generous than writes, because reads are retrieval, not generation. See pricing for the per-tier numbers: monthly quotas and requests per minute, hour and day (Hobby: 60 per minute, 1,000 per hour, 10,000 per day). A 429 rate_limit_exceeded carries Retry-After (seconds until the window that refused resets) and a message naming that window's limit. No other response carries rate-limit headers. GET /v1/ping counts against the rate limit like every other call. POST /v1/agents/init takes no key and has its own limit on new accounts per network and per day (429 signup_rate_limited).

The endpoints

Grouped in the sidebar: Core memory operations (add, search, list, get, update, delete, history), Context & facts (the typed bi-temporal layer: get context, get, write, close and correct facts, get profile), Users & agents (list and forget users, declare a user's name, list and delete agents, the audit log, delete the account), and Batch & status (batch import and status, write events, ping). Signing up (POST /v1/agents/init) is on Sign up as an agent. Start with Add a memory.