ingest— append messages to a scope. A plain write: it just stores them, and nothing waits on it.recall— given an arriving turn, return injectable context about the people involved. Billable.ask— answer a natural-language question over a scope. Billable.
recall (typical agent loop) or query the scope directly with
ask.
When to call them
All three are per-message or on-demand calls — none of them belong on a timer.ingest: every message, both the human’s and your agent’s. Memory can only recall what it has seen, so hold nothing back. Fire it in the background and ignore the result; a droppedingestcosts you one message of memory, not a reply.recall: on the turns where you are going to reply. In a 1:1 chat that is every message. In a group thread where most messages getstay_silent, call it only after the decision comes backspeak— context recalled for a reply you never draft is context nobody reads.ask: on demand. When a human, or your agent, has an actual question about the conversation’s history. It is not part of the reply loop.
recall runs while the user waits, so issue it in parallel with your other
per-message calls rather than in sequence. See
When to call each API.
Scopes
A scope is one conversation — “which group” the memory is about. The caller chooses the identifier:string
required
A non-empty string of up to 255 characters. The caller picks it (for example,
team-chat-1 or room:42). All three actions are addressed by this id.scope_id. There is no
clear or delete endpoint — to reset a scope, generate a new scope_id and
ingest into that. The old scope simply stops being read from.
Messages
Every transcript message — both the rows you ingest and the arriving turn passed torecall — uses the same shape:
string
required
Who sent the message: a display name or stable id, 1–255 characters. The
speaker is part of the signal — the same text from different speakers pulls
different context on
recall.string
required
The message text.
What a read sees
recall and ask answer from the conversation you have ingested into the
scope. A scope can grow without bound — there is no cap on how much you ingest,
and you can keep ingesting for the life of the conversation.
The only request rejected up front is an incoming recall.message.text or
ask.question that is itself too large for a single call: shorten it and retry
(400). An empty scope is a no-op for recall and ask — both return an empty
result immediately.

