Brainby arc-labs/docs
Sdk pythonrecall.agents
Python SDK

recall.agents

Manage agents — named personas that own memories within a namespace. SyncAgents and AsyncAgents with identical method surfaces.

All methods below exist on both SyncAgents (via Recall) and AsyncAgents (via AsyncRecall) with identical signatures. The only difference is await on the async path. Each example shows both variants in tabs.

list()

GET/v1/agentsAPI key (admin)stable
def list(
    self,
    *,
    limit: int = 20,
    cursor: Optional[str] = None,
) -> dict: ...

Return a paginated list of agents visible to the caller's org. Use cursor for stable pagination on orgs with high agent churn.

Parameters

ParameterTypeRequired
limitintoptional

Number of agents per page. Server clamps to [1, 100].

cursorstroptional

Opaque cursor from the previous page's meta.nextCursor. Omit on the first request.

Returns

{
    "items": [
        {
            "id": "ag_01HEX…",
            "name": "customer-support-v2",
            "namespaceId": "ns_01HEX…",
            "createdAt": "2026-05-01T10:00:00Z",
            "updatedAt": "2026-05-09T14:22:00Z",
        },
        # …
    ],
    "meta": {
        "count": 3,
        "limit": 20,
        "nextCursor": None,   # non-null when another page exists
    },
}

Examples

# Paginate all agents
cursor = None
all_agents = []

while True:
    page = recall.agents.list(limit=50, cursor=cursor)
    all_agents.extend(page["items"])
    cursor = page["meta"].get("nextCursor")
    if not cursor:
        break

print(f"Total agents: {len(all_agents)}")
cursor = None
all_agents = []

while True:
    page = await recall.agents.list(limit=50, cursor=cursor)
    all_agents.extend(page["items"])
    cursor = page["meta"].get("nextCursor")
    if not cursor:
        break

print(f"Total agents: {len(all_agents)}")

get()

GET/v1/agents/:idAPI key (admin)stable
def get(self, agent_id: str) -> dict: ...

Fetch a single agent by its ID. The returned dict includes deletedAt, which is null when the agent is active and an ISO 8601 timestamp when it has been soft-deleted.

Parameters

ParameterTypeRequired
agent_idstrrequired

The id of the agent to fetch, e.g. 'ag_01HEX…'.

Examples

agent = recall.agents.get("ag_01HEX…")
print(agent["name"], "active:", agent["deletedAt"] is None)
agent = await recall.agents.get("ag_01HEX…")
print(agent["name"], "active:", agent["deletedAt"] is None)

Raises RecallNotFoundError when the ID does not exist or belongs to a different org.

create()

POST/v1/agentsAPI key (admin)stable
def create(
    self,
    name: str,
    *,
    namespace_id: Optional[str] = None,
) -> dict: ...

Create a new agent persona. The new agent immediately accepts memory writes scoped to it.

Parameters

ParameterTypeRequired
namestrrequired

Human-readable name for the agent, e.g. 'customer-support-v2'. Must be unique within the org. Names are immutable post-creation — use patch() to rename.

namespace_idstroptional

Pin the agent to a specific namespace. When omitted, the agent is bound to the namespace derived from the API key.

Agent creation counts against the org's agentsLimit. Check recall.org.plan() before bulk-creating agents to avoid hitting the cap mid-loop.

Returns

Returns the full agent dict including id, name, namespaceId, createdAt, updatedAt, and deletedAt (always null on creation).

Examples

agent = recall.agents.create("customer-support-v2")
print(agent["id"], agent["name"])
# ag_01HEX… customer-support-v2
agent = await recall.agents.create("customer-support-v2")
print(agent["id"], agent["name"])

patch()

PATCH/v1/agents/:idAPI key (admin)stable
def patch(
    self,
    agent_id: str,
    *,
    name: Optional[str] = None,
) -> dict: ...

Partially update an agent. Only the kwargs you pass are sent on the wire — unspecified fields are left unchanged on the server.

Parameters

ParameterTypeRequired
agent_idstrrequired

ID of the agent to update.

namestroptional

New display name. Must be unique within the org.

Returns

Returns the updated agent dict with the same shape as create().

Examples

updated = recall.agents.patch("ag_01HEX…", name="support-bot-v3")
print(updated["name"])   # support-bot-v3
updated = await recall.agents.patch("ag_01HEX…", name="support-bot-v3")
print(updated["name"])

delete()

DELETE/v1/agents/:idAPI key (admin)stable
def delete(self, agent_id: str) -> dict: ...

Soft-delete an agent. The agent is flagged as deleted and can no longer accept memory writes, but its existing memories remain intact.

Parameters

ParameterTypeRequired
agent_idstrrequired

ID of the agent to delete.

Returns

{
    "id": "ag_01HEX…",
    "deletedAt": "2026-05-10T08:00:00Z",
    "soft": True,
}

Memories written by this agent are NOT deleted. The agent's memory history remains fully accessible via recall.memories.list() and recall.memories.search(). Call recall.memories.forget() to remove them if needed.

Examples

result = recall.agents.delete("ag_01HEX…")
print("Deleted at:", result["deletedAt"])
result = await recall.agents.delete("ag_01HEX…")
print("Deleted at:", result["deletedAt"])

stats()

GET/v1/agents/:id/statsAPI key (admin)stable
def stats(self, agent_id: str) -> dict: ...

Fetch activity counters for a specific agent. Useful for monitoring agent health and detecting stale personas that can be pruned.

Parameters

ParameterTypeRequired
agent_idstrrequired

ID of the agent to inspect.

Returns

{
    "memoryCount": 1_204,
    "sessionCount": 87,
    "lastActiveAt": "2026-05-09T22:11:00Z",  # null if never used
}

lastActiveAt is null for newly created agents that have never had a memory written to them.

Examples

stats = recall.agents.stats("ag_01HEX…")
print(
    f"Agent has {stats['memoryCount']:,} memories "
    f"across {stats['sessionCount']} sessions."
)
if stats["lastActiveAt"] is None:
    print("Agent has never been used.")
stats = await recall.agents.stats("ag_01HEX…")
print(
    f"Agent has {stats['memoryCount']:,} memories "
    f"across {stats['sessionCount']} sessions."
)

Errors

CodeStatusRetry
RecallAuthError401/403fatal

API key missing, expired, or lacks admin scope.

RecallNotFoundError404fatal

Agent ID does not exist or belongs to a different org.

RecallValidationError422fatal

Invalid name (e.g. duplicate within org), malformed body.

RecallPlanLimitError402fatal

agentsLimit reached. Upgrade the plan or delete unused agents.

RecallRateLimitError429fatal

Rate limit exceeded. Inspect .retry_after_ms.

RecallServerError5xxfatal

Server-side failure. Retried automatically up to max_retries.

Was this page helpful?

On this page