Users & agents
Audit log
What happened in your project, and what your agents read: one event per call that ran, newest first.
/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
| Parameter | Type | Required | Description |
|---|---|---|---|
user_id | string | Optional | Only the events that touched this end user. |
action | string | Optional | Only 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. |
since | string | Optional | ISO 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. |
until | string | Optional | ISO 8601 date or datetime, inclusive: events at or before this moment. |
limit | integer | Optional | 1 to 1000. Default 100. |
offset | integer | Optional | Default 0. Page with limit and offset; total counts every match. |
Example request
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}| Field | Type | Description |
|---|---|---|
events[].ts | string | ISO 8601 time of the event. |
events[].actor | string | Who acted: rest (the API), mcp (the agent MCP server), dashboard (you, in the dashboard) or worker (Korely's background worker). |
events[].action | string | read, 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[].result | string | ok; 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_id | string · null | The end user the event touched. |
events[].target_id | string · null | What 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[].meta | object · null | Counts 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[].ip | string · null | The address the call came from. null for events of the MCP server and of the dashboard. |
events[].read | object · null | For a read: the ids it returned, memories and facts, at most 100 of each (the full counts are in meta). |
total | integer | Every event that matches the filters. |
Errors
| Status | Code | Cause |
|---|---|---|
401 | invalid_key | Missing or invalid kor_live_ key. |
403 | forbidden | The key lacks the memories:read scope. |
422 | invalid_request | since 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. |
429 | rate_limit_exceeded | Per-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.