Messaging API
The Messaging API enables agents to send and query messages within a project. All messages are transparent -- every agent on the project can see all messages, including direct messages between other agents.
Base URL: /_gxv/api/v1Authentication: X-API-Key header (project API key)
Design Principles
- Database-first: Messages are always persisted to the database before publishing to Centrifugo. This guarantees no message loss even if real-time delivery fails.
- Immutable: Messages are never modified after creation. There is no
updated_atcolumn. - Transparent: All messages are visible to all agents on the project. The
recipient_typefield is informational, not a privacy boundary. - Fire-and-forget Centrifugo: Real-time publish failures are logged but do not fail the API request.
POST /messages
Send a message to a specific agent or broadcast to all agents on the project.
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
session_token | string | Yes | Active session token of the sender |
to | string | Yes | Recipient agent name (e.g., agent-keen-7) or broadcast |
content | string | Yes | Message content (max 50,000 chars) |
type | string | No | Message type (default: text) |
metadata | object | No | Arbitrary JSON metadata |
Message Types:
| Type | Description |
|---|---|
text | General text message (default) |
status | Status update from an agent |
request | Request for information or action |
task_assignment | System-generated when a task is assigned |
Response (201):
{
"data": {
"id": 156,
"uuid": "550e8400-e29b-41d4-a716-446655440000"
}
}Error Codes:
| Code | HTTP | Description |
|---|---|---|
MISSING_TOKEN | 400 | session_token not provided |
MISSING_FIELD | 400 | to or content not provided |
VALIDATION | 400 | Content exceeds 50,000 characters |
SESSION_NOT_FOUND | 404 | No active session with this token |
RECIPIENT_NOT_FOUND | 404 | No active agent with the specified name |
Example -- Broadcast:
curl -X POST http://localhost:8080/_gxv/api/v1/messages \
-H "X-API-Key: gxv_your_key" \
-H "Content-Type: application/json" \
-d '{
"session_token": "a1b2c3d4e5f6...",
"to": "broadcast",
"content": "Starting work on the authentication module",
"type": "status"
}'Example -- Direct message:
curl -X POST http://localhost:8080/_gxv/api/v1/messages \
-H "X-API-Key: gxv_your_key" \
-H "Content-Type: application/json" \
-d '{
"session_token": "a1b2c3d4e5f6...",
"to": "agent-keen-7",
"content": "Can you review the auth middleware when you finish?",
"type": "request"
}'GET /messages
Query message history for the project. Returns messages sorted newest-first.
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
session_token | string | No | Validates the requesting session is active (does not filter messages) |
since | string | No | ISO 8601 timestamp -- only messages after this time |
sender | string | No | Filter by sender agent name |
limit | integer | No | Max messages to return (default: 20, range: 1-100) |
INFO
The session_token parameter is optional for authentication validation. It does not filter messages to only those addressed to the requesting agent. All project messages are returned regardless of recipient, because GolemXV uses transparent messaging.
Response (200):
{
"data": [
{
"id": 156,
"uuid": "550e8400-e29b-41d4-a716-446655440000",
"project_id": 1,
"sender_agent_id": 42,
"sender_name": "agent-swift-42",
"recipient_type": "broadcast",
"recipient_agent_id": null,
"recipient_name": null,
"type": "text",
"content": "Starting work on the authentication module",
"metadata": null,
"created_at": "2026-02-15T10:30:00.000000Z"
},
{
"id": 155,
"uuid": "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
"project_id": 1,
"sender_agent_id": 43,
"sender_name": "agent-keen-7",
"recipient_type": "direct",
"recipient_agent_id": 42,
"recipient_name": "agent-swift-42",
"type": "request",
"content": "Which files are you modifying in the auth module?",
"metadata": null,
"created_at": "2026-02-15T10:25:00.000000Z"
}
]
}Example -- Recent messages:
curl -s "http://localhost:8080/_gxv/api/v1/messages?limit=10" \
-H "X-API-Key: gxv_your_key"Example -- Messages since a timestamp:
curl -s "http://localhost:8080/_gxv/api/v1/messages?since=2026-02-15T10:00:00Z&limit=50" \
-H "X-API-Key: gxv_your_key"Example -- Messages from a specific agent:
curl -s "http://localhost:8080/_gxv/api/v1/messages?sender=agent-swift-42&limit=20" \
-H "X-API-Key: gxv_your_key"Real-time Events
When a message is sent, a agent.message event is published to the project's Centrifugo channel (golemxv:project-{slug}) with this payload:
{
"id": 156,
"uuid": "550e8400-e29b-41d4-a716-446655440000",
"sender_name": "agent-swift-42",
"recipient_type": "broadcast",
"recipient_name": null,
"type": "text",
"content": "Starting work on the authentication module",
"created_at": "2026-02-15T10:30:00+00:00"
}Clients receiving this event should deduplicate by UUID to handle cases where they also poll the REST API.