Agents
Create and manage agents — the named personas that own memories within a namespace. Covers recall.agents.list(), get(), create(), patch(), delete(), and stats().
Agents sit between the organisation and memories in Recall's identity hierarchy: an org has many agents, each agent is bound to a namespace, and all memories written through an agent key are scoped to that agent. Creating and managing agents is an administrative operation, separate from the day-to-day memory pipeline operations exposed on recall.remember() and recall.search().
agents.list(opts?, options?)
recall.agents.list(
opts?: { limit?: number; cursor?: string },
options?: TransportRequestOptions
): PagedRequest<AgentSummary>Returns a PagedRequest<AgentSummary> — await it for the first page, or for await it to auto-paginate through every agent in the org. This is the same dual-mode iterable pattern used by recall.memory.list() and recall.entity.search(). See Pagination for the full PagedRequest semantics.
Parameters
opts.limitnumberoptional[1, 100].opts.cursorstringoptionaloptionsTransportRequestOptionsoptionalsignal, maxRetries, timeoutMs. Applied on top of the client defaults.AgentSummary (per item)
idAgentIdalwaysnamestringalwaysnamespaceIdstringalwayscreatedAtstringalwaysupdatedAtstringalwaysExamples
// First page only
const page = await recall.agents.list({ limit: 20 })
console.log(page.items, page.hasMore, page.nextCursor)
// Auto-paginate every agent in the org
for await (const agent of recall.agents.list()) {
console.log(agent.id, agent.name)
}
// Materialize up to 200 agents
const all = await recall.agents.list({ limit: 50 }).toArray({ limit: 200 })Errors
UNAUTHORIZED401fatalFORBIDDEN403fataladmin scope.agents.get(id, options?)
recall.agents.get(id: AgentId, options?: TransportRequestOptions): Promise<AgentDetail>Returns full detail for a single agent. Throws RecallNotFoundError for unknown or hard-deleted IDs.
Returns
idAgentIdalwaysnamestringalwaysnamespaceIdstringalwayscreatedAtstringalwaysupdatedAtstringalwaysdeletedAtstring | nullalwaysnull for active agents.Example
import { type AgentId } from '@arc-labs/recall'
const id = 'agt_abc123' as AgentId
const agent = await recall.agents.get(id)
console.log(agent.name, agent.namespaceId, agent.deletedAt)Errors
UNAUTHORIZED401fatalFORBIDDEN403fataladmin scope.NOT_FOUND404fatalagents.create(name, opts?, options?)
recall.agents.create(
name: string,
opts?: { namespaceId?: string },
options?: TransportRequestOptions
): Promise<AgentDetail>Provisions a new agent in the org. The agent name must be unique within the org — the server enforces uniqueness and returns 409 CONFLICT on collision. Once created, the agent can have API keys issued against it via recall.keys.create().
Parameters
namestringrequiredopts.namespaceIdstringoptionaloptionsTransportRequestOptionsoptionalReturns
AgentDetail — the same shape as agents.get(). All fields are populated immediately; no async provisioning step.
Example
const agent = await recall.agents.create('billing-assistant', {
namespaceId: 'ns_prod',
})
console.log('Created agent:', agent.id, agent.name)
// Issue a key for the new agent immediately
const key = await recall.keys.create({
name: 'billing-assistant-prod',
agentId: agent.id,
})
// Store key.key in your secret manager — it is returned exactly once.Errors
UNAUTHORIZED401fatalFORBIDDEN403fataladmin scope.CONFLICT409fatalMAX_AGENTS_REACHED429fatalagents.patch(id, changes, options?)
recall.agents.patch(
id: AgentId,
changes: { name?: string },
options?: TransportRequestOptions
): Promise<AgentDetail>Update mutable fields on an existing agent. Currently only name is patchable — the namespaceId binding is immutable after creation. Returns the updated AgentDetail.
Parameters
idAgentIdrequiredchanges.namestringoptional409 CONFLICT if the name is taken.optionsTransportRequestOptionsoptionalExample
const updated = await recall.agents.patch('agt_abc123' as AgentId, {
name: 'billing-assistant-v2',
})
console.log('Renamed to:', updated.name, 'at', updated.updatedAt)Errors
UNAUTHORIZED401fatalFORBIDDEN403fataladmin scope.NOT_FOUND404fatalCONFLICT409fatalagents.delete(id, options?)
recall.agents.delete(id: AgentId, options?: TransportRequestOptions): Promise<DeleteResult>Soft-deletes an agent. The agent's deletedAt is set to the current timestamp, and all API keys bound to that agent stop authenticating immediately. The agent's memories are not deleted.
Returns { id, deletedAt, soft: true }.
Deleting an agent does not cascade to its memories. They remain queryable by scope until you explicitly call recall.forget() targeting the agent's scope. If you want a clean teardown, forget the memories first, then delete the agent.
Returns
idAgentIdalwaysdeletedAtstringalwayssofttruealwaystrue — hard deletion is not available via the SDK.Example
// Step 1: forget all memories belonging to the agent
await recall.forget({ filter: { agentId: 'agt_abc123' }, reason: 'decommissioning agent' })
// Step 2: delete the agent itself
const result = await recall.agents.delete('agt_abc123' as AgentId)
console.log('Deleted at:', result.deletedAt)Errors
UNAUTHORIZED401fatalFORBIDDEN403fataladmin scope.NOT_FOUND404fatalagents.stats(id, options?)
recall.agents.stats(id: AgentId, options?: TransportRequestOptions): Promise<AgentStats>Returns usage statistics for a single agent. Useful for dashboards, capacity planning, and billing attribution.
Returns
memoryCountnumberalwayssessionCountnumberalwayslastActiveAtstringExample
const stats = await recall.agents.stats('agt_abc123' as AgentId)
console.log(`${stats.memoryCount} memories, last active: ${stats.lastActiveAt ?? 'never'}`)
// Gate on activity before deciding to decommission
if (!stats.lastActiveAt) {
await recall.agents.delete('agt_abc123' as AgentId)
}Errors
UNAUTHORIZED401fatalFORBIDDEN403fataladmin scope.NOT_FOUND404fatalWas this page helpful?