Skip to content

Messages API

Manage individual messages within dialogues.

Create Message

Add a single message to a dialogue.

Endpoint

http
POST /message

Authentication

Bearer token (via Authorization header)

Request Body

FieldTypeRequiredDescription
idstringNoCustom message ID (auto-generated if not provided)
dialogueIdstringYesDialogue ID
namespacestringNoNamespace (required if the dialogue was created with one)
rolestringYesMessage role: "user", "assistant", or "system"
contentstring | object | object[]YesMessage content - plain text, structured object, or array of content blocks
namestringNoOptional name for the speaker
createdstringNoCustom creation timestamp (ISO 8601, auto-generated if not provided)
metadataobjectNoCustom metadata (can't be changed after creation)
tagsstring[]NoCustom 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 name
  • id - Custom identifier (auto-generated if omitted)
  • created - Custom timestamp (auto-generated if omitted)
  • tags - Categorization tags
  • metadata - Custom metadata (can't be changed after creation)

System-managed (read-only):

  • dialogueId - Parent dialogue reference
  • contentLength - Content size in bytes
  • modified - 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

StatusError CodeDescription
400MISSING_PARAMETERMissing required field (role, content, or dialogue ID)
400MESSAGE_CONTENT_EMPTYMessage content cannot be empty
400MESSAGE_TOO_LARGEMessage exceeds 1MB uncompressed size limit
401N/AUnauthorized - invalid or missing API key
404DIALOGUE_NOT_FOUNDDialogue does not exist
409DIALOGUE_ENDEDCannot add messages to an ended dialogue
409DIALOGUE_IMMUTABLECannot add messages to immutable dialogue
429RATE_LIMIT_EXCEEDEDToo many requests - retry with backoff
500INTERNAL_ERRORServer 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 /messages

Authentication

Bearer token (via Authorization header)

Request Body

FieldTypeRequiredDescription
dialogueIdstringYesDialogue ID
namespacestringNoNamespace (required if the dialogue was created with one)
messagesarrayYesArray 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

ParameterTypeRequiredDescription
dialogueIdstringYesDialogue ID
namespacestringNoNamespace (required if the dialogue was created with one)
limitnumberNoMax messages to return (default: )
nextstringNoPagination 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

StatusError CodeDescription
400MISSING_PARAMETERMissing required dialogue ID
401N/AUnauthorized - invalid or missing API key
404DIALOGUE_NOT_FOUNDDialogue does not exist
429RATE_LIMIT_EXCEEDEDToo many requests - retry with backoff
500INTERNAL_ERRORServer 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

ParameterTypeRequiredDescription
messageIdstringYesMessage ID

Query Parameters

ParameterTypeRequiredDescription
dialogueIdstringYesDialogue ID
namespacestringNoNamespace (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

StatusError CodeDescription
400MISSING_PARAMETERMissing required dialogue ID or message ID
401N/AUnauthorized - invalid or missing API key
404MESSAGE_NOT_FOUNDMessage does not exist
429RATE_LIMIT_EXCEEDEDToo many requests - retry with backoff
500INTERNAL_ERRORServer 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

ParameterTypeRequiredDescription
messageIdstringYesMessage ID

Query Parameters

ParameterTypeRequiredDescription
dialogueIdstringYesDialogue ID
namespacestringNoNamespace (required if the dialogue was created with one)

Response

typescript
{
  success: boolean;
  id: string;
  dialogueId: string;
}

Behavior

  • Permanently removes the message
  • Dialogue totalMessages count is decremented
  • This operation cannot be undone

Warnings

  • Irreversible: Deleted messages cannot be recovered
  • Use sparingly: Consider soft-deletion via metadata instead
  • GET /messages?dialogueId={id} - List remaining messages
  • DELETE /dialogue/{id} - Delete entire dialogue

Errors

StatusError CodeDescription
400MISSING_PARAMETERMissing required dialogue ID or message ID
401N/AUnauthorized - invalid or missing API key
404MESSAGE_NOT_FOUNDMessage does not exist
409DIALOGUE_IMMUTABLECannot delete messages from immutable dialogue
429RATE_LIMIT_EXCEEDEDToo many requests - retry with backoff
500INTERNAL_ERRORServer 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.

Built with DialogueDB