Skip to main content
POST
Append a user message + enqueue a chat turn

Authorizations

Authorization
string
header
required

Authorization: Bearer <token> where <token> is either a neo_sk_<env>_<secret> API key (service account) or a Microsoft Entra ID access token (dashboard user).

Path Parameters

session_id
string
required

Body

application/json
attachments
PublicChatAttachment · object[]

Images or documents to include with this turn. Each must first be uploaded via POST /chat/sessions/<id>/attachments/upload-url. At most 6 per turn.

client_capabilities
string[]

Interactive stream parts this client renders. Supported values: 'user-questions' — declare it only when you render the data-user-questions part as tappable answers, including each question's multi_select flag (tick several, then send them as one message with one pick per line — never comma-joined, because a pick can itself contain a comma) and a payload of several questions (each question's text on its own line, then its picked values one per line after '- '). 'suggested-replies' — the older event, which carries one question and rides beside the new one for every single-question payload; declare it when you render data-suggested-replies alone, and the agent keeps naming the options in its text whenever it asks several questions at once, which that event cannot carry. Declaring either stops the agent naming the options for a payload you can draw. Omit both (the default) to keep every question fully readable as plain text.

client_message_id
string | null
message
string
default:""
model_tier
enum<string>
default:FAST

Speed/quality tier for this turn (ENG-5851): FAST keeps the agent's configured model; SMART escalates a single turn to a stronger model. May be flipped per turn to switch mid-conversation. Defaults to FAST.

Available options:
FAST,
SMART

Response

Success.

data
PostMessageResponse · object
required

202 Accepted body — the turn is enqueued, the agent's response streams via SSE.

since_cursor is the Redis-stream event id snapshotted right before this turn was enqueued. Callers tailing /chat/sessions/<id>/events should pass it as ?since=<since_cursor> (or Last-Event-Id: <since_cursor>) so the SSE tail starts strictly after the previous turn's terminal envelopes. Skipping this on a 2nd+ turn against the same session causes the tail to return the previous turn's final state. May be None on the first turn of a fresh session or under Redis failure; consumers treat None as "tail from beginning."

meta
object
required