curl -X POST "http://localhost:8000/api/v2/agents/my-agent/policy/apply" \
-H "X-Session-Token: your_session_token" \
-H "Content-Type: application/json" \
-d '{"dry_run": true}'
curl -X POST "http://localhost:8000/api/v2/agents/my-agent/policy/apply" \
-H "X-Session-Token: your_session_token" \
-H "Content-Type: application/json" \
-d '{"dry_run": false}'
{
"agent_id": "my-agent",
"dry_run": false,
"policy_is_empty": false,
"scanned": 5,
"already_expired": 3,
"matched": 1,
"expired": 1,
"per_rule": { "retention.context": 1 },
"memories": [
{
"id": "ec83b90a-a0a1-4c9a-9b4e-a8794b060612",
"title": "Current sprint is the billing rewrite",
"type": "context",
"created_at": "2026-08-18T19:44:00+00:00",
"updated_at": "2026-08-18T19:44:00+00:00",
"expired_by": "retention.context"
}
],
"errors": [],
"evaluated_at": "2026-08-18T19:56:29.873259+00:00"
}
{
"agent_id": "my-agent",
"dry_run": true,
"policy_is_empty": true,
"scanned": 4,
"already_expired": 0,
"matched": 0,
"expired": 0,
"per_rule": {},
"memories": [],
"errors": [],
"evaluated_at": "2026-08-18T19:56:29.873259+00:00"
}
{
"detail": "Missing session token. Use X-Session-Token header."
}
Expiry Policy
Apply Expiry Policy
Sweep the agent’s memories and expire everything the policy matches.
POST
/
api
/
v2
/
agents
/
{agent_id}
/
policy
/
apply
curl -X POST "http://localhost:8000/api/v2/agents/my-agent/policy/apply" \
-H "X-Session-Token: your_session_token" \
-H "Content-Type: application/json" \
-d '{"dry_run": true}'
curl -X POST "http://localhost:8000/api/v2/agents/my-agent/policy/apply" \
-H "X-Session-Token: your_session_token" \
-H "Content-Type: application/json" \
-d '{"dry_run": false}'
{
"agent_id": "my-agent",
"dry_run": false,
"policy_is_empty": false,
"scanned": 5,
"already_expired": 3,
"matched": 1,
"expired": 1,
"per_rule": { "retention.context": 1 },
"memories": [
{
"id": "ec83b90a-a0a1-4c9a-9b4e-a8794b060612",
"title": "Current sprint is the billing rewrite",
"type": "context",
"created_at": "2026-08-18T19:44:00+00:00",
"updated_at": "2026-08-18T19:44:00+00:00",
"expired_by": "retention.context"
}
],
"errors": [],
"evaluated_at": "2026-08-18T19:56:29.873259+00:00"
}
{
"agent_id": "my-agent",
"dry_run": true,
"policy_is_empty": true,
"scanned": 4,
"already_expired": 0,
"matched": 0,
"expired": 0,
"per_rule": {},
"memories": [],
"errors": [],
"evaluated_at": "2026-08-18T19:56:29.873259+00:00"
}
{
"detail": "Missing session token. Use X-Session-Token header."
}
Overview
Runs the expiry sweep. This is what moves memories fromactive to expired —
saving a policy on its own changes nothing.
Pass dry_run: true to get the identical report with nothing written, which
is how you preview a policy before committing to it.
Authentication
API clients do not send an API key orAuthorization header.
string
required
Session token from Activate Agent. Must match
agent_id.string
required
Must be
application/jsonPath Parameters
string
required
The unique identifier of the agent.
Body
boolean
default:"false"
When
true, report exactly what would be expired without writing anything.
The body may be omitted entirely to accept the default.Response Fields
integer
Active memories evaluated. A sweep never considers already-expired memories.
integer
Expired memories not rescanned. Reported so a
matched: 0 result can be told
apart from an empty namespace — these are governed by
purging, not by the retention table.integer
Memories the policy matched.
integer
Memories actually stamped. Always
0 on a dry run.object
Match counts keyed by the rule that fired (
retention.<type> for table entries).boolean
true when no policy is set, in which case the sweep is a no-op.curl -X POST "http://localhost:8000/api/v2/agents/my-agent/policy/apply" \
-H "X-Session-Token: your_session_token" \
-H "Content-Type: application/json" \
-d '{"dry_run": true}'
curl -X POST "http://localhost:8000/api/v2/agents/my-agent/policy/apply" \
-H "X-Session-Token: your_session_token" \
-H "Content-Type: application/json" \
-d '{"dry_run": false}'
{
"agent_id": "my-agent",
"dry_run": false,
"policy_is_empty": false,
"scanned": 5,
"already_expired": 3,
"matched": 1,
"expired": 1,
"per_rule": { "retention.context": 1 },
"memories": [
{
"id": "ec83b90a-a0a1-4c9a-9b4e-a8794b060612",
"title": "Current sprint is the billing rewrite",
"type": "context",
"created_at": "2026-08-18T19:44:00+00:00",
"updated_at": "2026-08-18T19:44:00+00:00",
"expired_by": "retention.context"
}
],
"errors": [],
"evaluated_at": "2026-08-18T19:56:29.873259+00:00"
}
{
"agent_id": "my-agent",
"dry_run": true,
"policy_is_empty": true,
"scanned": 4,
"already_expired": 0,
"matched": 0,
"expired": 0,
"per_rule": {},
"memories": [],
"errors": [],
"evaluated_at": "2026-08-18T19:56:29.873259+00:00"
}
{
"detail": "Missing session token. Use X-Session-Token header."
}
Notes
- Every memory in one sweep is stamped with the same
expired_at(evaluated_at), so a batch is consistent. - Memory age is measured from
updated_at, falling back tocreated_at— editing a memory resets its clock. - A memory with no usable timestamp is never expired.
- Per-memory failures are collected in
errorsrather than aborting the sweep. - The nightly schedule job calls this endpoint’s logic automatically.
Next Steps
- Purge Expired Memories for the destructive step
- Restore Memory to undo one expiry