Memory (AgentMemory)
AgentMemory is an agent's long-term memory. It turns an agent's conversations into
short structured memories (a decision, a learning, a pattern, a preference or a fact),
lets the agent search and correct them, and writes the most useful ones into the
MEMORY.md file the agent reads at the start of every session.
These endpoints are the same six methods the @opvs-ai/agentmemory skill gives an
agent, plus the one that registers a conversation source. Base path:
/api/v1/memory.
Authentication: dashboard session or brand-scoped PAT (standard OPVS brand auth).
See Authentication. Reads need the memory:read
scope and writes need memory:write. Everything you read or write is scoped to the
brand your token is pinned to: another brand's memories are invisible to you, and a
memory id from another brand answers 404, the same as one that does not exist.
The search and recall methods answer YAML by default, which costs an agent far
fewer tokens. Pass format=json for JSON, or format=md for Markdown. See
Format negotiation.
How a memory reaches an agent¶
- From conversations. Every 10 minutes the service picks up conversations that have not been turned into memories yet. A conversation whose model call fails is retried with growing waits (10 minutes, 30 minutes, 2 hours, 8 hours) and is marked failed after the fifth attempt, so a failure is never recorded as "nothing to remember".
- From your own calls.
POST /memoriesstores a memory you write yourself. - Into the agent's workspace. Once an hour the highest-confidence active memories
are written into a marked section of the
MEMORY.mdin the workspace the agent actually reads. Only that section is replaced: the agent's own notes in the file are never overwritten. A correction you make withPATCHshows up in search and recall at once, and inMEMORY.mdat the next hourly export.
POST /api/v1/memory/agents/{agent_id}/context¶
Search an agent's active memories by text. The skill method is searchMemories.
Returns active memories with confidence 0.3 or higher, ranked by how well they match
query when you pass one. A memory not verified for more than 30 days carries
stale: true and a stale_caveat.
| Parameter | In | Type | Default | Notes |
|---|---|---|---|---|
agent_id |
path | string | none | The agent's workspace id, such as acme-sdr-001. |
query |
query | string | none | Words to match in the title and body. Omit it to list the agent's top memories. |
kinds |
query | string | all | Comma-separated: decision, learning, pattern, preference, fact, summary. |
limit |
query | integer | 10 |
1 to 50. |
format |
query | string | yaml |
json, yaml or md. |
curl -s -X POST "https://api.opvs.ai/api/v1/memory/agents/acme-sdr-001/context?query=pricing+page&kinds=decision,fact&limit=5&format=json" \
-H "Authorization: Bearer $OPVS_PAT"
# → 200 {"memories": […], "count": 1, "agent_id": "acme-sdr-001"}
# → 422 if limit is above 50
{
"memories": [
{
"kind": "decision",
"title": "Quote annual prices first on the pricing page",
"body": "Prospects compared our monthly price with competitors' annual price. Show annual first.",
"description": "Annual price first on the pricing page",
"confidence": 0.82,
"tags": ["pricing", "website"]
}
],
"count": 1,
"agent_id": "acme-sdr-001"
}
Errors
| Error | When | Resolution |
|---|---|---|
401 |
The PAT is malformed, expired or revoked. | Request a new token. |
403 |
The token lacks memory:read. |
Request a token with the scope. |
422 |
limit is outside 1 to 50. |
Send a value in range. |
502 / 504 |
The memory service is unreachable, or did not answer within 30 seconds. | Retry with backoff. |
POST /api/v1/memory/agents/{agent_id}/context/relevant¶
Recall the memories most relevant to a topic or question. The skill method is
recallRelevant. A text search first collects up to 100 candidates, then a language
model reranks them and keeps the best limit. If the reranker fails, you get the text
search order instead of an error.
| Parameter | In | Type | Default | Notes |
|---|---|---|---|---|
agent_id |
path | string | none | The agent's workspace id. |
query |
query | string | required | The topic, question or conversation context, in plain language. |
kinds |
query | string | all | Comma-separated kinds, as above. |
limit |
query | integer | 20 |
1 to 50. |
format |
query | string | yaml |
json, yaml or md. |
curl -s -X POST "https://api.opvs.ai/api/v1/memory/agents/acme-sdr-001/context/relevant?query=how+do+we+price+for+agencies&limit=3&format=json" \
-H "Authorization: Bearer $OPVS_PAT"
# → 200 {"memories": […], "count": 3, "agent_id": "acme-sdr-001"}
# → 422 if query is missing
The response has the same shape as the search above. No match is not an error: it
answers {"memories": [], "count": 0, "agent_id": "…"}.
Errors
| Error | When | Resolution |
|---|---|---|
401 |
The PAT is malformed, expired or revoked. | Request a new token. |
403 |
The token lacks memory:read. |
Request a token with the scope. |
422 |
query is missing, or limit is outside 1 to 50. |
Send a query and a limit in range. |
502 / 504 |
The memory service is unreachable, or did not answer within 30 seconds. | Retry with backoff. |
POST /api/v1/memory/memories¶
Store a memory you write yourself. The skill method is createMemory. It always
creates a new memory: sending the same memory twice stores it twice. To change one,
use PATCH.
| Field | Type | Required | Notes |
|---|---|---|---|
agent_id |
string | yes | The agent's workspace id: 1 to 255 letters, digits, _ or -. |
kind |
string | yes | decision, learning, pattern, preference or fact. |
title |
string | yes | Up to 500 characters. Keep it short: it is what search shows first. |
body |
string | yes | The memory itself. |
description |
string | no | A one-line summary, up to 200 characters, shown beside the title in recall. |
tags |
string[] | no | Tags for grouping. Three learnings sharing a tag are consolidated into a pattern. |
confidence |
number | no | 0.0 to 1.0, default 0.8. It decays about 2% a week. |
importance |
string | no | low, normal (default), high or critical. A critical memory does not decay. |
curl -s -X POST "https://api.opvs.ai/api/v1/memory/memories" \
-H "Authorization: Bearer $OPVS_PAT" \
-H "Content-Type: application/json" \
-d '{
"agent_id": "acme-sdr-001",
"kind": "decision",
"title": "Quote annual prices first on the pricing page",
"body": "Prospects compared our monthly price with competitors annual price. Show annual first.",
"description": "Annual price first on the pricing page",
"tags": ["pricing", "website"],
"importance": "high"
}'
# → 201 {"id": "9b2f6a0e-4c1d-4e8a-9d3b-2f7c1a5e8b40", "status": "active", …}
# → 403 if agent_id belongs to another brand
The response is the full memory, with its id. Keep the id to correct or delete it
later.
Errors
| Error | When | Resolution |
|---|---|---|
401 |
The PAT is malformed, expired or revoked. | Request a new token. |
403 |
The token lacks memory:write, or agent_id is an agent another brand owns. |
Name one of your own agents. The answer is the same whichever brand owns it. |
422 |
A required field is missing, confidence is outside 0 to 1, description is over 200 characters, or agent_id is not a plain workspace id (it has a ., /, a space or another character outside the set). |
Fix the field the error names. |
502 / 504 |
The memory service is unreachable, or did not answer within 30 seconds. | Retry with backoff. |
GET /api/v1/memory/memories/stats¶
Counts for your brand's memories. The skill method is getStats.
| Parameter | In | Type | Default | Notes |
|---|---|---|---|---|
agent_id |
query | string | all agents | Limit the counts to one agent. |
format |
query | string | json |
json, yaml or md. |
curl -s "https://api.opvs.ai/api/v1/memory/memories/stats?agent_id=acme-sdr-001" \
-H "Authorization: Bearer $OPVS_PAT"
# → 200 {"total_active": 31, "total_archived": 4, "total_merged": 2, "by_kind": {…}, "avg_confidence": 0.71}
# → 401 if the token is revoked
{
"total_active": 31,
"total_archived": 4,
"total_merged": 2,
"by_kind": { "decision": 6, "learning": 14, "fact": 11 },
"avg_confidence": 0.71
}
Errors
| Error | When | Resolution |
|---|---|---|
401 |
The PAT is malformed, expired or revoked. | Request a new token. |
403 |
The token lacks memory:read. |
Request a token with the scope. |
502 / 504 |
The memory service is unreachable, or did not answer within 30 seconds. | Retry with backoff. |
PATCH /api/v1/memory/memories/{memory_id}¶
Correct a memory in place. The skill method is updateMemory. Only the fields you send
change. Correcting beats writing a second memory that contradicts the first.
| Field | Type | Notes |
|---|---|---|
title |
string | Replacement title. |
body |
string | Replacement body. |
description |
string | Replacement one-line summary, up to 200 characters. Recall shows it beside the title, so when you correct the body, correct this too. |
kind |
string | Re-classify the memory. |
tags |
string[] | Replaces the whole tag list. |
confidence |
number | 0.0 to 1.0. |
importance |
string | low, normal, high or critical. |
status |
string | archived retires a memory from search and recall without deleting it; active restores it. |
curl -s -X PATCH "https://api.opvs.ai/api/v1/memory/memories/9b2f6a0e-4c1d-4e8a-9d3b-2f7c1a5e8b40" \
-H "Authorization: Bearer $OPVS_PAT" \
-H "Content-Type: application/json" \
-d '{
"body": "Agencies compare annual prices. Show annual first for every plan.",
"description": "Annual price first for every plan"
}'
# → 200 {"id": "9b2f6a0e-4c1d-4e8a-9d3b-2f7c1a5e8b40", "description": "Annual price first for every plan", …}
# → 404 if the memory is not in your brand
The response is the full memory after the change.
Errors
| Error | When | Resolution |
|---|---|---|
401 |
The PAT is malformed, expired or revoked. | Request a new token. |
403 |
The token lacks memory:write. |
Request a token with the scope. |
404 |
No memory with that id in your brand. "Not yours" and "not there" answer the same. | Check the id with a search. |
422 |
memory_id is not a UUID, confidence is outside 0 to 1, or description is over 200 characters. |
Fix the value the error names. |
502 / 504 |
The memory service is unreachable, or did not answer within 30 seconds. | Retry with backoff. |
DELETE /api/v1/memory/memories/{memory_id}¶
Delete a memory that is wrong. The skill method is deleteMemory. It stops appearing
in search and recall at once, and leaves MEMORY.md at the next hourly export. For a memory that is outdated rather than wrong,
PATCH it to status: archived instead.
curl -s -o /dev/null -w "%{http_code}\n" -X DELETE \
"https://api.opvs.ai/api/v1/memory/memories/9b2f6a0e-4c1d-4e8a-9d3b-2f7c1a5e8b40" \
-H "Authorization: Bearer $OPVS_PAT"
# → 204 (no body)
# → 404 if the memory is not in your brand, or was already deleted
Errors
| Error | When | Resolution |
|---|---|---|
401 |
The PAT is malformed, expired or revoked. | Request a new token. |
403 |
The token lacks memory:write. |
Request a token with the scope. |
404 |
No memory with that id in your brand, or it is already deleted. | Nothing to do if you deleted it before. |
422 |
memory_id is not a UUID. |
Send the memory's id. |
502 / 504 |
The memory service is unreachable, or did not answer within 30 seconds. | Retry with backoff. |
POST /api/v1/memory/sources¶
Register a conversation source for one of your agents, so the service turns that agent's conversations into memories. A source can only name an agent your brand owns.
| Field | Type | Required | Notes |
|---|---|---|---|
agent_id |
string | yes | Your agent's workspace id: 1 to 255 letters, digits, _ or -. |
source_type |
string | yes | openclaw (agent chat sessions), agentboard (completed tasks) or claude_code. |
config |
object | no | Source-specific settings. |
enabled |
boolean | no | Default true. |
curl -s -X POST "https://api.opvs.ai/api/v1/memory/sources" \
-H "Authorization: Bearer $OPVS_PAT" \
-H "Content-Type: application/json" \
-d '{"agent_id": "acme-sdr-001", "source_type": "openclaw"}'
# → 201 {"id": "3c5e9d12-7a4b-4f60-8e21-6b9d0c4f2a17", "agent_id": "acme-sdr-001", …}
# → 403 if the agent is not your brand's
Errors
| Error | When | Resolution |
|---|---|---|
401 |
The PAT is malformed, expired or revoked. | Request a new token. |
403 |
The token lacks memory:write; or agent_id is not an agent your brand owns (another brand's, or one of the platform's own agents); or your plan's source limit is reached (the body then says quota_exceeded). |
Name one of your own agents, or upgrade the plan. The ownership answer is the same for every agent that is not yours, so it does not reveal whether that agent exists. |
422 |
agent_id is not a plain workspace id, or a required field is missing. |
Fix the field the error names. |
503 |
Ownership could not be checked just now. Nothing was created. | Retry shortly. |
502 / 504 |
The memory service is unreachable, or did not answer within 30 seconds. | Retry with backoff. |