interlocute.ai beta

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:

POST https://YOUR-NODE-ALIAS.interlocute.ai/chat

Subdomain-based routing. The node is resolved from the subdomain automatically.

POST https://api.interlocute.ai/nodes/{nodeId}/chat

Path-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.

Node-scoped API keys add a layer of isolation: even if a key is compromised, it can only access the single node it was issued for. A 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.
Quoted contexts require the node's prompt configuration to include quoted context support. If the node does not have this capability enabled, the quoted contexts are accepted but may not influence the response.

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).
Attachments are transmitted inline. Keep file sizes reasonable — large files increase request latency and may hit request body limits. Supported file types depend on the underlying model's capabilities.

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.

Store the 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.
Retry on 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:

  1. Reserve — credits are estimated and reserved based on message length and expected output.
  2. Execute — the node processes the request.
  3. 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