Korely

Users & agents

Audit log

What happened in your project, and what your agents read: one event per call that ran, newest first.

GET /v1/audit

"Who wrote this memory, and what did the agent know when it decided?" Filter by user_id to get the events attributed to one end user: writes, edits, fact writes, corrections and forgets, end-user erasures, reads of one memory, and every read made with that user_id, with the memories and facts it returned. A read made without a user_id and a batch import carry user_id null: find them by target_id or in read. A read lists ids. To know what a fact said at that moment, read it with as_of set to the time of the event.

The log records ids, counts and short labels, never the text of a memory, a fact or a query. Erasing an end user or an agent namespace therefore removes its content for good, and the log still shows that it happened. Forgetting a single memory is recorded as erase too, but keeps the memory and its facts as history. Events are kept for 400 days.

Authentication

HTTP header, required: Authorization: Bearer kor_live_.... The key needs the memories:read scope. Reading the log does not count against your query quota, and the read is not itself written to the log.

A key sees only the events of its own account and its own project. A key without a project sees the events that have no project.

Query parameters

ParameterTypeRequiredDescription
user_idstringOptionalOnly the events that touched this end user.
actionstringOptionalOnly the events with this action: read, write, fact_write, fact_invalidate, erase, key_create, key_revoke, key_change or setting_change. An open string, max 32 chars: an unknown action returns an empty page, not an error.
sincestringOptionalISO 8601 date or datetime, inclusive: events at or after this moment (2026-10-01 or 2026-10-01T00:00:00Z). Give the offset as Z, or encode + as %2B.
untilstringOptionalISO 8601 date or datetime, inclusive: events at or before this moment.
limitintegerOptional1 to 1000. Default 100.
offsetintegerOptionalDefault 0. Page with limit and offset; total counts every match.

Example request

Terminal window
curl "https://api.korely.ai/v1/audit?user_id=customer-4812&limit=50" \
-H "Authorization: Bearer kor_live_..."

Response

200 OK. The events, newest first, and how many match. The order is ts descending, then the event's internal id descending, so two events in the same instant keep one order and paging with offset is stable: a page neither repeats nor skips an event that was already there.

{
"events": [
{
"ts": "2026-10-02T09:14:31.218Z",
"actor": "rest",
"action": "read",
"result": "ok",
"user_id": "customer-4812",
"target_id": null,
"meta": {"endpoint": "context", "tokens": 412, "degraded": false, "memories_read": 3, "facts_read": 2},
"ip": "203.0.113.9",
"read": {"memories": ["mem_8f2c1a", "mem_41d0e7", "mem_c9a0b2"], "facts": ["fct_a1", "fct_b7"]}
},
{
"ts": "2026-10-02T09:12:05.004Z",
"actor": "rest",
"action": "write",
"result": "ok",
"user_id": "customer-4812",
"target_id": "mem_c9a0b2",
"meta": {"endpoint": "memories:add", "facts": 0},
"ip": "203.0.113.9",
"read": null
}
],
"total": 2
}
FieldTypeDescription
events[].tsstringISO 8601 time of the event.
events[].actorstringWho acted: rest (the API), mcp (the agent MCP server), dashboard (you, in the dashboard) or worker (Korely's background worker).
events[].actionstringread, write (a memory added, updated or batch-imported), fact_write (a fact written or corrected), fact_invalidate (a fact closed by Korely, not by a call), erase (a memory, an end user, an agent namespace or a fact forgotten, or a project deleted with its data), key_create, key_revoke, key_change (a key moved to another project), setting_change (a setting changed in the dashboard: meta.setting says which, meta.op how). Read the field as an open string: new actions can appear.
events[].resultstringok; denied when a write was refused before it wrote anything: a memory write or edit, a batch import, a fact write or correction (meta.reason says why: quota_exceeded or agent_cap_exceeded, your plan; writes_paused, the service's daily model budget; stale_write, a memory edit whose expected_updated_at is not the memory's version); error when the memory or fact the call names is not in the key's project (GET, PATCH or DELETE /v1/memories/{memory_id}, its history, a fact forget or correction), or when a model a fact write needs gave no usable answer (meta.reason model_unavailable, nothing written). Requests refused before they ran are not recorded: a bad key or scope, a malformed request, the rate limit, the monthly query quota.
events[].user_idstring · nullThe end user the event touched.
events[].target_idstring · nullWhat was acted on: a memory (mem_), a fact (fct_), a batch job (job_), an agent namespace (agent:<agent_id>), a key, a project, a webhook or an alias (its id). null for an end-user erasure and for list and search reads.
events[].metaobject · nullCounts and labels: the endpoint, how many facts a write returned inline (0 when extraction runs after the write; see List events), how many memories and facts a read returned. For setting_change: setting is region, project, webhook or alias, and op is set, create, rename, archive, delete or enable (a webhook switched back on); a region change also has from and to, for example {"setting": "region", "op": "set", "from": "global", "to": "eu"}. For key_change: op is move, with the projects in from and to. Never a webhook address or an alias name.
events[].ipstring · nullThe address the call came from. null for events of the MCP server and of the dashboard.
events[].readobject · nullFor a read: the ids it returned, memories and facts, at most 100 of each (the full counts are in meta).
totalintegerEvery event that matches the filters.

Errors

StatusCodeCause
401invalid_keyMissing or invalid kor_live_ key.
403forbiddenThe key lacks the memories:read scope.
422invalid_requestsince or until cannot be read as a date or datetime, limit is outside 1..1000, offset is below 0, user_id is longer than 255 chars, or action longer than 32.
429rate_limit_exceededPer-key rate limit exceeded. Honor the Retry-After header and back off. The log never answers quota_exceeded: it does not count against the query quota.

Self-hosted too. Korely Agents self-hosted answers GET /v1/audit with the same parameters.