Profiles and Memory
Every user in Configure has a Memory Profile — a persistent data structure that accumulates identity, preferences, tool data, and per-agent memories across every agent they interact with. Profiles are the core read/write surface of the SDK.
What a Memory Profile Contains
A profile is composed of five sections:
| Section | Description |
|---|---|
identity | Name, email, phone, bio, occupation, interests, and other structured fields |
preferences | Natural-language facts about the user (e.g., "Prefers window seats on flights") |
integrations | Connection status and synced data for Gmail, Calendar, Drive, and Notion |
agents | Per-agent memories, preferences, and metadata |
summary | Auto-generated natural-language summary of the user |
Reading Profiles
Use profile.get() to read a user's profile. By default it returns all sections.
typescript
import { ConfigureClient } from 'configure';
const client = new ConfigureClient('sk_your_api_key');
// Full profile
const profile = await client.profile.get(token, userId);
// Specific sections only
const partial = await client.profile.get(token, userId, {
sections: ['identity', 'preferences'],
});
// Specific path (returns raw data)
const identity = await client.profile.get(token, userId, {
path: 'identity',
});Formatting for Prompts
.format() converts a profile into a prompt-ready string. By default it includes identity, preferences, and memories — but excludes tool data (Gmail, Calendar, Drive, Notion) to keep the context lean. Pass { includeTools: true } when your agent needs inline access to tool data.
typescript
const context = profile.format(); // identity + preferences + memories
const rich = profile.format({ includeTools: true }); // + Gmail, Calendar, Drive, Notion dataSee the format() reference for details.
Example Response
json
{
"identity": {
"name": "Sarah Chen",
"email": "sarah@example.com",
"phone": "+14155551234",
"bio": "Product manager at a fintech startup",
"occupation": "Product Manager",
"interests": ["travel", "cooking", "photography"]
},
"preferences": [
"Prefers window seats on flights",
"Vegetarian, no shellfish",
"Morning person — schedule meetings before noon",
"Likes detailed itineraries over loose plans"
],
"integrations": {
"gmail": { "connected": true },
"calendar": { "connected": true },
"drive": { "connected": false },
"notion": { "connected": false }
},
"agents": {
"travelbot": {
"memories": "Booked a trip to Tokyo in March 2026...",
"preferences": ["Budget: $5000 per trip"]
}
},
"summary": "Sarah is a product manager who enjoys travel and cooking. She prefers structured planning and morning schedules."
}Saving Memories
Use profile.remember() to save a single fact or preference. The memory is stored under the calling agent's namespace, so different agents maintain separate memory streams for the same user.
typescript
await client.profile.remember(token, userId, 'Prefers window seats on flights');
await client.profile.remember(token, userId, 'Budget is $5000 per trip');
await client.profile.remember(token, userId, 'Allergic to shellfish, strictly vegetarian');The response confirms the save:
json
{
"saved": true,
"app": "travelbot",
"fact": "Prefers window seats on flights"
}Querying Memories
Use profile.getMemories() to retrieve memories with optional filters. Memories are sorted by date, newest first.
typescript
// All memories across all agents
const { memories } = await client.profile.getMemories(token, userId);
// Only this agent's memories
const { memories } = await client.profile.getMemories(token, userId, {
agent: 'self',
});
// Memories from a specific agent
const { memories } = await client.profile.getMemories(token, userId, {
agent: 'travelbot',
});
// Multiple agents
const { memories } = await client.profile.getMemories(token, userId, {
agents: ['travelbot', 'focusai'],
});
// Date range filter
const { memories } = await client.profile.getMemories(token, userId, {
agent: 'travelbot',
from: '2026-03-01',
to: '2026-03-15',
});Each memory entry contains:
json
{
"memories": [
{
"agent": "travelbot",
"date": "2026-03-15",
"content": "User booked a flight to Tokyo. Prefers JAL over ANA.",
"source": "conversation"
},
{
"agent": "travelbot",
"date": "2026-03-12",
"content": "Budget for Japan trip is $5000. Interested in ryokans.",
"source": "conversation"
}
]
}Memory Extraction
profile.ingest() analyzes content and automatically extracts facts, preferences, and context. It supports three modes.
Conversation Mode
Pass a messages array. Configure analyzes the conversation and extracts relevant facts.
typescript
await client.profile.ingest(token, userId, [
{ role: 'user', content: 'I just moved to San Francisco from New York' },
{ role: 'assistant', content: 'Welcome to SF! How are you settling in?' },
{ role: 'user', content: 'Great! I work at Stripe and live in the Mission District' },
], { sync: true });Text Mode
Pass freeform text — notes, exported conversations, bios, or any unstructured content.
typescript
await client.profile.ingest(token, userId, {
text: 'Sarah is a product manager at a fintech startup in SF. She loves Japanese cuisine, especially omakase. She runs 5K every morning and is training for a half marathon.',
sync: true,
});Batch Mode
Pass an array of IngestUserEntry objects to process up to 50 users at once. No user token is required — users are identified by userId (Configure UUID, email, or any stable identifier).
typescript
const result = await client.profile.ingest([
{
userId: 'sarah@example.com',
text: 'Prefers morning meetings. Works in product management.',
},
{
userId: 'alex@example.com',
conversations: [
{
messages: [
{ role: 'user', content: 'I need help planning a trip to Japan' },
{ role: 'assistant', content: 'What dates are you considering?' },
],
},
],
},
], { sync: true });
console.log(result.totalUsers); // 2
console.log(result.totalFactsWritten); // number of facts extractedSync vs. Async
By default, ingest() is fire-and-forget — it returns immediately with status: 'processing'. Pass { sync: true } to block until extraction completes and receive the extracted facts in the response.
Documents
Configure generates AI-ready identity documents from profile data. These are polished markdown files suitable for CLAUDE.md, system prompts, or any agent context.
Available Documents
| Document | Contents |
|---|---|
user.md | Comprehensive user overview — identity, preferences, communication style |
soul.md | Deeper personality profile — values, motivations, behavioral patterns |
preferences.md | Structured preferences organized by category |
context.md | Current context — recent activities, active projects, upcoming events |
Reading Documents
Documents are available as part of profile.get() response (as summary, soul, preferencesDoc, contextDoc), or can be read individually:
typescript
// Via profile.get() response
const profile = await client.profile.get(token, userId);
console.log(profile.summary);
// Read individual documents by path
const soul = await client.profile.read(token, userId, '/soul.md');
const prefs = await client.profile.read(token, userId, '/documents/preferences.md');Regenerating Documents
generateDocuments() regenerates documents using the latest profile data. It has a 1-hour cooldown — calling it within the cooldown window returns the cached version with cached: true.
typescript
const result = await client.profile.generateDocuments(token, userId);
if (result.cached) {
console.log('Returned cached documents (generated within last hour)');
} else {
console.log('Freshly generated documents');
}Sync
tools.syncAll() refreshes data from connected tools (Gmail, Calendar, Drive, Notion). Call this to pull the latest data before answering questions that depend on tool content.
typescript
// Sync all connected tools
const result = await client.tools.syncAll(token, userId);
// Sync specific tools
const result = await client.tools.syncAll(token, userId, ['gmail', 'calendar']);The response includes what was synced:
json
{
"userId": "usr_abc123",
"synced": {
"gmail": { "threads_count": 15 },
"calendar": { "events_count": 8 }
}
}