Appearance
Messages API
Manage individual messages within dialogues.
Create Message
Add a single message to a dialogue.
Endpoint
http
POST /messageAuthentication
Bearer token (via Authorization header)
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
id | string | No | Custom message ID (auto-generated if not provided) |
dialogueId | string | Yes | Dialogue ID |
namespace | string | No | Namespace (required if the dialogue was created with one) |
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 |
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;
namespace?: 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
Namespace Required
If the dialogue was created with a namespace, you must pass the same namespace on all subsequent requests (create, get, list, delete), or the dialogue will not be found.
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/api/v1/message \
-H "Authorization: Bearer DIALOGUE_DB_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"dialogueId": "dlg_abc123xyz",
"role": "user",
"content": "Hello, how are you?"
}'typescript
const message = 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,
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(
"https://api.dialoguedb.com/api/v1/message",
headers={
"Authorization": "Bearer DIALOGUE_DB_API_KEY",
"Content-Type": "application/json"
},
json={
"dialogueId": dialogue_id,
"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()
}
});Create Messages (Batch)
Add multiple messages to a dialogue in a single request.
Endpoint
http
POST /messagesAuthentication
Bearer token (via Authorization header)
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
dialogueId | string | Yes | Dialogue ID |
namespace | string | No | Namespace (required if the dialogue was created with one) |
messages | array | Yes | Array of message objects |
Each message in the array has the same fields as a single create (role, content, name, id, created, metadata, tags).
Examples
bash
curl -X POST https://api.dialoguedb.com/api/v1/messages \
-H "Authorization: Bearer DIALOGUE_DB_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"dialogueId": "dlg_abc123xyz",
"messages": [
{ "role": "user", "content": "Hello" },
{ "role": "assistant", "content": "Hi there!" }
]
}'typescript
const result = await fetch(
'https://api.dialoguedb.com/api/v1/messages',
{
method: 'POST',
headers: {
'Authorization': 'Bearer DIALOGUE_DB_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
dialogueId,
messages: [
{ role: 'user', content: 'Hello' },
{ role: 'assistant', content: 'Hi there!' }
]
})
}
).then(r => r.json());python
import requests
response = requests.post(
"https://api.dialoguedb.com/api/v1/messages",
headers={
"Authorization": "Bearer DIALOGUE_DB_API_KEY",
"Content-Type": "application/json"
},
json={
"dialogueId": dialogue_id,
"messages": [
{"role": "user", "content": "Hello"},
{"role": "assistant", "content": "Hi there!"}
]
}
)
result = response.json()List Messages
Retrieve messages for a specific dialogue with pagination.
Endpoint
http
GET /messages?dialogueId={id}Authentication
Bearer token (via Authorization header)
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
dialogueId | string | Yes | Dialogue ID |
namespace | string | No | Namespace (required if the dialogue was created with one) |
limit | number | No | Max messages to return (default: ) |
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;
namespace?: 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/api/v1/messages?dialogueId=dlg_abc123xyz&limit=20" \
-H "Authorization: Bearer DIALOGUE_DB_API_KEY"typescript
const { items, next } = await fetch(
`https://api.dialoguedb.com/api/v1/messages?dialogueId=${dialogueId}&limit=20`,
{
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/api/v1/messages?dialogueId=${dialogueId}&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/api/v1/messages?dialogueId={dialogue_id}",
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/api/v1/messages?dialogueId={dialogue_id}",
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: 20
});
// Load next page
const moreMessages = await dialogue.loadMessages({
limit: 20,
next: messages.next
});Get Single Message
Retrieve a single message by ID.
Endpoint
http
GET /message/{messageId}?dialogueId={id}Authentication
Bearer token (via Authorization header)
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
messageId | string | Yes | Message ID |
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
dialogueId | string | Yes | Dialogue ID |
namespace | string | No | Namespace (required if the dialogue was created with one) |
Response
typescript
{
id: string;
dialogueId: string;
namespace?: 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/api/v1/message/msg_xyz789abc?dialogueId=dlg_abc123xyz \
-H "Authorization: Bearer DIALOGUE_DB_API_KEY"typescript
const message = await fetch(
`https://api.dialoguedb.com/api/v1/message/${messageId}?dialogueId=${dialogueId}`,
{
headers: {
'Authorization': 'Bearer DIALOGUE_DB_API_KEY'
}
}
).then(r => r.json());python
import requests
response = requests.get(
f"https://api.dialoguedb.com/api/v1/message/{message_id}?dialogueId={dialogue_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 /message/{messageId}?dialogueId={id}Authentication
Bearer token (via Authorization header)
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
messageId | string | Yes | Message ID |
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
dialogueId | string | Yes | Dialogue ID |
namespace | string | No | Namespace (required if the dialogue was created with one) |
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 /messages?dialogueId={id}- 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/api/v1/message/msg_xyz789abc?dialogueId=dlg_abc123xyz \
-H "Authorization: Bearer DIALOGUE_DB_API_KEY"typescript
const result = await fetch(
`https://api.dialoguedb.com/api/v1/message/${messageId}?dialogueId=${dialogueId}`,
{
method: 'DELETE',
headers: {
'Authorization': 'Bearer DIALOGUE_DB_API_KEY'
}
}
).then(r => r.json());python
import requests
response = requests.delete(
f"https://api.dialoguedb.com/api/v1/message/{message_id}?dialogueId={dialogue_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: 25,
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.

