• English
  • Octop Chat API: WebSocket Streaming and Thread Management

    Octop streams agent responses over a WebSocket connection, delivering chunks in real time as the model generates them. Thread management — creating, listing, renaming, and retrieving history — uses standard REST endpoints under the same agent path. All endpoints require owner-level access to the target agent.

    WebSocket chat

    Endpoint

    WS /api/agents/{id}/chat/ws?token=<jwt>

    Pass your JWT as the token query parameter. The WebSocket connection stays open for the lifetime of a conversation session; you can send multiple turns on the same connection.

    Message frames

    Send a user turn:

    {"type": "user_turn", "content": "Hello, what can you help me with?", "thread_id": "abc123"}

    Receive streaming response chunks — the server emits one or more content frames, then terminates with a done or error frame:

    {"type": "chunk", "content": "I can help you with research, writing, "}
    {"type": "chunk", "content": "code review, and more."}
    {"type": "done"}

    On error:

    {"type": "error", "message": "Agent runtime is unavailable."}

    Keepalive ping/pong:

    // Send
    {"type": "ping"}
    
    // Receive
    {"type": "pong"}

    Resume an in-flight turn after reconnect — disconnect alone does not cancel the turn. Send subscribe to attach to a thread that is still streaming; the server replies with turn_status:

    // Send
    {"type": "subscribe", "thread_id": "abc123"}
    
    // Receive
    {"type": "turn_status", "thread_id": "abc123", "active": true}

    Stop an active turn explicitly:

    {"type": "cancel", "thread_id": "abc123"}
    NOTE

    thread_id is stable across sessions. Pass the same thread_id on every turn to keep messages in one continuous conversation. Use session_key to resume a specific thread when opening a new WebSocket connection. After a page reload, call history and check turn_active before re-subscribe.

    Thread management endpoints

    MethodPathAuthDescription
    GET/agents/{id}/chat/sessionsownerList threads
    POST/agents/{id}/chat/sessionsownerCreate thread
    PATCH/agents/{id}/chat/sessions/{thread_id}ownerRename or pin thread
    DELETE/agents/{id}/chat/sessions/{thread_id}ownerArchive thread
    GET/agents/{id}/chat/sessions/{thread_id}/historyownerPaginated message history; includes turn_active, artifacts, and knowledge citations when present
    GET/agents/{id}/history-migration/statusownerReport old chats that still need history projection
    POST/agents/{id}/history-migration/startownerQueue old chats for background history projection
    GET/agents/{id}/threads/{thread_id}/context-usageownerReturn context-window usage by segment
    POST/agents/{id}/threads/{thread_id}/readownerMark a thread as read
    POST/agents/{id}/threads/{thread_id}/forkownerFork a thread at an assistant reply
    GET/agents/{id}/threads/{thread_id}/trajectoryownerPaginated run-trajectory summaries; use before_seq for older rows
    GET/agents/{id}/threads/{thread_id}/trajectory/events/{event_id}ownerFull event payload
    GET/agents/{id}/threads/{thread_id}/trajectory/metricsownerAggregated turn, timing, and token metrics
    GET/agents/{id}/threads/{thread_id}/trajectory/streamownerLive SSE; resume with after_seq or Last-Event-ID
    GET/agents/{id}/threads/{thread_id}/trajectory/exportownerDownload the ledger as JSONL (default) or JSON
    GET/agents/{id}/chat/welcomeagent access{welcome_message, quick_prompts, task_examples}; task_examples is null when the workspace field is absent
    POST/agents/{id}/chat/hitl/resumeownerResume a paused human-in-the-loop request

    Create a thread

    Creating a thread returns a thread_id for routing turns and a session_key for resuming the thread across WebSocket reconnections.

    cURL
    Response
    cURL
    curl -X POST http://127.0.0.1:8088/api/agents/main/chat/sessions \
      -H 'Authorization: Bearer $TOKEN' \
      -H 'Content-Type: application/json' \
      -d '{}'

    Get message history

    Retrieve paginated message history for a specific thread.

    cURL
    cURL
    curl 'http://127.0.0.1:8088/api/agents/main/chat/sessions/abc123/history' \
      -H 'Authorization: Bearer $TOKEN'

    The response returns a paginated array of message objects ordered chronologically, plus turn_active (boolean). When turn_active is true, re-open the chat WebSocket and send {"type":"subscribe","thread_id":"..."} to resume streaming. Use the standard limit and offset query parameters to page through long threads.

    For older threads created before the v10 history projection, the response can include:

    FieldMeaning
    history_loadingThe projected message rows are not ready yet
    history_statuspending, queued, running, failed, or ready
    history_retry_after_msSuggested delay before polling history again

    Call POST /agents/{id}/history-migration/start to queue old chats in the background. Octop processes them one at a time per agent so new chats remain available.

    Rename or pin a thread

    Send a PATCH request with a title to rename a thread, or set pinned: true to pin it to the top of the session list.

    cURL
    cURL
    curl -X PATCH http://127.0.0.1:8088/api/agents/main/chat/sessions/abc123 \
      -H 'Authorization: Bearer $TOKEN' \
      -H 'Content-Type: application/json' \
      -d '{"title": "Q2 Research Session", "pinned": true}'

    Welcome and task examples

    GET /agents/{id}/chat/welcome returns the agent's welcome copy, quick prompts, and task_examples from the workspace .octop/manifest.json. task_examples is a {zh,en} pair of string arrays, normalized for display to 3 or 6 items. Prefer this endpoint when you also need cron empty-state examples — it includes the same field as GET /agents/{id}/cron/examples.

    Polish endpoint

    The polish endpoint accepts a single prompt and returns a refined version in one shot — useful for improving user messages before sending them to an agent.

    cURL
    cURL
    curl -X POST http://127.0.0.1:8088/api/agents/main/chat/polish \
      -H 'Authorization: Bearer $TOKEN' \
      -H 'Content-Type: application/json' \
      -d '{"text": "make this shorter: ...your text..."}'

    The response body is {"text": "...refined text..."}. You can optionally pass default_model to override the agent's default for this one call.

    Human-in-the-loop resume

    When a tool pauses for approval or asks the user a question, history includes hitl_pending. Resume the turn with an SSE request:

    curl -N -X POST http://127.0.0.1:8088/api/agents/main/chat/hitl/resume \
      -H 'Authorization: Bearer $TOKEN' \
      -H 'Content-Type: application/json' \
      -d '{
        "thread_id": "abc123",
        "decisions": [{"type": "respond", "message": "Use the staging database."}]
      }'

    Supported decision types are approve, edit, reject, and respond. Use respond for ask_user_question prompts. Send at most 16 decisions at once. respond and reject messages must be strings, and each message can be up to 8000 characters.

    Fork a thread

    POST /api/agents/{id}/threads/{thread_id}/fork copies a conversation into a new thread up to a chosen assistant reply. The original thread is unchanged. Send assistant_turns_from_end: 1 to fork from the latest reply, or pass a message_id. The agent must be running.

    Files and knowledge citations

    Thread list and history include generated files (for example after the agent writes a file or takes a desktop screenshot) and knowledge-base sources when the reply used your documents. Click a citation in the web UI to preview the document in chat.

    Run trajectory

    GET /agents/{id}/threads/{thread_id}/trajectory* exposes the same ledger as the chat trajectory drawer: paginated event summaries, a single full event, aggregated metrics, a live SSE stream, and an export. Use these when you need an audit of turns and tool calls without scraping the chat UI.

    TIP

    Use the polish endpoint in your own UI to offer a "Improve my prompt" button — it adds minimal latency and runs on the same model as the agent without persisting anything to the thread history.