---
title: "Add Memory"
method: POST
path: "/v1/memories"
tags: ["v1"]
---

# Add Memory

`POST /v1/memories`

## Request

- Base URL: `https://api.korely.ai`
- URL: `https://api.korely.ai/v1/memories`
- Auth: HTTP bearer

Store a memory for an end user (`user_id`), an agent (`agent_id`) or a
run (`run_id`).

The call returns once the memory is stored. Its typed facts are extracted
by a model after that, so the reply says `status: processing` with
`facts: []`; a server run with `WRITE_ASYNC=false` extracts before
answering and returns the facts inline. Poll `GET /v1/events` or read the
memory again to see them.

`timestamp` is when the events happened, not when you send them: the
facts take it as `valid_from`, so reads with `as_of` answer about the
right date. An unreadable one is a 422, never a silent "now".

## Headers

- `X-Korely-Client` string, nullable: The tool writing, e.g. claude-code: kept on the memory as `client`. Not a namespace and not counted in the agent cap.

## Request body

- AddBody
  - `content` string, required
  - `user_id` string, nullable: The end user this memory belongs to. 1 to 255 characters, no '/', no control characters, and not '.' or '..': the id names a namespace that DELETE /v1/users/<user_id>/memories and DELETE /v1/agents/<agent_id> address as one URL path segment.
  - `agent_id` string, nullable: Agent namespace. 1 to 255 characters, no '/', no control characters, and not '.' or '..': the id names a namespace that DELETE /v1/users/<user_id>/memories and DELETE /v1/agents/<agent_id> address as one URL path segment.
  - `run_id` string, nullable
  - `metadata` object, nullable
  - `kind` 'note' | 'session': What the text is: `note` (the default), what somebody said or decided; `session`, the log of a work session (what a coding assistant's hooks save). A read may leave the sessions out, their facts with them (`exclude_sessions`).
  - `timestamp` string, nullable: ISO date/datetime the memory's events occurred (defaults to now). Facts extracted inherit it as valid_from, so `as_of` point-in-time queries reflect when things were true, not when they were ingested.

## Response `201`

Successful Response

- MemoryWithFacts
  - `id` string, required
  - `content` string, required
  - `user_id` string, nullable, required
  - `agent_id` string, nullable, required
  - `run_id` string, nullable, required
  - `client` string, nullable: The tool that wrote it: the X-Korely-Client header of the write, or the name an MCP client gave when it connected. A label, not a namespace: no read is scoped by it and the agent cap does not count it.
  - `kind` string: `note`, or `session` for the log of a work session (`kind` of the write).
  - `metadata` object, required
  - `status` string: Whether this memory's typed facts are queryable yet: 'processing', 'ready', or 'error'. Extraction runs after the write returns, so a read taken immediately can legitimately find no facts. Poll GET /v1/events or read the memory again: no webhook says that extraction finished (`memory.created` is sent when the memory is stored, before its facts).
  - `created_at` string, nullable, required
  - `updated_at` string, nullable, required
  - `facts` object[]

## Other responses

- `401`: `invalid_key`: the `Authorization: Bearer` key is missing, unknown, revoked or expired.
- `403`: `forbidden`: the key lacks the scope this operation needs; `message` names it.
- `413`: `payload_too_large`: the body is larger than 2,097,152 bytes, the most this route takes. Refused before it is read; nothing was done.
- `422`: `invalid_request`: the body, a query parameter or a path parameter is malformed (`detail` is the list of fields that failed, `message` names the first), or the endpoint refuses a value (an empty content, an unreadable timestamp; `detail` is a sentence or `{code, message}`).
- `429`: `rate_limit_exceeded`: past the request ceiling, the per-minute one set on this install (`RATE_LIMIT_PER_MINUTE`) or, on the hosted service, the plan's minute, hour or day; `message` names the window and `Retry-After` the seconds until it resets. On this service also `quota_exceeded`: the plan's writes of the month are spent (`limit`, `used`, `resets_at`, and no `Retry-After`: a retry fails until `resets_at`, a top-up or a bigger plan). And `agent_cap_exceeded`: a new `agent_id` past the plan's named agents (`limit`, `used`).
- `500`: `internal_error`: the server failed on this request; `message` holds no detail of it.
- `503`: A dependency did not answer: the database while the key was checked (`unavailable`, see `Retry-After`), or the one `code` names. Nothing was written; retry.

---

[API](https://skmtc.dev/korely/apis/korely-agents-api.md) · [All operations](https://skmtc.dev/korely/apis/korely-agents-api/llms.txt) · [OpenAPI document](https://skmtc.dev/korely/apis/korely-agents-api/revisions/8a40bf09eca1?raw)
