Chats
Chats are conversations between a user and an agent. Messages stream in real time via WebSocket — see WebSocket for the streaming protocol.
List chats
GET /api/chats
Authorization: Bearer nxr_...Query params:
| Param | Type | Description |
|---|---|---|
agent_id | uuid? | Filter to chats using a specific agent |
The endpoint returns the caller’s chats plus shared chats in the active org’s projects, ordered by updated_at descending. It is not paginated.
Get chat
GET /api/chats/{chat_id}
Authorization: Bearer nxr_...Create chat
POST /api/chats
Authorization: Bearer nxr_...
Content-Type: application/json
{
"title": "Deploy review",
"agent_id": "uuid",
"project_id": "uuid-optional"
}agent_id is required. title defaults to "New Chat" if omitted.
Update chat title
There is no generic PATCH /api/chats/{chat_id} endpoint. To rename a chat, use the dedicated
title endpoint:
PATCH /api/chats/{chat_id}/title
Authorization: Bearer nxr_...
Content-Type: application/json
{ "title": "New title" }Other chat properties have their own endpoints: PATCH /api/chats/{chat_id}/provider-chain
and PATCH /api/chats/{chat_id}/webhook.
Delete chat
DELETE /api/chats/{chat_id}
Authorization: Bearer nxr_...Soft-delete (204 No Content). Restore with:
PATCH /api/chats/{chat_id}/restore
Authorization: Bearer nxr_...Messages
List messages
GET /api/chats/{chat_id}/messages
Authorization: Bearer nxr_...Query params:
| Param | Type | Description |
|---|---|---|
limit | int | Max to return (default: 100, max: 500) |
offset | int | Number of messages to skip (default: 0) |
Messages are returned oldest-first (ordered by created_at).
Send message
There is no REST endpoint for sending a message. Send messages over the WebSocket connection (message frame) or via the SSE streaming endpoint POST /api/chats/{chat_id}/stream (see below). Both accept a client_message_id for deduplication — safe to retry on network error.
Exclude message from context
Toggle whether a message is included in the agent’s context window:
PATCH /api/chats/{chat_id}/messages/{message_id}/excluded
Authorization: Bearer nxr_...
Content-Type: application/json
{ "excluded": true }Message schema
{
"id": "uuid",
"role": "user | assistant",
"content": "Message text",
"metadata_": {},
"provider_used": "OpenAI – Production",
"agent_id": "uuid",
"agent_name": "Research Assistant",
"user_id": "uuid",
"user_name": "Jane Doe",
"excluded": false,
"created_at": "2026-01-01T00:00:00Z"
}Tool calls and results are recorded in the metadata_ object (e.g. tool_call_count, tool_calls_detail) rather than as top-level fields.
Files
Attach files to a chat for the agent to reference.
Upload file
POST /api/chats/{chat_id}/files
Authorization: Bearer nxr_...
Content-Type: multipart/form-data
file=@/path/to/file.pdfList files
GET /api/chats/{chat_id}/files
Authorization: Bearer nxr_...Download file
GET /api/chats/{chat_id}/files/{file_id}/content
Authorization: Bearer nxr_...Delete file
DELETE /api/chats/{chat_id}/files/{file_id}
Authorization: Bearer nxr_...Search
Full-text search across the messages of all chats accessible to the caller:
GET /api/chats/search?q=deployment+error
Authorization: Bearer nxr_...Query params:
| Param | Type | Description |
|---|---|---|
q | string | Search query (minimum 2 characters) |
page | int | Page number (default: 1) |
per_page | int | Results per page (default: 10, max: 50) |
Returns { "results": [...], "total": <int>, "query": "<q>" }. Each result carries
chat_id, chat_title, message_id, excerpt, role, and created_at.
For streaming responses you have two options. Connect to the WebSocket endpoint, or use the WebSocket-free SSE streaming endpoint POST /api/chats/{chat_id}/stream, which returns a text/event-stream response. The SSE stream emits stream_start, chunk, tool_call, stream_end, and error events as the agent generates its reply (stream_end is the terminal event and carries the saved message). There is no REST send-message endpoint — generation is triggered either over the WebSocket or via this SSE endpoint.