Skip to main content
POST
Procedural-memory recall (pre-tool-call hook)

Authorizations

x-api-key
string
header
required

Long-lived org API key. Alternative: Authorization: Bearer <key>.

Body

application/json

POST /v1/memories/trigger — procedural-memory recall for a pre-tool-call hook.

An agent calls this right before (or just after) a tool runs to pull the lesson/procedure insights that past sessions recorded about the symbols it's touching — what worked, what didn't. Recall fires on the symbol tripwire, never a semantic query: the server extracts greppable identifiers from action (tool / args / output) or takes them straight from entities, and matches them exactly against directives' trigger_entities.

What comes back is advisory, not a mandate — ranked :class:Memory rows (type: "lesson" | "procedure") in the shared :class:SearchResponse, with the assembled markdown in context under mode="compose".

Scope follows "scope by what you pass": every axis you supply ANDs; org_id is derived server-side from your API key. At least one of user_id / agent_id / app_id / group_ids is required — an unscoped org-wide recall is rejected.

action
ActionContext · object | null

The in-flight tool call the agent is touching right now — the firing signal for recall. Greppable identifiers are extracted server-side (tool name, args values, optional output) and matched exactly against directives' trigger_entities. Supply this or entities.

entities
string[] | null

Escape hatch: pre-extracted greppable identifiers to fire on, bypassing server-side extraction from action. Use when the client already knows the exact symbols the agent is touching.

Example:
include
enum<string>[]

Which procedural corpora to recall. Defaults to both (lesson/procedure); subset to restrict (e.g. ["lesson"]).

Available options:
lesson,
procedure
namespace
string | null

Namespace the agent is working in right now — repo, customer account, service (whatever was passed at ingest). Narrows recall to directives learned under that namespace plus global ones (ingested with no namespace) — it never hides global directives, so it is always safe to pass. Unrelated to the tenancy axes.

Maximum string length: 256
Example:

"MemHub-Backend"

task
string | null

The agent's current goal, in one line. Fed to the relevance gate under mode=compose so it keeps only the insights that help with THIS task.

Maximum string length: 2000
Example:

"fix finalize-on-abort in the tool loop"

mode
enum<string>
default:compose

Pipeline depth selector.

  • compose (default) — symbol-tripwire recall plus an LLM relevance-gate step that keeps only the insights relevant to task, then assembles a markdown block. data carries the gated rows; context carries the markdown. One LLM call.
  • retrieve — recall only. No LLM, cheaper and faster. data carries the matched rows; context is null.
Available options:
retrieve,
compose
user_id
string | null

Scope key. When supplied, applied as an AND pin so reads are tenant-isolated at the storage filter layer. Optional: omit it and pass group_ids to read a shared group across users. At least one of user_id / agent_id / app_id / group_ids is required.

Example:

"user-123"

group_ids
string[]

Optional group tags — another AND scope axis. When non-empty, matched rows must be tagged to at least one of the requested group(s). Group ids are server-generated unguessable handles (see POST /v1/groups); knowing the id is the access boundary.

Example:
agent_id
string | null

Optional agent scope. When set, ANDs onto the active primary scope (whether that's user_id or group_ids): matched rows must also carry this exact agent_id.

Example:

"bot-7"

app_id
string | null

Optional app scope. When set, ANDs onto the active primary scope (like agent_id): matched rows must also carry this exact app_id.

Example:

"app-3"

Response

Successful Response

POST /v1/memories/search response.

data is always populated — both modes return the ranked Memory rows from retrieval. context is populated only when mode='compose' with the assembled markdown block from the LLM context-selection step. stage_timings is always present for per-stage latency attribution.

Note that under mode='compose' the rows in data are the retrieval candidates — a possibly larger set than the subset the LLM selected and wove into context. Useful for showing "everything we found" alongside "what we sent to the model."

mode
enum<string>
required

Echoes the request's mode. compose ⇒ both data and context populated; retrievedata populated and context null.

Available options:
retrieve,
compose
object
string
default:search

Constant discriminator for the resource type.

Allowed value: "search"
data
Memory · object[]

Ranked Memory rows from retrieval. Populated for both modes. Semantic rows (fact/artifact/episode) are ordered by score desc; when include requests lesson/procedure, those directive rows are precision-gated (not vector-scored, score is null) and lead the list ahead of the semantic rows. For mode=compose, the semantic rows are the candidates considered by the context-selection step — a (possibly larger) superset of what ended up in context.

context
string | null

Assembled markdown context block ready for prompt insertion. Populated only when mode=compose; null otherwise.

stage_timings
Stage Timings · object

Per-stage retrieval-pipeline latencies (seconds). Populated in both modes.

context_selection_applied
boolean
default:false

True when the LLM context-selection step ran. False indicates the pipeline fell through (e.g. an empty candidate pool, or context selection disabled by config).