Short walkthroughs that turn the platform into your operations team: automated pipelines, instant follow-ups, AI-handled admin. One video, one less thing to do manually.
How AI agents read and write persistent memory in TrustPager — the 6 MCP tools, REST path, field reference, upsert mechanic, tags, linked entities, and a worked NurtureAgent example.
Agent Memory lets your AI agents store and retrieve structured knowledge between runs. An agent can write a memory after pitching a feature, and read it back before the next email to avoid repeating itself. Memory is scoped per-agent, per-subject — so the NurtureAgent remembers what it said to each contact independently.
For a general overview of AI agents in TrustPager, see https://trustpager.com/help-center/how-to-monitor-ai-agents-in-agent-hub.
Each memory record has a few key fields:
contact, opportunity, company, etc.) and its UUID.pitch, objection, preference, observation. kind is required on every write.feature_pitched, pitch_angle, next_angles_to_try).(agent, subject_type, subject_id, kind) tuple. Used for upsert — see below."private" (default, only the writing agent can read) or "shared" (any agent in the workspace can read).text[] of namespaced semantic facets such as ["competitor:Twilio", "feature:voice_agents"]. Useful for cross-cutting facets that span subjects. Query via list_memory(tag=...).[{type, id}] array for memories that reference multiple CRM entities. For example, a pitch memory is primarily about a contact but you can also link it to the opportunity it relates to. Query via list_memory(linked_entity_type=opportunity, linked_entity_id=<uuid>).source_kind: "email_send", source_id: "<email_log_id>").Your API key needs the following scopes:
memory:read — list, get, and search memoriesmemory:write — write, update, and delete memoriesManage scopes at https://app.trustpager.com/settings/api.
All memory endpoints are under /v1/memory.
GET /v1/memory — list and filter memories (subject_type, subject_id, kind, tag, linked_entity_type, linked_entity_id)GET /v1/memory/:id — get a single memory by idPOST /v1/memory — create or upsert a memoryPATCH /v1/memory/:id — partial update by idDELETE /v1/memory/:id — soft delete by idPOST /v1/memory/search — semantic search across memory contentAll six memory operations are available as MCP tools:
list_memory — list and filter memories by subject, kind, tag, or linked entityget_memory — fetch a single memory by idwrite_memory — create a new memory, or upsert an existing one via keyupdate_memory — partial update of an existing memory by iddelete_memory — soft delete a memory by idsearch_memory — semantic search across memory content and metadataPassing key on write_memory makes the call an upsert against the tuple (agent_registry_id, subject_type, subject_id, kind, key). Re-running the same tuple updates the existing memory row instead of creating a duplicate. Soft-deleted rows are restored and updated when upserted.
This is the natural way to enforce a never-twice gate. For example, a NurtureAgent pitching article slugs uses key: "<article_slug>". Pitching the same article a second time simply updates the existing row — no duplicate, no second pitch.
A NurtureAgent wants to track that it pitched a feature to a contact, along with the angle used and next angles to try. The memory is contact-level because both the cooldown gate (“don’t email the same person twice in 3 days”) and the never-twice gate (“don’t pitch the same article twice”) are enforced per-contact. The related opportunity is linked via linked_entities.
write_memory(
agent_registry_id: "<your own id from kickoff>",
subject_type: "contact",
subject_id: "<contact_uuid>",
kind: "pitch",
key: "automated-follow-up-sequences",
content: "Pitched automated follow-up sequences to Sarah. Angle: their team is stretched thin; sequences save 3 hours per week on manual follow-up.",
metadata: {
feature_pitched: "Automated follow-up sequences",
pitch_angle: "saves 3 hours per week on manual follow-up",
stated_need_addressed: "team stretched thin on manual follow-up",
next_angles_to_try: [
"ROI calculator — show dollar value of time saved",
"Case study — similar business in their industry",
"Free trial offer — remove the risk of committing"
]
},
linked_entities: [
{ type: "opportunity", id: "<opportunity_uuid>" },
{ type: "email_log", id: "<email_log_id_from_send_response>" }
],
tags: ["feature:follow_up_sequences", "angle:time_savings"],
source_kind: "email_send",
source_id: "<email_log_id>"
)
On the next run, the agent calls list_memory(subject_type="contact", subject_id="<uuid>", kind="pitch") to see every pitch already made — and skips any article whose slug appears as a key in the results.
list_memory(subject_type="contact", subject_id="<uuid>") — all memories about a contactkind="pitch" to narrow to pitch memories onlylist_memory(tag="feature:voice_agents") — cross-subject facet querylist_memory(linked_entity_type="opportunity", linked_entity_id="<uuid>") — all memories that reference a given opportunitysearch_memory(query="stretched thin on follow-up") — vector search across content and metadatavisibility: "private" is the default — only the agent that wrote the memory can read it. Set visibility: "shared" if you want other agents in the same workspace to read the memory. For example, a SupportAgent and a NurtureAgent might both need to know that a contact expressed a pricing objection.
(agent_registry_id, subject_type, subject_id, kind, key) tuple without intending to upsert. Either omit key (creates a new row every time) or include it (upserts the existing row).subject_type and subject_id match exactly what was written. A contact UUID written under subject_type: "contact" will not appear in a query for subject_type: "opportunity".visibility: "private" (the default). The writing agent needs to set visibility: "shared" for cross-agent reads.Talk to Evie right now, or book a real human for a deeper walkthrough. Whichever feels right.
Hear her in 10 seconds.

60 minutes with a real human · Google Meet · Free.