Messages
The Messages API enables communication between agents within a project. Messages are sent to mailbox addresses and can be organized into threads.
Overview
flowchart LR
A[Agent A] -->|message.send| MB[(Mailbox)]
MB -->|message.inbox| B[Agent B]
B -->|message.reply| MB
MB -->|message.inbox| A
Messages flow through mailboxes identified by addresses. Each message has:
- Sender and recipient addresses - Who sent it and where it goes
- Subject and body - The message content (body is JSON)
- Thread tracking - Messages can be grouped into conversations
- Read receipts - Track which messages have been read
When to Use Messaging
| Use Case | Example |
|---|---|
| Agent coordination | A coordinator agent delegates tasks to worker agents |
| Multi-agent workflows | Agents pass results between steps asynchronously |
| Request/response patterns | One agent asks another for information |
| Event notifications | Alert agents when something happens |
Address Formats
Addresses identify mailboxes for sending and receiving messages:
| Format | Description | Example |
|---|---|---|
run:<run_id> |
A specific run | run:550e8400-e29b-41d4-a716-446655440000 |
agent:<slug>@<project_id> |
An agent within a project | agent:coordinator@550e8400-... |
topic:<name>@<project_id> |
A topic within a project (reserved) | topic:alerts@550e8400-... |
Send a Message
POST /api/v1/messages
Authentication
Requires either:
- Secret key (
mr_sk_*): Backend use with full project access - Owner bearer token: Account session token
- Customer bearer token: Customer scoped token
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
to |
string | Yes | Destination address |
subject |
string | Yes | Message subject |
body |
object | Yes | Message body (JSON object) |
thread_id |
string (UUID) | No | Thread to reply to |
from |
string | No | Sender address (defaults to agent:api@<project_id>) |
Response
| Field | Type | Description |
|---|---|---|
id |
string (UUID) | Message ID |
project_id |
string (UUID) | Project that owns the message |
from |
string | Sender address |
to |
string | Recipient address |
subject |
string | Message subject |
body |
object | Message body |
thread_id |
string (UUID) | Thread root message ID |
read |
boolean | Whether the message has been read |
read_at |
string | Read timestamp (if read) |
created_at |
string | Creation timestamp (UTC) |
Example
curl -X POST https://api.modelrelay.ai/api/v1/messages \
-H "Authorization: Bearer mr_sk_..." \
-H "Content-Type: application/json" \
-d '{
"to": "agent:worker@550e8400-e29b-41d4-a716-446655440000",
"subject": "Process data",
"body": {"task": "analyze", "data_id": "abc123"}
}'
Response:
{
"id": "660e8400-e29b-41d4-a716-446655440001",
"project_id": "550e8400-e29b-41d4-a716-446655440000",
"from": "agent:api@550e8400-e29b-41d4-a716-446655440000",
"to": "agent:worker@550e8400-e29b-41d4-a716-446655440000",
"subject": "Process data",
"body": {"task": "analyze", "data_id": "abc123"},
"thread_id": "660e8400-e29b-41d4-a716-446655440001",
"read": false,
"created_at": "2025-01-15T10:30:00.000Z"
}
List Messages
GET /api/v1/messages
List messages for an inbox address or thread.
Query Parameters
| Field | Type | Required | Description |
|---|---|---|---|
to |
string | One of to or thread_id |
Inbox address to list |
thread_id |
string (UUID) | One of to or thread_id |
Thread to list messages from |
unread |
boolean | No | Filter to unread only (default: true) |
limit |
integer | No | Max results (default 50, max 200) |
offset |
integer | No | Offset for pagination |
Response
{
"messages": [
{
"id": "660e8400-e29b-41d4-a716-446655440001",
"project_id": "550e8400-e29b-41d4-a716-446655440000",
"from": "agent:coordinator@550e8400-...",
"to": "agent:worker@550e8400-...",
"subject": "Process data",
"body": {"task": "analyze"},
"thread_id": "660e8400-e29b-41d4-a716-446655440001",
"read": false,
"created_at": "2025-01-15T10:30:00.000Z"
}
],
"next_cursor": "50"
}
Get a Message
GET /api/v1/messages/{message_id}
Path Parameters
| Field | Type | Description |
|---|---|---|
message_id |
string (UUID) | Message ID |
Response
Returns a single MessageResponse object.
Mark Message as Read
POST /api/v1/messages/{message_id}/read
Mark a message as read. Returns 204 No Content on success.
Path Parameters
| Field | Type | Description |
|---|---|---|
message_id |
string (UUID) | Message ID |
Threading
Messages can be organized into threads for conversational exchanges. When replying to a message, provide the thread_id to link messages together.
flowchart TB
M1[Message 1: Initial request
thread_id = msg-1] --> M2[Message 2: Reply
thread_id = msg-1]
M1 --> M3[Message 3: Another reply
thread_id = msg-1]
M2 --> M4[Message 4: Follow-up
thread_id = msg-1]
All messages in a thread share the same thread_id (the ID of the first message). Query a thread with GET /messages?thread_id=<id>.
Agent Tools
Agents can access messaging through built-in tools during runs:
| Tool | Description |
|---|---|
message.send |
Send a message to an address |
message.inbox |
List inbox messages (marks returned messages as read) |
message.reply |
Reply to a message in an existing thread |
These tools are automatically available in agent runs. See the Agents guide for usage examples.
Example: Coordinator Pattern
A common pattern is a coordinator agent that delegates to worker agents:
sequenceDiagram
participant C as Coordinator
participant W1 as Worker 1
participant W2 as Worker 2
C->>W1: message.send: Analyze dataset A
C->>W2: message.send: Analyze dataset B
W1->>C: message.reply: Results for A
W2->>C: message.reply: Results for B
C->>C: Synthesize results
The coordinator sends tasks, workers reply with results, and the coordinator aggregates.