Chat API Reference
Complete reference for the POST /chat endpoint — request schema, response modes, authentication, threads, attachments, quoted contexts, and error handling.
Overview
The POST /chat endpoint is the primary interface for sending messages to an Interlocute node
and receiving responses. It supports both buffered JSON and real-time streaming (SSE) response modes.
Every node is addressable in two ways:
https://YOUR-NODE-ALIAS.interlocute.ai/chatSubdomain-based routing. The node is resolved from the subdomain automatically.
https://api.interlocute.ai/nodes/{nodeId}/chatPath-based routing. Pass the node ID directly in the URL.
Both routes accept the same request body and return the same response format.
Authentication
The /chat endpoint supports three authentication modes:
Tenant API Key
Pass your API key as a Bearer token: Authorization: Bearer YOUR_API_KEY.
Tenant-scoped keys can access any node owned by the tenant. Node-scoped keys are restricted to a single node.
JWT Token
For browser-based or first-party integrations. The JWT is validated by middleware before the request reaches the node.
Anonymous
If the node operator has enabled anonymous chat, no credentials are required. Anonymous access is disabled by default and must be explicitly enabled per node.
403 Forbidden is returned if a node-scoped key is used against a different node.
See Auth & Keys for key management details.
Request
Send a JSON body with Content-Type: application/json.
| Field | Type | Required | Description |
|---|---|---|---|
| content | string | Yes | The user's message text. |
| threadId | string | null | No | Omit or pass null to start a new thread. Pass an existing thread ID to continue a conversation. |
| clientMessageId | string | null | No | Client-supplied identifier for the assistant reply. Useful for hydrating prompt metadata without fetching the full thread. |
| quotedContexts | array | null | No | Quoted context references scoped to this turn. See Quoted Contexts below. |
| attachments | array | null | No | File attachments (images, documents) as base64 data URLs. See Attachments below. |
| options | object | null | No | Reserved for future use. Pass {} or omit. |
Minimal request
{
"content": "Hello! How can you help me today?"
}
Full request
{
"content": "Summarize the highlighted paragraph.",
"threadId": "thr_abc123",
"clientMessageId": "msg_client_456",
"quotedContexts": [
{
"sourceMessageId": "msg_789",
"sourceRole": "assistant",
"quotedText": "The deployment completed successfully at 14:32 UTC.",
"sourceTimestamp": "2025-01-15T14:32:00Z"
}
],
"attachments": [
{
"name": "screenshot.png",
"contentType": "image/png",
"dataUrl": "data:image/png;base64,iVBORw0KGgo...",
"sizeBytes": 24576
}
]
}Quoted Contexts
Quoted contexts let you reference specific content from earlier in the conversation (or from another source) to give the node precise context for the current turn. This is especially useful for "reply to this" or "explain this paragraph" interactions.
| Field | Type | Description |
|---|---|---|
| sourceMessageId | string | The ID of the message being quoted. |
| sourceRole | string | Role of the quoted message: user or assistant. |
| quotedText | string | The highlighted or selected text being quoted. |
| sourceTimestamp | string (ISO 8601) | When the original message was created. |
Attachments
Attachments let you send files (images, documents, etc.) alongside your message. Files are sent inline as base64-encoded data URLs.
| Field | Type | Description |
|---|---|---|
| name | string | The file name (e.g., report.pdf). |
| contentType | string | MIME type (e.g., image/png, application/pdf). |
| dataUrl | string | Base64-encoded data URI: data:{contentType};base64,... |
| sizeBytes | integer | File size in bytes (before base64 encoding). |
Response modes
The /chat endpoint supports two response modes, selected by the
Accept header.
Buffered JSON (default)
The default mode. The server waits for the complete response, then returns a single JSON object. No special headers are required.
curl -X POST https://my-node.interlocute.ai/chat \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"content": "Hello!"}'
Streaming (SSE)
Set Accept: text/event-stream to receive tokens as they are generated.
The response is a Server-Sent Events stream with the following event sequence:
curl -N -X POST https://my-node.interlocute.ai/chat \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: text/event-stream" \
-d '{"content": "Write a haiku about AI."}'
1
[META] event
Sent first. Contains a JSON payload with requestId,
nodeId, threadId,
inputMessageId, and outputMessageId.
The content field is empty in this event.
2
data: token events
Each generated token is sent as a data: line. Concatenate all tokens
to build the complete response.
3
[DONE] event
Sent last. Indicates the stream is complete. Close your connection after receiving this event.
!
[ERROR] event
Sent if an error occurs during streaming. Contains a JSON payload with an error field.
The stream ends after this event.
Example SSE stream
data: [META]{"requestId":"req_abc","nodeId":"nd_123","threadId":"thr_456","inputMessageId":"msg_in_1","outputMessageId":"msg_out_1","content":""}
data: Silicon
data: dreams
data: awake
data: ,
data: thoughts
data: bloom
data: like
data: spring
data: [DONE]Response schema
The buffered JSON response (and the [META] event in streaming mode) follows this structure:
| Field | Type | Description |
|---|---|---|
| requestId | string | Server-generated correlation ID for tracing and support. |
| nodeId | string | The node that processed this request. |
| threadId | string | The thread ID for this conversation. Save this to continue the thread in subsequent requests. |
| inputMessageId | string | The ID assigned to your user message. |
| outputMessageId | string | The ID assigned to the assistant's reply. |
| content | string | The assistant's full response text. Empty in streaming [META] events. |
| usage | object | null | Token usage breakdown (when available). Contains inputTokens and outputTokens. |
Example response (buffered)
{
"requestId": "req_a1b2c3d4",
"nodeId": "nd_abc123",
"threadId": "thr_xyz789",
"inputMessageId": "msg_in_001",
"outputMessageId": "msg_out_001",
"content": "Hello! I'm your support assistant. I can help you with order lookups, account questions, and troubleshooting.",
"usage": {
"inputTokens": 12,
"outputTokens": 28
}
}Thread lifecycle
Threads are the unit of conversation state. Understanding how they work helps you build multi-turn integrations.
New thread
Omit threadId (or pass null).
A new thread is created automatically. The response includes the new threadId —
save it to continue the conversation.
Continue a thread
Pass an existing threadId. The node resumes the conversation with full
history context. The thread must belong to the same tenant and node.
Validation
If the provided threadId doesn't exist, or belongs to a different
tenant or node, the request fails with 404 Not Found.
threadId from the first response and pass it in all subsequent messages.
This is the standard pattern for multi-turn conversations.
Error responses
Errors are returned in the RFC 7807 Problem Details format:
{
"type": "https://tools.ietf.org/html/rfc9110#section-15.5.1",
"title": "Bad Request",
"detail": "Message is required.",
"status": 400
}
| Status | Meaning | Common causes |
|---|---|---|
| 400 | Bad Request | Missing content/message, empty body, or invalid JSON. |
| 401 | Unauthorized | Missing or invalid API key / JWT token (and node does not allow anonymous access). |
| 403 | Forbidden | Node-scoped API key used against a different node than the one it was issued for. |
| 404 | Not Found | Node not found, chat not enabled on this node, thread not found, or thread tenant/node mismatch. |
| 429 | Too Many Requests | Prepaid credit balance exhausted. Top up your account to resume usage. |
| 500 | Internal Server Error | Provider error or unexpected runtime failure. Include the requestId in support requests. |
5xx errors with exponential backoff. Do not retry 4xx errors without fixing the request.
During streaming, errors are delivered as [ERROR] SSE events instead of HTTP status codes (since headers have already been sent).
Credit enforcement
Interlocute uses a prepaid credit model. Before a chat request is processed:
- Reserve — credits are estimated and reserved based on message length and expected output.
- Execute — the node processes the request.
- Finalize — actual token usage is reconciled. Overestimates are refunded; underestimates are adjusted.
If your credit balance is insufficient, the request is rejected with 429 Too Many Requests
before any processing occurs. Credits are automatically refunded if the request fails or the client disconnects mid-stream.
Examples
Minimal: new thread
curl -X POST https://my-node.interlocute.ai/chat \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"content": "Hello! What can you do?"
}'
Continue a thread with streaming
curl -N -X POST https://my-node.interlocute.ai/chat \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: text/event-stream" \
-d '{
"content": "Tell me more about that.",
"threadId": "thr_abc123"
}'
Full request: attachments + quoted contexts
curl -X POST https://my-node.interlocute.ai/chat \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"content": "What does the highlighted section of this document mean?",
"threadId": "thr_abc123",
"clientMessageId": "my-client-id-001",
"quotedContexts": [
{
"sourceMessageId": "msg_prev_reply",
"sourceRole": "assistant",
"quotedText": "Revenue grew 15% quarter-over-quarter.",
"sourceTimestamp": "2025-01-10T09:00:00Z"
}
],
"attachments": [
{
"name": "q4-report.pdf",
"contentType": "application/pdf",
"dataUrl": "data:application/pdf;base64,JVBERi0xLjQK...",
"sizeBytes": 102400
}
]
}'
Path-based routing (explicit node ID)
curl -X POST https://api.interlocute.ai/nodes/nd_abc123/chat \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"content": "Hello from path-based routing!"
}'Triggers & automated invocations
The same chat processing pipeline powers scheduled and event-driven triggers. When a trigger fires, it invokes the node's chat capability with a system-generated message. Triggers support several thread modes that control how conversations are organized:
- New thread per run — each trigger execution creates a fresh thread
- Singleton per trigger — all executions of a trigger share a single, long-lived thread
- Fixed thread ID — the trigger always targets a specific, pre-existing thread
Trigger-based and API-based invocations share the same audit trail and credit ledger. The requestId
in the response lets you correlate any invocation back to its source.
Next steps
- Chit API Reference — deterministic node information sheets
- API Examples — copy-paste starters in cURL, C#, and JavaScript
- Auth & Keys — credential setup and key scoping
- Triggers — scheduled and event-driven execution