Appearance
Core Concepts
Understanding DialogueDB's core concepts will help you build better conversational applications. This guide covers the fundamental building blocks: dialogues, messages, threads, state, and memory.
Dialogues
A dialogue is a conversation session containing a series of messages. Think of it as a container for a complete conversation between users and AI assistants.
Dialogue Properties
typescript
{
id: string; // Unique identifier (user-provided or auto-generated)
namespace?: string; // Namespace - part of the resource's identity (required on all ops if set)
threadOf?: string; // Parent dialogue if this is a thread
requestId: string; // Request tracking ID
status: "active" | "ended" | "archived";
tags: string[]; // Custom tags for organization
totalMessages: number; // Count of messages in this dialogue
threadCount: number; // Number of child threads
lastMessageCreated: string; // Timestamp of most recent message
metadata: object; // Custom metadata
metadataLength?: number; // Size of metadata
metadataSHA256?: string; // Metadata hash
created: string; // Creation timestamp (ISO 8601)
modified: string; // Last modification timestamp (ISO 8601)
state: object; // Custom state data
messages?: Message[]; // Array of message objects (when included)
}Dialogue Lifecycle
- Created: New dialogue initialized
- Active: Accepting new messages
- Ended: Conversation marked as complete
- Deleted: Permanently removed (messages remain)
Creating Dialogues
bash
# Simple dialogue
curl -X POST https://api.dialoguedb.com/api/v1/dialogue \
-H "Authorization: Bearer DIALOGUE_DB_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"message": {
"role": "user",
"content": "Hello!"
}
}'
# Dialogue with metadata
curl -X POST https://api.dialoguedb.com/api/v1/dialogue \
-H "Authorization: Bearer DIALOGUE_DB_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"metadata": {
"userId": "user_123",
"channel": "web",
"sessionId": "session_abc"
},
"tags": ["customer-support", "billing-question"],
"message": {
"role": "user",
"content": "I have a billing question"
}
}'typescript
// Simple dialogue
const response = await fetch('https://api.dialoguedb.com/api/v1/dialogue', {
method: 'POST',
headers: {
'Authorization': 'Bearer DIALOGUE_DB_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
message: {
role: 'user',
content: 'Hello!'
}
})
});
const dialogue = await response.json();
// Dialogue with metadata
const response2 = await fetch('https://api.dialoguedb.com/api/v1/dialogue', {
method: 'POST',
headers: {
'Authorization': 'Bearer DIALOGUE_DB_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
metadata: {
userId: 'user_123',
channel: 'web',
sessionId: 'session_abc'
},
tags: ['customer-support', 'billing-question'],
message: {
role: 'user',
content: 'I have a billing question'
}
})
});
const dialogue2 = await response2.json();python
import requests
# Simple dialogue
response = requests.post(
"https://api.dialoguedb.com/api/v1/dialogue",
headers={"Authorization": "Bearer DIALOGUE_DB_API_KEY"},
json={
"message": {
"role": "user",
"content": "Hello!"
}
}
)
dialogue = response.json()
# Dialogue with metadata
response = requests.post(
"https://api.dialoguedb.com/api/v1/dialogue",
headers={"Authorization": "Bearer DIALOGUE_DB_API_KEY"},
json={
"metadata": {
"userId": "user_123",
"channel": "web",
"sessionId": "session_abc"
},
"tags": ["customer-support", "billing-question"],
"message": {
"role": "user",
"content": "I have a billing question"
}
}
)
dialogue = response.json()typescript
// Simple dialogue
const dialogue = await db.createDialogue({
messages: [{
role: 'user',
content: 'Hello!'
}]
});
// Dialogue with metadata
const dialogue = await db.createDialogue({
metadata: {
userId: 'user_123',
channel: 'web',
sessionId: 'session_abc'
},
tags: ['customer-support', 'billing-question'],
messages: [{
role: 'user',
content: 'I have a billing question'
}]
});If you create a dialogue with a namespace, you must pass the same namespace on every subsequent operation - see Namespace.
Messages
Messages are the individual exchanges within a dialogue. Each message represents a single turn in the conversation.
Message Properties
typescript
{
id: string; // Unique identifier (user-provided or auto-generated)
dialogueId: string; // Parent dialogue ID
namespace?: string; // Inherited from dialogue - required on all ops if set
role: string; // "user", "assistant", "system" by convention - custom roles allowed
content: string | object | object[]; // Message content (flexible shape)
name?: string; // Optional name for the speaker
metadata: object; // Custom metadata
tags: string[]; // Custom tags
created: string; // Creation timestamp (ISO 8601)
}Content accepts any shape: plain strings, structured objects, or arrays of content blocks. This lets you store tool calls, multi-part messages, and provider-specific formats directly without serializing to a string. See the Messages API for detailed examples.
Working with streaming LLMs
DialogueDB stores complete messages - it doesn't proxy or generate LLM responses. Stream from your LLM provider as usual, then call saveMessage() with the full response after the stream finishes. See Working with Streaming LLMs for a complete example.
Message Roles
DialogueDB supports three message roles:
User - Messages from end users
typescript
{
role: 'user',
content: 'What is the weather today?'
}Assistant - Responses from AI assistants
typescript
{
role: 'assistant',
content: 'The current weather is sunny with a high of 75°F.'
}System - System prompts and instructions
typescript
{
role: 'system',
content: 'You are a helpful weather assistant. Provide accurate and friendly weather information.'
}Message Storage
Messages are automatically stored and optimized for fast retrieval. The system handles storage transparently - you don't need to do anything special.
Creating Messages
bash
# Add a message to an existing dialogue
curl -X POST https://api.dialoguedb.com/api/v1/message \
-H "Authorization: Bearer DIALOGUE_DB_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"dialogueId": "DIALOGUE_ID",
"role": "user",
"content": "Can you explain quantum computing?"
}'
# Message with metadata
curl -X POST https://api.dialoguedb.com/api/v1/message \
-H "Authorization: Bearer DIALOGUE_DB_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"dialogueId": "DIALOGUE_ID",
"role": "assistant",
"content": "Quantum computing uses quantum mechanics...",
"metadata": {
"model": "gpt-4",
"tokensUsed": 250,
"temperature": 0.7
}
}'typescript
// Add a message to an existing dialogue
const response = await fetch('https://api.dialoguedb.com/api/v1/message', {
method: 'POST',
headers: {
'Authorization': 'Bearer DIALOGUE_DB_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
dialogueId: 'DIALOGUE_ID',
role: 'user',
content: 'Can you explain quantum computing?'
})
});
const message = await response.json();
// Message with metadata
const response2 = await fetch('https://api.dialoguedb.com/api/v1/message', {
method: 'POST',
headers: {
'Authorization': 'Bearer DIALOGUE_DB_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
dialogueId: 'DIALOGUE_ID',
role: 'assistant',
content: 'Quantum computing uses quantum mechanics...',
metadata: {
model: 'gpt-4',
tokensUsed: 250,
temperature: 0.7
}
})
});
const message2 = await response2.json();python
import requests
# Add a message to an existing dialogue
response = requests.post(
"https://api.dialoguedb.com/api/v1/message",
headers={"Authorization": "Bearer DIALOGUE_DB_API_KEY"},
json={
"dialogueId": "DIALOGUE_ID",
"role": "user",
"content": "Can you explain quantum computing?"
}
)
message = response.json()
# Message with metadata
response = requests.post(
"https://api.dialoguedb.com/api/v1/message",
headers={"Authorization": "Bearer DIALOGUE_DB_API_KEY"},
json={
"dialogueId": "DIALOGUE_ID",
"role": "assistant",
"content": "Quantum computing uses quantum mechanics...",
"metadata": {
"model": "gpt-4",
"tokensUsed": 250,
"temperature": 0.7
}
}
)
message = response.json()typescript
// Add a message to an existing dialogue
const message = await dialogue.saveMessage({
role: 'user',
content: 'Can you explain quantum computing?'
});
// Message with metadata
const message = await dialogue.saveMessage({
role: 'assistant',
content: 'Quantum computing uses quantum mechanics...',
metadata: {
model: 'gpt-4',
tokensUsed: 250,
temperature: 0.7
}
});Retrieving Messages
bash
# Get messages with pagination
curl -X GET "https://api.dialoguedb.com/api/v1/messages?dialogueId=DIALOGUE_ID&limit=20" \
-H "Authorization: Bearer DIALOGUE_DB_API_KEY"
# Get specific message
curl -X GET https://api.dialoguedb.com/api/v1/message/MESSAGE_ID \
-H "Authorization: Bearer DIALOGUE_DB_API_KEY"typescript
// Get messages with pagination
const response = await fetch(
'https://api.dialoguedb.com/api/v1/messages?dialogueId=DIALOGUE_ID&limit=20',
{
headers: {
'Authorization': 'Bearer DIALOGUE_DB_API_KEY'
}
}
);
const { items: messages, next } = await response.json();
// Load next page using the cursor
if (next) {
const nextResponse = await fetch(
`https://api.dialoguedb.com/api/v1/messages?dialogueId=DIALOGUE_ID&limit=20&next=${next}`,
{
headers: {
'Authorization': 'Bearer DIALOGUE_DB_API_KEY'
}
}
);
const { items: moreMessages } = await nextResponse.json();
}python
import requests
# Get messages with pagination
response = requests.get(
"https://api.dialoguedb.com/api/v1/messages",
headers={"Authorization": "Bearer DIALOGUE_DB_API_KEY"},
params={"dialogueId": "DIALOGUE_ID", "limit": 20}
)
data = response.json()
messages = data["items"]
# Load next page using the cursor
if data.get("next"):
response = requests.get(
"https://api.dialoguedb.com/api/v1/messages",
headers={"Authorization": "Bearer DIALOGUE_DB_API_KEY"},
params={"dialogueId": "DIALOGUE_ID", "limit": 20, "next": data["next"]}
)
more_messages = response.json()["items"]typescript
// Get messages with pagination
const messages = await dialogue.loadMessages({ limit: 20 });
// Load next page (SDK manages the cursor internally)
if (dialogue.hasMoreMessages) {
const more = await dialogue.loadMessages({ limit: 20, next: true });
}
// Get specific message
const message = await dialogue.getMessage(messageId);If the parent dialogue has a namespace, pass it when listing or retrieving messages too - see Namespace.
Threads
Threads are dialogues that are organizationally linked to a parent dialogue. Think of them as sub-conversations or related processes grouped under a main dialogue, rather than traditional conversational branches.
Understanding Threads
A thread is a full dialogue with its own messages, state, and lifecycle - but it references a parent dialogue via the threadOf field. This creates an organizational hierarchy without affecting the content or independence of either dialogue.
Key characteristics:
- Threads are complete, independent dialogues
- Used primarily for grouping and organization
- Each thread has its own message history
- Parent dialogue tracks
threadCountautomatically - Threads can be listed by their parent
Thread Use Cases
- Agent activities: Sub-tasks or tool executions related to a main conversation
- Parallel reasoning: Multiple AI thought processes for a single query
- Tool call logs: Detailed execution traces grouped under the main dialogue
- Internal processes: System operations associated with a user conversation
- Work breakdown: Decomposing a complex request into sub-dialogues
- Related conversations: Grouping follow-up discussions under an original inquiry
Creating Threads
bash
# Create a thread linked to a parent dialogue
curl -X POST https://api.dialoguedb.com/api/v1/dialogue \
-H "Authorization: Bearer DIALOGUE_DB_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"threadOf": "PARENT_DIALOGUE_ID",
"metadata": { "purpose": "tool-call" },
"tags": ["fetch_weather_data"]
}'
# Add a message to the thread
curl -X POST https://api.dialoguedb.com/api/v1/message \
-H "Authorization: Bearer DIALOGUE_DB_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"dialogueId": "THREAD_ID",
"role": "system",
"content": "Executing tool call: fetch_weather_data"
}'typescript
// Create a thread linked to a parent dialogue
const response = await fetch('https://api.dialoguedb.com/api/v1/dialogue', {
method: 'POST',
headers: {
'Authorization': 'Bearer DIALOGUE_DB_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
threadOf: 'PARENT_DIALOGUE_ID',
metadata: { purpose: 'tool-call' },
tags: ['fetch_weather_data']
})
});
const thread = await response.json();
// Add messages to the thread
await fetch('https://api.dialoguedb.com/api/v1/message', {
method: 'POST',
headers: {
'Authorization': 'Bearer DIALOGUE_DB_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
dialogueId: thread.id,
role: 'system',
content: 'Executing tool call: fetch_weather_data'
})
});
await fetch('https://api.dialoguedb.com/api/v1/message', {
method: 'POST',
headers: {
'Authorization': 'Bearer DIALOGUE_DB_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
dialogueId: thread.id,
role: 'assistant',
content: 'Weather data retrieved successfully'
})
});python
import requests
# Create a thread linked to a parent dialogue
response = requests.post(
"https://api.dialoguedb.com/api/v1/dialogue",
headers={"Authorization": "Bearer DIALOGUE_DB_API_KEY"},
json={
"threadOf": "PARENT_DIALOGUE_ID",
"metadata": {"purpose": "tool-call"},
"tags": ["fetch_weather_data"]
}
)
thread = response.json()
# Add messages to the thread
requests.post(
"https://api.dialoguedb.com/api/v1/message",
headers={"Authorization": "Bearer DIALOGUE_DB_API_KEY"},
json={
"dialogueId": thread["id"],
"role": "system",
"content": "Executing tool call: fetch_weather_data"
}
)
requests.post(
"https://api.dialoguedb.com/api/v1/message",
headers={"Authorization": "Bearer DIALOGUE_DB_API_KEY"},
json={
"dialogueId": thread["id"],
"role": "assistant",
"content": "Weather data retrieved successfully"
}
)typescript
// Create a thread linked to a parent dialogue
const thread = await dialogue.createThread({
metadata: { purpose: 'tool-call' },
tags: ['fetch_weather_data']
});
// Add messages after creation - createThread does not accept messages
await thread.saveMessage({
role: 'system',
content: 'Executing tool call: fetch_weather_data'
});
// The thread is a full dialogue with its own messages
await thread.saveMessage({
role: 'assistant',
content: 'Weather data retrieved successfully'
});
// Parent dialogue automatically tracks threadCount
const parent = await db.getDialogue('dlg_abc123');
console.log(`Parent has ${parent.threadCount} threads`);Listing Threads
typescript
// Get all threads of a dialogue
const threads = await dialogue.getThreads();
console.log(`Found ${threads.length} threads`);
// Each thread is a full dialogue
threads.forEach(thread => {
console.log(`Thread ${thread.id}: ${thread.totalMessages} messages`);
});Thread Hierarchy Example
Main Dialogue (ID: dlg_abc123)
├── User: "Analyze this code and suggest improvements"
├── Assistant: "I'll analyze the code using multiple approaches..."
│
├── Thread: Code Quality Analysis (threadOf: dlg_abc123)
│ ├── System: "Running static analysis..."
│ └── Assistant: "Found 5 issues..."
│
├── Thread: Performance Analysis (threadOf: dlg_abc123)
│ ├── System: "Profiling execution..."
│ └── Assistant: "Identified 3 bottlenecks..."
│
└── Thread: Security Scan (threadOf: dlg_abc123)
├── System: "Scanning for vulnerabilities..."
└── Assistant: "No critical issues found..."In this example, the main dialogue contains the user conversation, while threads capture parallel analysis processes.
Threads vs. Namespace
Don't confuse threads with namespace:
| Feature | Threads | Namespace |
|---|---|---|
| Purpose | Organizational hierarchy | User/tenant isolation |
| Relationship | Parent-child link | Flat grouping |
| Use Case | Sub-processes of a dialogue | Multi-tenant data separation |
| Visibility | Listed via parent ID | Queried by namespace value |
Use threads when: You need to group related dialogues under a parent conversation
Use namespace when: You need to isolate dialogues by user, tenant, or organization
State
State allows you to attach custom data to dialogues. Use state to persist conversation context, user preferences, or application-specific information.
State Use Cases
- Conversation context: Store current topic, intent, or stage
- User preferences: Remember user settings across messages
- Application data: Store form data, shopping cart, etc.
- Session information: Track authentication, permissions
Managing State
bash
# Create dialogue with initial state
curl -X POST https://api.dialoguedb.com/api/v1/dialogue \
-H "Authorization: Bearer DIALOGUE_DB_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"state": {
"currentTopic": "weather",
"location": "San Francisco",
"userPreference": "celsius"
},
"message": {
"role": "user",
"content": "What'\''s the temperature?"
}
}'
# Update state
curl -X PUT https://api.dialoguedb.com/api/v1/dialogue/DIALOGUE_ID/state \
-H "Authorization: Bearer DIALOGUE_DB_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"currentTopic": "weather",
"location": "New York",
"userPreference": "fahrenheit"
}'typescript
// Create dialogue with initial state
const response = await fetch('https://api.dialoguedb.com/api/v1/dialogue', {
method: 'POST',
headers: {
'Authorization': 'Bearer DIALOGUE_DB_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
state: {
currentTopic: 'weather',
location: 'San Francisco',
userPreference: 'celsius'
},
message: {
role: 'user',
content: "What's the temperature?"
}
})
});
const dialogue = await response.json();
// Update state
await fetch(`https://api.dialoguedb.com/api/v1/dialogue/${dialogue.id}/state`, {
method: 'PUT',
headers: {
'Authorization': 'Bearer DIALOGUE_DB_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
currentTopic: 'weather',
location: 'New York',
userPreference: 'fahrenheit'
})
});python
import requests
# Create dialogue with initial state
response = requests.post(
"https://api.dialoguedb.com/api/v1/dialogue",
headers={"Authorization": "Bearer DIALOGUE_DB_API_KEY"},
json={
"state": {
"currentTopic": "weather",
"location": "San Francisco",
"userPreference": "celsius"
},
"message": {
"role": "user",
"content": "What's the temperature?"
}
}
)
dialogue = response.json()
# Update state
requests.put(
f"https://api.dialoguedb.com/api/v1/dialogue/{dialogue['id']}/state",
headers={"Authorization": "Bearer DIALOGUE_DB_API_KEY"},
json={
"currentTopic": "weather",
"location": "New York",
"userPreference": "fahrenheit"
}
)typescript
// Create dialogue with initial state
const dialogue = await db.createDialogue({
state: {
currentTopic: 'weather',
location: 'San Francisco',
userPreference: 'celsius'
},
messages: [{
role: 'user',
content: 'What\'s the temperature?'
}]
});
// Update state
await dialogue.saveState({
currentTopic: 'weather',
location: 'New York', // Updated
userPreference: 'fahrenheit' // Updated
});
// Or set state property and save
dialogue.state = { currentTopic: 'weather', location: 'New York' };
await dialogue.save();
// Retrieve dialogue with state
const d = await db.getDialogue(dialogueId);
console.log(d.state); // Access stateState Best Practices
Do:
- Keep state small and focused
- Use state for session-specific data
- Update state as conversation progresses
Don't:
- Store large objects in state
- Use state for message history (use messages instead)
- Store sensitive data without encryption
Memory
Memories are persistent, searchable pieces of information that live independently of any dialogue. Unlike state (scoped to a single dialogue) or messages (conversation turns), memories persist across all dialogues and can be found via semantic search.
Use memories for anything that should be recalled later: user preferences, facts, context that spans conversations.
Memory vs. State vs. Messages
| Feature | Memory | State | Messages |
|---|---|---|---|
| Lifespan | Indefinite (until deleted) | Per-dialogue | Per-dialogue |
| Search | Semantic search | Not searchable | Semantic search |
| Updates | Tags only | Merged on update | Immutable |
| Scope | Global or namespace | Dialogue-specific | Dialogue-specific |
| Use case | Long-term facts & preferences | Session context | Conversation turns |
Memory Properties
typescript
{
id: string; // Unique identifier (custom or auto-generated)
value: any; // The stored value (string, number, boolean, object, or array)
namespace?: string; // Optional namespace for isolation
label?: string; // Human-readable label
description?: string; // Description of this memory
tags: string[]; // Categorization tags
metadata: object; // Custom metadata (immutable after creation)
created: string; // Creation timestamp (ISO 8601)
modified: string; // Last modification timestamp (ISO 8601)
}Creating and Searching Memories
bash
# Store a memory
curl -X POST https://api.dialoguedb.com/api/v1/memory \
-H "Authorization: Bearer DIALOGUE_DB_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"value": "User prefers dark mode and metric units",
"namespace": "user_456",
"tags": ["preferences"],
"label": "Display Settings"
}'
# Search memories by meaning
curl -X POST https://api.dialoguedb.com/api/v1/search \
-H "Authorization: Bearer DIALOGUE_DB_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"query": "display settings",
"object": "memory",
"namespace": "user_456"
}'typescript
// Store a memory
const response = await fetch('https://api.dialoguedb.com/api/v1/memory', {
method: 'POST',
headers: {
'Authorization': 'Bearer DIALOGUE_DB_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
value: 'User prefers dark mode and metric units',
namespace: 'user_456',
tags: ['preferences'],
label: 'Display Settings'
})
});
const memory = await response.json();
// Search memories by meaning
const searchResponse = await fetch('https://api.dialoguedb.com/api/v1/search', {
method: 'POST',
headers: {
'Authorization': 'Bearer DIALOGUE_DB_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
query: 'display settings',
object: 'memory',
namespace: 'user_456'
})
});
const results = await searchResponse.json();python
import requests
# Store a memory
response = requests.post(
"https://api.dialoguedb.com/api/v1/memory",
headers={"Authorization": "Bearer DIALOGUE_DB_API_KEY"},
json={
"value": "User prefers dark mode and metric units",
"namespace": "user_456",
"tags": ["preferences"],
"label": "Display Settings"
}
)
memory = response.json()
# Search memories by meaning
response = requests.post(
"https://api.dialoguedb.com/api/v1/search",
headers={"Authorization": "Bearer DIALOGUE_DB_API_KEY"},
json={
"query": "display settings",
"object": "memory",
"namespace": "user_456"
}
)
results = response.json()typescript
// Store a memory
const memory = await db.createMemory({
value: 'User prefers dark mode and metric units',
namespace: 'user_456',
tags: ['preferences'],
label: 'Display Settings'
});
// Search memories by meaning
const memories = await db.searchMemories('display settings', {
namespace: 'user_456'
});Retrieving and Deleting Memories
bash
# Get a memory by ID
curl -X GET "https://api.dialoguedb.com/api/v1/memory/mem_abc123?namespace=user_456" \
-H "Authorization: Bearer DIALOGUE_DB_API_KEY"
# Delete a memory
curl -X DELETE "https://api.dialoguedb.com/api/v1/memory/mem_abc123?namespace=user_456" \
-H "Authorization: Bearer DIALOGUE_DB_API_KEY"typescript
// Get a memory by ID
const response = await fetch(
`https://api.dialoguedb.com/api/v1/memory/${memoryId}?namespace=user_456`,
{ headers: { 'Authorization': 'Bearer DIALOGUE_DB_API_KEY' } }
);
const memory = await response.json();
// Delete a memory
await fetch(
`https://api.dialoguedb.com/api/v1/memory/${memoryId}?namespace=user_456`,
{
method: 'DELETE',
headers: { 'Authorization': 'Bearer DIALOGUE_DB_API_KEY' }
}
);python
import requests
# Get a memory by ID
response = requests.get(
f"https://api.dialoguedb.com/api/v1/memory/{memory_id}",
headers={"Authorization": "Bearer DIALOGUE_DB_API_KEY"},
params={"namespace": "user_456"}
)
memory = response.json()
# Delete a memory
requests.delete(
f"https://api.dialoguedb.com/api/v1/memory/{memory_id}",
headers={"Authorization": "Bearer DIALOGUE_DB_API_KEY"},
params={"namespace": "user_456"}
)typescript
// Get a memory by ID
const memory = await db.getMemory('mem_abc123', { namespace: 'user_456' });
// Delete a memory
await db.deleteMemory('mem_abc123', { namespace: 'user_456' });Memory Use Cases
- User preferences: Store settings that persist across conversations
- Facts and knowledge: Remember information mentioned in past dialogues
- Entity data: Structured data about users, products, relationships
- Feature flags: Per-user or per-namespace configuration
Memory Best Practices
Do:
- Use namespace to scope memories by user or tenant
- Use custom IDs for predictable access (e.g.,
user_${id}_preferences) - Use tags for categorization and organization
- Use search to find memories by meaning, not just exact keys
Don't:
- Store conversation history in memories (use messages)
- Store temporary session data in memories (use state)
- Store large blobs - memories are indexed for search
TIP
For complete Memory API details, see the Memory API Reference. For SDK methods, see the Memory & Search SDK Reference.
Dialogue Actions
DialogueDB provides actions to manage dialogue lifecycle:
End Conversation
Mark a dialogue as complete:
typescript
await dialogue.end();typescript
await fetch(`https://api.dialoguedb.com/api/v1/dialogue/${dialogueId}/end`, {
method: 'POST',
headers: {
'Authorization': 'Bearer DIALOGUE_DB_API_KEY'
}
});python
import requests
response = requests.post(
f"https://api.dialoguedb.com/api/v1/dialogue/{dialogue_id}/end",
headers={"Authorization": "Bearer DIALOGUE_DB_API_KEY"}
)bash
curl -X POST https://api.dialoguedb.com/api/v1/dialogue/DIALOGUE_ID/end \
-H "Authorization: Bearer DIALOGUE_DB_API_KEY"Use when:
- User closes the conversation
- AI completes a task
- Session expires
Pagination
When retrieving large datasets, use pagination:
typescript
// Initial request
const { items, next } = await db.listDialogues({
limit: 20
});
// Next page
if (next) {
const { items: moreItems, next: nextToken } = await db.listDialogues({
limit: 20,
next: next
});
}
// Messages use SDK-managed pagination (next: true, not a cursor string)
const messages = await dialogue.loadMessages({ limit: 20 });
if (dialogue.hasMoreMessages) {
const more = await dialogue.loadMessages({ limit: 20, next: true });
}Namespace
Namespace is an optional property for grouping and isolating dialogues, messages, and memories within a project. It's the recommended way to scope data by user, tenant, or any other boundary.
How It Works
Set namespace when creating a resource. If you create a dialogue with a namespace, pass the same namespace when operating on that dialogue, its messages, and its state.
Namespace rules: Letters, numbers, underscores, and hyphens only. Must start and end with a letter or number. No dots, colons, or slashes.
bash
# Create dialogue with namespace
curl -X POST https://api.dialoguedb.com/api/v1/dialogue \
-H "Authorization: Bearer DIALOGUE_DB_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"namespace": "user_789",
"message": {
"role": "user",
"content": "Hello"
}
}'
# Get it back - pass the same namespace
curl -X GET "https://api.dialoguedb.com/api/v1/dialogue/DIALOGUE_ID?namespace=user_789" \
-H "Authorization: Bearer DIALOGUE_DB_API_KEY"
# List dialogues filtered by namespace
curl -X GET "https://api.dialoguedb.com/api/v1/dialogue?namespace=user_789" \
-H "Authorization: Bearer DIALOGUE_DB_API_KEY"typescript
// Create dialogue with namespace
const response = await fetch('https://api.dialoguedb.com/api/v1/dialogue', {
method: 'POST',
headers: {
'Authorization': 'Bearer DIALOGUE_DB_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
namespace: 'user_789',
message: {
role: 'user',
content: 'Hello'
}
})
});
const dialogue = await response.json();
// Get it back - pass the same namespace
const getResponse = await fetch(
`https://api.dialoguedb.com/api/v1/dialogue/${dialogue.id}?namespace=user_789`,
{
headers: {
'Authorization': 'Bearer DIALOGUE_DB_API_KEY'
}
}
);
const found = await getResponse.json();
// List dialogues filtered by namespace
const listResponse = await fetch(
'https://api.dialoguedb.com/api/v1/dialogue?namespace=user_789',
{
headers: {
'Authorization': 'Bearer DIALOGUE_DB_API_KEY'
}
}
);
const { items } = await listResponse.json();python
import requests
# Create dialogue with namespace
response = requests.post(
"https://api.dialoguedb.com/api/v1/dialogue",
headers={"Authorization": "Bearer DIALOGUE_DB_API_KEY"},
json={
"namespace": "user_789",
"message": {
"role": "user",
"content": "Hello"
}
}
)
dialogue = response.json()
# Get it back - pass the same namespace
response = requests.get(
f"https://api.dialoguedb.com/api/v1/dialogue/{dialogue['id']}",
headers={"Authorization": "Bearer DIALOGUE_DB_API_KEY"},
params={"namespace": "user_789"}
)
found = response.json()
# List dialogues filtered by namespace
response = requests.get(
"https://api.dialoguedb.com/api/v1/dialogue",
headers={"Authorization": "Bearer DIALOGUE_DB_API_KEY"},
params={"namespace": "user_789"}
)
items = response.json()["items"]typescript
// Create dialogue with namespace
const dialogue = await db.createDialogue({
namespace: 'user_789',
messages: [{
role: 'user',
content: 'Hello'
}]
});
// Get it back - pass the same namespace
const found = await db.getDialogue(dialogue.id, { namespace: 'user_789' });
// List dialogues filtered by namespace
const { items } = await db.listDialogues({
namespace: 'user_789'
});Namespace Required on All Operations
If you create a resource with a namespace, you must pass the same namespace on every subsequent operation - get, update, delete, and list. Omitting it returns a not-found error (DIALOGUE_NOT_FOUND, MEMORY_NOT_FOUND, etc.) even though the resource exists.
typescript
// Created with namespace
const dialogue = await db.createDialogue({ namespace: 'tenant-a', ... });
// Must include namespace to retrieve
await db.getDialogue(dialogue.id, { namespace: 'tenant-a' }); // works
await db.getDialogue(dialogue.id); // DIALOGUE_NOT_FOUNDThis applies to dialogues, messages, memories, and state. If you're getting unexpected not-found errors, check whether the resource was created with a namespace.
Namespace Use Cases
- User isolation: Scope conversations by user ID for multi-user apps
- Tenant separation: Isolate data by organization in B2B applications
- Environment segmentation: Separate dev/staging/prod data
- Feature flagging: Group dialogues by feature or experiment
Namespace Examples
Multi-tenant SaaS:
typescript
const ns = `org_${organizationId}`;
// Create
await db.createDialogue({
namespace: ns,
message: { role: 'user', content: 'Help request' }
});
// List
const { items } = await db.listDialogues({ namespace: ns });
// Get
const dialogue = await db.getDialogue(dialogueId, { namespace: ns });User-specific memories:
typescript
const ns = `user_${userId}`;
// Store
await db.createMemory({
namespace: ns,
value: 'Prefers dark mode',
label: 'UI Preference'
});
// Retrieve
const memory = await db.getMemory(memoryId, { namespace: ns });
// Search
const memories = await db.searchMemories('preferences', {
namespace: ns
});Namespace Best Practices
Do:
- Use consistent naming conventions (e.g.,
user_${id},org_${id}) - Keep namespace values meaningful and predictable
- Always store and pass the namespace alongside the resource ID
Don't:
- Put sensitive data in namespace (it's not encrypted)
- Use extremely long namespace strings (max 64 characters)
- Treat namespace as authentication (use proper API key scoping)
- Mix namespaced and non-namespaced resources if you can avoid it
Namespace vs. Other Features
| Feature | Purpose | Scope |
|---|---|---|
| Namespace | Grouping and isolation | User-defined, required on all operations if set |
| Project | Top-level isolation | API key scoped |
| Thread | Parent-child linking | Hierarchical relationship |
| Metadata | Arbitrary key-values | Resource-specific |
| Tags | Categorization | Simple labels |
Identifiers
All resources in DialogueDB have unique identifiers:
- Dialogues: User-provided or auto-generated (e.g.,
01KACE6RAZKQ93354SF18CJHHCormy-custom-id) - Messages: User-provided or auto-generated (e.g.,
01KAD7FYPBVZBF5J1KVVR9NR8S) - Memories: Custom keys or auto-generated
- Projects: e.g.,
01KAD6R34620P1C5J0M2KRMGRG
Auto-generated IDs are:
- Globally unique: No collisions across your account
- Time-sortable: IDs contain timestamp information for natural ordering
- URL-safe: Can be used directly in API paths
Custom IDs must be unique within a project and can be 1-64 characters.
Next Steps
- Use Cases & Patterns - Common conversation patterns
- API Reference - Detailed endpoint documentation
- Best Practices - Optimization strategies

