Appearance
Messages API
Manage individual messages within dialogues.
Create Message
Add a new message to a dialogue.
Endpoint
http
POST /dialogue/{id}/messagesAuthentication
Bearer token (via Authorization header)
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Dialogue ID (identifier) |
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
role | string | Yes | Message role: "user", "assistant", or "system" |
content | string | object | object[] | Yes | Message content — plain text, structured object, or array of content blocks |
name | string | No | Optional name for the speaker |
id | string | No | Custom message ID (auto-generated if not provided) |
created | string | No | Custom creation timestamp (ISO 8601, auto-generated if not provided) |
metadata | object | No | Custom metadata (can't be changed after creation) |
tags | string[] | No | Custom tags |
Response
typescript
{
id: string;
dialogueId: string;
role: string;
content: string | object | object[];
contentLength: number;
created: string;
modified: string;
}Behavior
- Authenticated via bearer token
- Full content included in response
- Updates dialogue message count and timestamp
Which Fields Can Be Changed?
User-settable on creation:
content- Message content (required)role- Message role (required)name- Optional speaker nameid- Custom identifier (auto-generated if omitted)created- Custom timestamp (auto-generated if omitted)tags- Categorization tagsmetadata- Custom metadata (can't be changed after creation)
System-managed (read-only):
dialogueId- Parent dialogue referencecontentLength- Content size in bytesmodified- Last modification timestamp
Messages Can't Be Changed
Messages cannot be updated after creation — only created and deleted. If you need to "edit" a message:
- Delete the original message
- Create a new message with the corrected content
- Or keep the original and add a follow-up correction message
Metadata Can't Be Changed
Message metadata is set at creation and cannot be changed. Use tags for categorization that may need to change later.
Errors
| Status | Error Code | Description |
|---|---|---|
| 400 | MISSING_PARAMETER | Missing required field (role, content, or dialogue ID) |
| 400 | MESSAGE_CONTENT_EMPTY | Message content cannot be empty |
| 400 | MESSAGE_TOO_LARGE | Message exceeds 1MB uncompressed size limit |
| 401 | N/A | Unauthorized - invalid or missing API key |
| 404 | DIALOGUE_NOT_FOUND | Dialogue does not exist |
| 409 | DIALOGUE_ENDED | Cannot add messages to an ended dialogue |
| 409 | DIALOGUE_IMMUTABLE | Cannot add messages to immutable dialogue |
| 429 | RATE_LIMIT_EXCEEDED | Too many requests - retry with backoff |
| 500 | INTERNAL_ERROR | Server error - contact support with requestId |
See Error Handling for complete error reference.
Examples
bash
curl -X POST https://api.dialoguedb.com/dialogue/dlg_abc123xyz/messages \
-H "Authorization: Bearer DIALOGUE_DB_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"role": "user",
"content": "Hello, how are you?"
}'typescript
const message = await fetch(
`https://api.dialoguedb.com/dialogue/${dialogueId}/messages`,
{
method: 'POST',
headers: {
'Authorization': 'Bearer DIALOGUE_DB_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
role: 'user',
content: 'Hello, how are you?',
metadata: {
timestamp: new Date().toISOString(),
userId: 'user_123'
}
})
}
).then(r => r.json());python
import requests
response = requests.post(
f"https://api.dialoguedb.com/dialogue/{dialogue_id}/messages",
headers={
"Authorization": "Bearer DIALOGUE_DB_API_KEY",
"Content-Type": "application/json"
},
json={
"role": "user",
"content": "Hello, how are you?",
"metadata": {
"timestamp": "2026-02-19T12:00:00Z"
}
}
)
message = response.json()typescript
const dialogue = await db.getDialogue(dialogueId);
const message = await dialogue.saveMessage({
role: 'user',
content: 'Hello, how are you?',
metadata: {
timestamp: new Date().toISOString()
}
});List Messages
Retrieve messages for a specific dialogue with pagination.
Endpoint
http
GET /dialogue/{id}/messagesAuthentication
Bearer token (via Authorization header)
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Dialogue ID (identifier) |
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
limit | number | No | Max messages to return (default: 50) |
next | string | No | Pagination token for next page |
Response
typescript
{
items: Message[];
next?: string; // Pagination token if more messages exist
}Message Format
typescript
{
id: string;
dialogueId: string;
role: "user" | "assistant" | "system";
content: string | object | object[];
contentLength: number;
created: string;
metadata?: Record<string, any>;
}Behavior
- Messages ordered chronologically (oldest first)
- Paginate for large conversation histories
- Full content included for all messages
- Authenticated via bearer token
Errors
| Status | Error Code | Description |
|---|---|---|
| 400 | MISSING_PARAMETER | Missing required dialogue ID |
| 401 | N/A | Unauthorized - invalid or missing API key |
| 404 | DIALOGUE_NOT_FOUND | Dialogue does not exist |
| 429 | RATE_LIMIT_EXCEEDED | Too many requests - retry with backoff |
| 500 | INTERNAL_ERROR | Server error - contact support with requestId |
See Error Handling for complete error reference.
Examples
bash
curl -X GET "https://api.dialoguedb.com/dialogue/dlg_abc123xyz/messages?limit=100" \
-H "Authorization: Bearer DIALOGUE_DB_API_KEY"typescript
const { items, next } = await fetch(
`https://api.dialoguedb.com/dialogue/${dialogueId}/messages?limit=100`,
{
headers: {
'Authorization': 'Bearer DIALOGUE_DB_API_KEY'
}
}
).then(r => r.json());
// Load next page
if (next) {
const { items: more, next: nextToken } = await fetch(
`https://api.dialoguedb.com/dialogue/${dialogueId}/messages?limit=100&next=${next}`,
{
headers: {
'Authorization': 'Bearer DIALOGUE_DB_API_KEY'
}
}
).then(r => r.json());
}python
import requests
response = requests.get(
f"https://api.dialoguedb.com/dialogue/{dialogue_id}/messages",
headers={"Authorization": "Bearer DIALOGUE_DB_API_KEY"},
params={"limit": 100}
)
data = response.json()
items = data["items"]
next_token = data.get("next")
# Load next page
if next_token:
response = requests.get(
f"https://api.dialoguedb.com/dialogue/{dialogue_id}/messages",
headers={"Authorization": "Bearer DIALOGUE_DB_API_KEY"},
params={"limit": 100, "next": next_token}
)
more_data = response.json()typescript
const dialogue = await db.getDialogue(dialogueId);
const messages = await dialogue.loadMessages({
limit: 100
});
// Load next page
const moreMessages = await dialogue.loadMessages({
limit: 100,
next: messages.next
});Get Single Message
Retrieve a single message by ID.
Endpoint
http
GET /dialogue/{id}/message/{messageId}Authentication
Bearer token (via Authorization header)
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Dialogue ID (identifier) |
messageId | string | Yes | Message ID (identifier) |
Response
typescript
{
id: string;
dialogueId: string;
role: "user" | "assistant" | "system";
content: string | object | object[];
contentLength: number;
created: string;
metadata?: Record<string, any>;
}Behavior
- Returns complete message with full content
- Authenticated via bearer token
Errors
| Status | Error Code | Description |
|---|---|---|
| 400 | MISSING_PARAMETER | Missing required dialogue ID or message ID |
| 401 | N/A | Unauthorized - invalid or missing API key |
| 404 | MESSAGE_NOT_FOUND | Message does not exist |
| 429 | RATE_LIMIT_EXCEEDED | Too many requests - retry with backoff |
| 500 | INTERNAL_ERROR | Server error - contact support with requestId |
See Error Handling for complete error reference.
Examples
bash
curl -X GET https://api.dialoguedb.com/dialogue/dlg_abc123xyz/message/msg_xyz789abc \
-H "Authorization: Bearer DIALOGUE_DB_API_KEY"typescript
const message = await fetch(
`https://api.dialoguedb.com/dialogue/${dialogueId}/message/${messageId}`,
{
headers: {
'Authorization': 'Bearer DIALOGUE_DB_API_KEY'
}
}
).then(r => r.json());python
import requests
response = requests.get(
f"https://api.dialoguedb.com/dialogue/{dialogue_id}/message/{message_id}",
headers={"Authorization": "Bearer DIALOGUE_DB_API_KEY"}
)
message = response.json()typescript
// Get a single message by ID (use raw API)
import { api } from 'dialogue-db';
const message = await api.message.get({
dialogueId,
id: messageId
});Delete Message
Delete a specific message from a dialogue.
Endpoint
http
DELETE /dialogue/{id}/message/{messageId}Authentication
Bearer token (via Authorization header)
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Dialogue ID (identifier) |
messageId | string | Yes | Message ID (identifier) |
Response
typescript
{
success: boolean;
id: string;
dialogueId: string;
}Behavior
- Permanently removes the message
- Dialogue
totalMessagescount is decremented - This operation cannot be undone
Warnings
- Irreversible: Deleted messages cannot be recovered
- Use sparingly: Consider soft-deletion via metadata instead
Related Endpoints
GET /dialogue/{id}/messages- List remaining messagesDELETE /dialogue/{id}- Delete entire dialogue
Errors
| Status | Error Code | Description |
|---|---|---|
| 400 | MISSING_PARAMETER | Missing required dialogue ID or message ID |
| 401 | N/A | Unauthorized - invalid or missing API key |
| 404 | MESSAGE_NOT_FOUND | Message does not exist |
| 409 | DIALOGUE_IMMUTABLE | Cannot delete messages from immutable dialogue |
| 429 | RATE_LIMIT_EXCEEDED | Too many requests - retry with backoff |
| 500 | INTERNAL_ERROR | Server error - contact support with requestId |
See Error Handling for complete error reference.
Examples
bash
curl -X DELETE https://api.dialoguedb.com/dialogue/dlg_abc123xyz/message/msg_xyz789abc \
-H "Authorization: Bearer DIALOGUE_DB_API_KEY"typescript
const result = await fetch(
`https://api.dialoguedb.com/dialogue/${dialogueId}/message/${messageId}`,
{
method: 'DELETE',
headers: {
'Authorization': 'Bearer DIALOGUE_DB_API_KEY'
}
}
).then(r => r.json());python
import requests
response = requests.delete(
f"https://api.dialoguedb.com/dialogue/{dialogue_id}/message/{message_id}",
headers={"Authorization": "Bearer DIALOGUE_DB_API_KEY"}
)
result = response.json()typescript
const dialogue = await db.getDialogue(dialogueId);
await dialogue.deleteMessage(messageId);Message Roles
User
Messages from end users or human participants.
typescript
{
role: 'user',
content: 'What is the weather today?'
}Assistant
Responses from AI assistants or bots.
typescript
{
role: 'assistant',
content: 'The current weather is sunny with a high of 75°F.'
}System
System prompts, instructions, or notifications.
typescript
{
role: 'system',
content: 'You are a helpful weather assistant. Provide accurate information.'
}Message Content
The content field accepts string | object | object[] — store whatever shape your application needs. DialogueDB doesn't enforce any particular content schema; it stores and returns your content exactly as provided.
This is especially useful for AI applications where messages aren't just plain text.
Plain Text
json
{
"role": "user",
"content": "What is the weather today?"
}Tool Calls
Store tool/function calls directly in content — no need to flatten to a string:
json
{
"role": "assistant",
"content": [
{
"type": "text",
"text": "Let me check the weather for you."
},
{
"type": "tool_use",
"id": "call_abc123",
"name": "get_weather",
"input": { "location": "San Francisco", "unit": "fahrenheit" }
}
]
}Tool Results
json
{
"role": "user",
"content": [
{
"type": "tool_result",
"tool_use_id": "call_abc123",
"content": "72°F, sunny with light clouds"
}
]
}Multi-Part Content
json
{
"role": "user",
"content": [
{ "type": "text", "text": "What's in this image?" },
{ "type": "image_url", "image_url": { "url": "https://example.com/photo.jpg" } }
]
}Structured Objects
json
{
"role": "assistant",
"content": {
"type": "structured_output",
"data": { "sentiment": "positive", "confidence": 0.95, "topics": ["weather", "travel"] }
}
}Store It As-Is
You don't need to JSON.stringify() structured content into a string. Pass objects and arrays directly — DialogueDB handles serialization and will return the original structure when you retrieve the message.
Message Storage
Messages are automatically stored and optimized for fast retrieval. The system handles storage transparently - you don't need to do anything special.
Retrieving Messages
All messages include full content when retrieved:
typescript
const dialogue = await db.getDialogue(dialogueId);
const messages = await dialogue.loadMessages();
// All messages include complete content
messages.forEach(msg => {
console.log(msg.content); // Full message content
console.log(msg.contentLength); // Content size in bytes
});Best Practices
Pagination
Always use pagination for dialogues with many messages:
typescript
async function getAllMessages(dialogueId: string) {
const db = new DialogueDB({ apiKey: process.env.DIALOGUE_DB_API_KEY });
const dialogue = await db.getDialogue(dialogueId);
const allMessages = [];
let nextToken = undefined;
do {
const result = await dialogue.loadMessages({
limit: 100,
next: nextToken
});
allMessages.push(...result);
nextToken = result.next;
} while (nextToken);
return allMessages;
}Message Batching
When adding multiple messages, use parallel creation:
typescript
// Add multiple messages efficiently using saveMessages
const dialogue = await db.getDialogue(dialogueId);
await dialogue.saveMessages([
{ role: 'user', content: 'Question 1' },
{ role: 'assistant', content: 'Answer 1' },
{ role: 'user', content: 'Question 2' }
]);Error Handling
Handle message creation errors gracefully with proper error codes:
typescript
async function safeCreateMessage(dialogue: any, message: any) {
try {
return await dialogue.saveMessage(message);
} catch (error) {
switch (error.code) {
case 'DIALOGUE_NOT_FOUND':
console.error('Dialogue not found - create it first');
break;
case 'MESSAGE_CONTENT_EMPTY':
console.error('Message content cannot be empty');
break;
case 'MESSAGE_TOO_LARGE':
console.error('Message exceeds 1MB limit');
break;
case 'DIALOGUE_IMMUTABLE':
console.error('Cannot modify immutable dialogue');
break;
case 'RATE_LIMIT_EXCEEDED':
await sleep(1000);
return safeCreateMessage(dialogue, message);
default:
console.error('Failed to create message:', error);
}
throw error;
}
}See Error Handling Guide for comprehensive error handling patterns.

