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"
}'

Try it

Fill in the fields, send the request from your browser, and read the live response. The curl below updates as you type.

Kept in this browser tab only and cleared when it closes.

cURL for this request
curl --request POST \
  --url 'https://recoup-api.vercel.app/api/chat' \
  --header 'Content-Type: application/json' \
  --data '{
  "messages": [
    {
      "id": "string",
      "role": "user",
      "content": "string"
    }
  ],
  "chatId": "YOUR_ID",
  "sessionId": "YOUR_ID"
}'

Run this one from the terminal with the curl above.

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"
          }
        }
      }
    }
  }
}