Skip to main content

Memory.recall()

The Memory.recall() method retrieves messages from a specific thread, with support for pagination, filtering options, and semantic search.

Usage example
Direct link to Usage example

const { messages } = await memory.recall({
threadId: 'thread-123',
perPage: 20,
})

Parameters
Direct link to Parameters

threadId:

string
The unique identifier of the thread to retrieve messages from

resourceId?:

string
Optional ID of the resource that owns the thread. If provided, validates thread ownership

vectorSearchString?:

string
Search string for finding semantically similar messages. Requires semantic recall to be enabled in threadConfig.

perPage?:

number | false
Number of messages to retrieve per page. Set to false to fetch all messages without pagination. If not provided, defaults to threadConfig.lastMessages.

page?:

number
Zero-based page number for pagination. Used with perPage to retrieve messages in batches.

include?:

{ id: string; threadId?: string; withPreviousMessages?: number; withNextMessages?: number }[]
Array of specific message IDs to include with optional context messages. Each item has an id (required), optional threadId (defaults to main threadId), withPreviousMessages (number of messages before, defaults to 2 for vector search, 0 otherwise), and withNextMessages (number of messages after, defaults to 2 for vector search, 0 otherwise).

filter?:

{ dateRange?: { start?: Date; end?: Date; startExclusive?: boolean; endExclusive?: boolean }; metadata?: Record<string, string | number | boolean | null> }
Filter options for message retrieval. dateRange filters messages by creation date. metadata filters shallow message metadata by exact scalar key-value pairs using AND semantics. Metadata values can be strings, finite numbers, booleans, or null.

hideSignals?:

boolean | ('user' | 'state' | 'reactive' | 'notification' | 'user-message' | 'system-reminder')[]
Use true to hide all recognized signals, false to include all, or an array to omit exact stored types. Any explicit value takes precedence over includeSystemReminders. Does not change storage or model context.

includeSystemReminders?:

boolean
= false
Deprecated. Use hideSignals: false to include all signals, or hideSignals: ["reactive", "system-reminder"] to hide reminders. When hideSignals is omitted, true includes all signals; false or omitted preserves reminder-hidden history.

orderBy?:

{ field: 'createdAt'; direction: 'ASC' | 'DESC' }
Sort order for retrieved messages. Defaults to descending by creation date.

threadConfig?:

MemoryConfig
Configuration options for message retrieval and semantic search
MemoryConfig

lastMessages?:

number | false
Number of most recent messages to retrieve. Set to false to disable. When perPage is not explicitly provided, this value is used as the default.

semanticRecall?:

boolean | { topK: number; messageRange: number | { before: number; after: number }; scope?: 'thread' | 'resource' }
Enable semantic search in message history. Can be a boolean or an object with configuration options. When enabled, requires both vector store and embedder to be configured.

workingMemory?:

WorkingMemory
Configuration for working memory feature. Can be { enabled: boolean; template?: string; schema?: ZodObject<any> | JSONSchema7; scope?: 'thread' | 'resource' } or { enabled: boolean } to disable.

threads?:

{ generateTitle?: boolean | { model: DynamicArgument<MastraLanguageModel>; instructions?: DynamicArgument<string> } }
Settings related to memory thread creation. generateTitle controls automatic thread title generation from the conversation transcript. Can be a boolean or an object with custom model and instructions.

Signal visibility
Direct link to Signal visibility

hideSignals filters messages returned by this call, not the underlying storage or later model requests. Ordinary messages remain available. This option isn't a security boundary and doesn't change signal delivery or persistence policies such as ifActive, ifIdle, or transient.

Defaults and precedence
Direct link to Defaults and precedence

hideSignalsincludeSystemRemindersReturned signals
OmittedOmitted or falseExisting reminder-hidden history
OmittedtrueAll signals
false or []Any valueAll signals
trueAny valueNo recognized signals, including legacy reminders
Nonempty listAny valueAll except matching types

Unlike agent streams, recall continues to hide reminders by default for compatibility. The deprecated includeSystemReminders flag only applies when hideSignals is omitted.

const all = await memory.recall({
threadId: 'thread-123',
hideSignals: false,
})

const withoutSignals = await memory.recall({
threadId: 'thread-123',
hideSignals: true,
})

const withoutReminders = await memory.recall({
threadId: 'thread-123',
hideSignals: ['reactive', 'system-reminder'],
})

Stored types and legacy messages
Direct link to Stored types and legacy messages

Recall matches the exact stored type, without alias normalization. For example, ['reactive'] doesn't exclude a row encoded as system-reminder, and ['user'] doesn't exclude one encoded as user-message. Modern streams and subscriptions normalize these aliases instead. Use ['reactive', 'system-reminder'] to exclude both reminder representations across these APIs.

A recognized type in a data-signal or data-user-message part takes precedence over signal metadata and legacy reminder markers. Signal-role messages can also encode their type in content.metadata.signal.type. Unknown types and malformed signal parts don't match exclusions, including hideSignals: true.

If no recognized encoded type exists, a message classified by the existing legacy reminder rules counts as system-reminder, not reactive. These rules include user messages with systemReminder or dynamicAgentsMdReminder metadata, or a first text part starting with <system-reminder. Such rows remain visible with ['reactive'] and are excluded with ['system-reminder'].

Pagination and API scope
Direct link to Pagination and API scope

Filtering happens after the storage query and pagination. A page can contain fewer than perPage messages, or none, without changing total, hasMore, or page offsets. Totals still describe the underlying query, not the filtered messages.

The option applies to in-process memory.recall() calls. HTTP and client-js contracts don't expose hideSignals in this release.

Metadata filtering
Direct link to Metadata filtering

Use filter.metadata to match shallow scalar metadata stored on messages:

const { messages } = await memory.recall({
threadId: 'thread-123',
filter: {
metadata: {
category: 'billing',
escalated: true,
priority: 2,
archivedAt: null,
},
},
})

All metadata entries are combined with AND semantics. A message must match every key and value with exact type equality. null matches metadata that's explicitly set to null. It doesn't match a missing key.

Metadata filters only support shallow scalar values: string, finite number, boolean, and null. Nested objects, arrays, NaN, and infinities aren't supported. Metadata keys must start with a letter or underscore and contain only alphanumeric or underscore characters. The limit is 128 characters. Reserved prototype keys such as __proto__, constructor, and prototype aren't allowed. Performance depends on the storage backend. Arbitrary metadata filters may require scanning candidate messages, so narrow the query with threadId, resourceId, or dateRange when possible.

Returns
Direct link to Returns

messages:

MastraDBMessage[]
Array of retrieved messages in the database format

Extended usage example
Direct link to Extended usage example

src/test-memory.ts
import { mastra } from './mastra'

const agent = mastra.getAgent('agent')
const memory = await agent.getMemory()

// Retrieve messages with pagination
const { messages } = await memory!.recall({
threadId: 'thread-123',
perPage: 50,
vectorSearchString: 'What messages are there?',
include: [
{
id: 'msg-123',
},
{
id: 'msg-456',
withPreviousMessages: 3,
withNextMessages: 1,
},
],
threadConfig: {
semanticRecall: true,
},
})

console.log(messages) // MastraDBMessage[]

// Fetch all messages without pagination
const allMessages = await memory!.recall({
threadId: 'thread-123',
perPage: false, // Fetch all
})

// Convert to AI SDK format if needed
import { toAISdkV5Messages } from '@mastra/ai-sdk/ui'
const uiMessages = toAISdkV5Messages(messages)