RecoupGet a Free AuditFree Audit

API REFERENCE

Stream Chat

On this page
POST/api/chat

Streams an agent loop running as a durable Vercel Workflow against the session's sandbox. The agent uses sandbox-only tools (bash, read, write, grep, glob, todo, task, ask_user_question, skill, fetch) — no MCP or Composio. Requires a sandbox provisioned via POST /api/sandbox.

Related endpoints - POST /api/chat/runs — the headless counterpart: it provisions its own session + sandbox and runs without a streaming client. Use that for tasks/cron/programmatic runs; use this for interactive, streaming turns on an existing chat. - GET /api/chat/{chatId}/stream — reconnect to an in-progress response. - GET /api/chat/runs/{runId} — check whether a headless run finished (status, not content).

Authentication

x-api-key in header

Request

cURL
curl --request POST \
  --url 'https://api.recoupable.dev/api/chat' \
  --header 'x-api-key: YOUR_API_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
  "messages": [
    {
      "id": "string",
      "role": "user",
      "content": "string"
    }
  ],
  "chatId": "YOUR_ID",
  "sessionId": "YOUR_ID"
}'

Request body required

Chat workflow request

application/json

messagesarray<UIMessage>required

Conversation history as an array of UIMessage objects, matching the Vercel AI SDK UIMessage shape. The last entry is typically the new user turn — the agent loop reads the entire array and persists the latest user message before the workflow starts.

Item properties for messages
idstring

Unique identifier for the message

rolestring · enum

The role of the message sender

Values: "user", "assistant", "system"

contentstring

The text content of the message

chatIdstringrequired

UUID of an existing chat under sessionId. The chat's active_stream_id column is used for compare-and-set race control across concurrent requests.

format: uuid

sessionIdstringrequired

UUID of the session that owns both the chat and the sandbox. The session must have a non-null sandbox_state — call POST /api/sandbox first if not.

format: uuid

contextobject

Optional per-prompt context overrides forwarded into the agent loop.

Properties for context
contextLimitinteger

Upper bound on the number of tokens / messages of conversation history the agent should consider for this prompt. Overrides the model's default for this call only.

Responses

200Server-Sent Events stream of UI message parts compatible with the Vercel AI SDK createUIMessageStreamResponse. The x-workflow-run-id response header carries the durable workflow run ID for resume/stop operations.
x-workflow-run-idresponse header

Durable workflow run ID. Persist alongside the chat so a later GET /api/chat/{chatId}/stream request can resume this run after a disconnect.

text/event-stream

string

400Bad request — missing required fields, invalid body, or sandbox not initialized for the session.

application/json

statusstring · enumrequired

Status of the request

Values: "error"

errorstringrequired

Error message describing what went wrong

missing_fieldsarray<string>

Present on validation failures (400): the path of the field that failed. Empty for a malformed path parameter.

Item properties for missing_fields

string

401Missing or invalid API key.

application/json

statusstring · enumrequired

Status of the request

Values: "error"

errorstringrequired

Error message describing what went wrong

missing_fieldsarray<string>

Present on validation failures (400): the path of the field that failed. Empty for a malformed path parameter.

Item properties for missing_fields

string

403The API key's account does not own the referenced sessionId or chatId.

application/json

statusstring · enumrequired

Status of the request

Values: "error"

errorstringrequired

Error message describing what went wrong

missing_fieldsarray<string>

Present on validation failures (400): the path of the field that failed. Empty for a malformed path parameter.

Item properties for missing_fields

string

404Session or chat not found.

application/json

statusstring · enumrequired

Status of the request

Values: "error"

errorstringrequired

Error message describing what went wrong

missing_fieldsarray<string>

Present on validation failures (400): the path of the field that failed. Empty for a malformed path parameter.

Item properties for missing_fields

string

409A response is already streaming for this chat. Reconnect to it via GET /api/chat/{chatId}/stream instead of POSTing again.

application/json

statusstring · enumrequired

Status of the request

Values: "error"

errorstringrequired

Error message describing what went wrong

missing_fieldsarray<string>

Present on validation failures (400): the path of the field that failed. Empty for a malformed path parameter.

Item properties for missing_fields

string

Full specification

Download the OpenAPI file for complete schemas, constraints, and examples.

Download research.json
View operation source
json
{
  "summary": "Stream sandbox-driven chat (Vercel Workflow)",
  "description": "Streams an agent loop running as a durable [Vercel Workflow](https://vercel.com/docs/workflow) against the session's sandbox. The agent uses sandbox-only tools (`bash`, `read`, `write`, `grep`, `glob`, `todo`, `task`, `ask_user_question`, `skill`, `fetch`) — no MCP or Composio. Requires a sandbox provisioned via [`POST /api/sandbox`](/api-reference/sandbox/create).\n\n**Related endpoints**\n- [`POST /api/chat/runs`](/api-reference/chat/runs) — the **headless** counterpart: it provisions its own session + sandbox and runs without a streaming client. Use that for tasks/cron/programmatic runs; use this for **interactive, streaming** turns on an existing chat.\n- [`GET /api/chat/{chatId}/stream`](/api-reference/chat/workflow-stream) — reconnect to an in-progress response.\n- [`GET /api/chat/runs/{runId}`](/api-reference/chat/runs-status) — check **whether** a headless run finished (status, not content).",
  "security": [
    {
      "apiKeyAuth": []
    }
  ],
  "requestBody": {
    "description": "Chat workflow request",
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/ChatWorkflowRequest"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Server-Sent Events stream of UI message parts compatible with the Vercel AI SDK `createUIMessageStreamResponse`. The `x-workflow-run-id` response header carries the durable workflow run ID for resume/stop operations.",
      "headers": {
        "x-workflow-run-id": {
          "description": "Durable workflow run ID. Persist alongside the chat so a later `GET /api/chat/{chatId}/stream` request can resume this run after a disconnect.",
          "schema": {
            "type": "string"
          }
        }
      },
      "content": {
        "text/event-stream": {
          "schema": {
            "type": "string",
            "description": "Server-Sent Events stream containing UI message parts"
          }
        }
      }
    },
    "400": {
      "description": "Bad request — missing required fields, invalid body, or sandbox not initialized for the session.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ChatStreamErrorResponse"
          }
        }
      }
    },
    "401": {
      "description": "Missing or invalid API key.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ChatStreamErrorResponse"
          }
        }
      }
    },
    "403": {
      "description": "The API key's account does not own the referenced `sessionId` or `chatId`.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ChatStreamErrorResponse"
          }
        }
      }
    },
    "404": {
      "description": "Session or chat not found.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ChatStreamErrorResponse"
          }
        }
      }
    },
    "409": {
      "description": "A response is already streaming for this chat. Reconnect to it via `GET /api/chat/{chatId}/stream` instead of POSTing again.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ChatStreamErrorResponse"
          }
        }
      }
    }
  }
}