Conversation
Chat requests and streaming
Use authenticated video or Assistant conversations with the current NDJSON request, event and history contracts.
Choose a conversation scope
| Scope | Account endpoint | Context |
|---|---|---|
| Video chat | POST /v1/interact/llm/chat/ | videoId and authorized video context; pausedTime can identify the current playback position. |
| Standalone Assistant | POST /v1/interact/assistant/chat/ | A videoless Assistant session. Do not use a video-scoped session here. |
| Restored video chat on Assistant | POST /v1/interact/llm/chat/ | Retain the videoId and video session. pausedTime is null because no player is active. |
Session identifiers do not grant access. The backend validates session ownership and scope independently of the user-supplied ID.
Video chat and Assistant use Workflow V2 for answers, criteria, confirmation and optional browser dispatch. An informational question can finish without opening a browser.
Build an account chat request
The direct production backend base is https://api.rapideye.ai/v1/. Supply a fresh authorized user bearer token and retain the conversation’s session ID.
| Field or header | Meaning | Client guidance |
|---|---|---|
| Authorization | Bearer account access token | Resolve fresh credentials through the authenticated account session. Never use an owner cookie as a viewer token. |
| Idempotency-Key | Stable identity for this request | Keep it unchanged when retrying identical content. Use a new identity for a new turn. |
| session_id | Conversation identity | Use a UUID for a new session. Reuse an owned session for continuation. |
| messages | Array of role/content records | Include the relevant conversation and the current user message. Current clients send text content. |
| videoId | Video context | Use only on the video route, with authorized video access. |
| pausedTime | Playback position in seconds, number or null | Use the current player position for video context. Use null without an active player. |
| clientTimezone | Client timezone | Supply the client’s timezone for time-sensitive criteria. |
| linkInteractionVersion | Native workflow protocol selection | Current clients send 2. |
| completedWorkflowId | A completed task to recheck | Use an owned task from the same conversation when the application offers rechecking. |
| viewerVariantState | Request-local recolor presentation | Advanced video-client state. It is not a stored change to the source video. |
| model / agentModel / generatorProvider | Optional model requests | Production policy restricts overrides. Omit these to use deployed defaults. |
async function requestVideoChat({ accessToken, videoId, sessionId, requestId, messages, signal }) {
return fetch('https://api.rapideye.ai/v1/interact/llm/chat/', {
method: 'POST',
headers: {
Authorization: 'Bearer ' + accessToken,
'Content-Type': 'application/json',
'Idempotency-Key': requestId
},
body: JSON.stringify({
videoId, session_id: sessionId, messages,
pausedTime: null,
clientTimezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
linkInteractionVersion: 2
}),
signal
});
} Generate the session UUID once per new conversation. Generate the request UUID once per new turn. Retrying identical content retains its request UUID.
For standalone Assistant, use interact/assistant/chat/ and omit videoId and pausedTime. Keep its session separate from a video conversation.
Do not proxy the streamed answer through a buffering application route. The RapidEye client reads the backend stream directly.
Decode NDJSON across transport chunks
Successful streaming responses use application/x-ndjson. Each line is a JSON event. Network chunks can split lines or UTF-8 characters.
async function readNdjson(response, onEvent) {
if (!response.ok) throw new Error('HTTP ' + response.status);
if (!response.body) throw new Error('Missing response body');
const reader = response.body.getReader();
const decoder = new TextDecoder();
let pending = '';
try {
while (true) {
const { value, done } = await reader.read();
pending += done ? decoder.decode() : decoder.decode(value, { stream: true });
const lines = pending.split('\n');
pending = done ? '' : lines.pop();
for (const line of lines) {
if (line.trim()) onEvent(JSON.parse(line));
}
if (done) return;
}
} finally {
reader.releaseLock();
}
} | Event family | Role | Persistence |
|---|---|---|
| assistant_ack | Initial acknowledgment text in payload.text | Live response signal; not a completed browser task. |
| assistant_delta | Incremental text in payload.text | Ephemeral; do not treat deltas as replayable durable messages. |
| assistant_status | For example web_searching with active true/false | Ephemeral activity signal. |
| assistant_message | Completed message in payload.text | Native durable event when workflow coordinates are present. |
| criteria_request / confirmation_request / destination_selection_request | Next user decision or required criteria | Workflow events with their own gate semantics. |
| agent_started / agent_progress_message / agent_selection_request | Browser task lifecycle and decision state | Follow the authenticated session event stream. |
| agent_completed / agent_failed | Terminal workflow outcome | Separate from a frame, acknowledgment or request completion. |
| stream_done | The current HTTP stream finished | Does not imply an asynchronously dispatched browser task finished. |
Durable envelopes carry type, workflow_id, session_id, sequence, cursor and payload. Live signals can omit those coordinates.
Render unknown event types conservatively. Do not interpret a delta or a screenshot as a command acknowledgment or task success.
Understand video context and attachments
The answer pipeline can use authored metadata, available transcript, timestamps, detected entities and scene context. It can research missing current information when appropriate.
Authored CMS facts take precedence over conflicting external results. Nearby dialogue uses a bounded window around the player position and stays inside an authored scene.
Semantic navigation uses available video timestamps. An uncertain identity or ambiguous navigation request can require clarification instead of producing a seek.
A failed context lookup can leave fields unavailable while preserving other evidence. Model-generated identities, relevance and confidence still require review.
Upload a source video through the video workflow. Do not substitute base64 media, private credentials or an arbitrary attachment field into messages.
Continue and restore conversations
Account history separates video sessions from Assistant sessions. A restored video session retains its source video identity even when opened from Assistant.
The backend projects authoritative workflow messages into account history. Avoid a second client writer for the same transcript.
Titles can be generated or renamed. An application history label is not the conversation’s authorization or replay cursor.
HTTP and WebSocket delivery can include the same durable event. Deduplicate by conversation and cursor. Preserve the raw current user reply.
Embedded visitor history has different isolation and restoration limits. It is not an account history API or access to an owner’s messages.
Separate answer interruption from task cancellation
Aborting a chat fetch stops local stream delivery. It does not establish cancellation of a browser task already dispatched by the workflow.
The account player coordinates spoken and typed input. Voice interruption stops speech and the active answer stream. Explicit Stop owns browser task cancellation.
Account voice uses authenticated transcription and speech admission. It does not inherit an embedded experience’s Voice toggle or viewer session.