# Send Chat Message

`POST /api/v1/chat`

## Description
Send one message to Chat and wait for the complete reply. Chat runs with a workflow as context and can call its tools (edit blocks, read logs, query tables, and so on) on behalf of the API key's user.

The request is synchronous: the response arrives once the turn finishes, which can take minutes for multi-step work. Pass the returned `chatId` on the next request to continue the same conversation.

For a new chat, if `workflowId` is omitted, Chat uses the workflow named by `workflowName`, or else the user's first workflow. When continuing with `chatId`, Chat keeps that conversation's workflow and history; you do not need to repeat the workflow. An explicit workflow must match the chat's workflow. Chats without an attached workflow cannot be continued through this endpoint.

Chat acts with the key owner's full access, so this endpoint needs an unrestricted personal API key with write access to the target workflow, in a workspace that allows personal API keys. Scoped, workspace and organization keys are rejected with `403` for now.

Requests count against the same v1 API request limit as the workflows, logs, and audit logs endpoints.

`/api/v1/copilot/chat` is a compatibility alias for this endpoint and accepts the same request.

## Request Body

```json
{
  "type": "object",
  "required": [
    "message"
  ],
  "properties": {
    "message": {
      "type": "string",
      "minLength": 1,
      "description": "The message to send to Chat."
    },
    "workflowId": {
      "type": "string",
      "description": "The workflow Chat uses as context. Takes precedence over `workflowName`. When continuing a chat, it must match the stored workflow."
    },
    "workflowName": {
      "type": "string",
      "description": "Name of the workflow to use as context when `workflowId` is omitted."
    },
    "chatId": {
      "type": "string",
      "description": "An existing workflow chat to continue with its stored workflow and message history. Omit to start a new chat. Unknown or inaccessible IDs return 404; this field cannot create a chat with a caller-supplied ID."
    },
    "model": {
      "type": "string",
      "description": "Model ID for this turn. Defaults to the platform's default Chat model."
    },
    "autoExecuteTools": {
      "type": "boolean",
      "default": true,
      "description": "Whether Chat runs its tools during the turn. When false, tool calls are returned without running."
    },
    "timeout": {
      "type": "number",
      "default": 3600000,
      "description": "Maximum time for the turn, in milliseconds. The server stops waiting after one hour regardless."
    },
    "mode": {
      "type": "string",
      "enum": [
        "ask",
        "build",
        "plan",
        "agent"
      ],
      "default": "agent",
      "deprecated": true,
      "description": "Accepted for compatibility and ignored."
    }
  }
}
```

## Responses

### 200 — The finished turn. `success` is false when the turn ran but failed; `error` then says why.

```json
{
  "type": "object",
  "required": [
    "success",
    "content",
    "toolCalls",
    "chatId"
  ],
  "properties": {
    "success": {
      "type": "boolean",
      "description": "Whether the turn completed without error."
    },
    "content": {
      "type": "string",
      "description": "Chat's text reply."
    },
    "toolCalls": {
      "type": "array",
      "description": "Tools Chat called during the turn, in order.",
      "items": {
        "type": "object",
        "required": [
          "id",
          "name",
          "status"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Tool call ID."
          },
          "name": {
            "type": "string",
            "description": "Tool name."
          },
          "status": {
            "type": "string",
            "enum": [
              "success",
              "error",
              "pending"
            ],
            "description": "`pending` means the tool was not run, for example when `autoExecuteTools` is false."
          },
          "params": {
            "type": "object",
            "additionalProperties": true,
            "description": "Arguments Chat passed to the tool."
          },
          "result": {
            "description": "What the tool returned."
          },
          "error": {
            "type": "string",
            "description": "Why the tool call failed."
          },
          "durationMs": {
            "type": "number",
            "description": "How long the tool took, in milliseconds."
          }
        }
      }
    },
    "chatId": {
      "type": "string",
      "description": "The chat this turn belongs to. Pass it as `chatId` to continue the conversation."
    },
    "error": {
      "type": "string",
      "description": "Why the turn failed, when `success` is false."
    }
  }
}
```

### 400 — Invalid request body, no workflow is available, the requested workflow differs from the chat, or the chat has no attached workflow.

```json
{
  "type": "object",
  "required": [
    "success",
    "error"
  ],
  "properties": {
    "success": {
      "type": "boolean",
      "enum": [
        false
      ]
    },
    "error": {
      "type": "string",
      "description": "Human-readable error message."
    },
    "details": {
      "type": "array",
      "items": {
        "type": "object"
      },
      "description": "Field-level validation errors, on `400` responses."
    }
  }
}
```

### 401 — Missing or invalid API key.

```json
{
  "type": "object",
  "required": [
    "success",
    "error"
  ],
  "properties": {
    "success": {
      "type": "boolean",
      "enum": [
        false
      ]
    },
    "error": {
      "type": "string",
      "description": "Human-readable error message."
    },
    "details": {
      "type": "array",
      "items": {
        "type": "object"
      },
      "description": "Field-level validation errors, on `400` responses."
    }
  }
}
```

### 403 — The API key can't use Chat here: it is a scoped, workspace or organization key, or a personal key without write access to the workflow or in a workspace that disallows personal keys.

```json
{
  "type": "object",
  "required": [
    "success",
    "error"
  ],
  "properties": {
    "success": {
      "type": "boolean",
      "enum": [
        false
      ]
    },
    "error": {
      "type": "string",
      "description": "Human-readable error message."
    },
    "details": {
      "type": "array",
      "items": {
        "type": "object"
      },
      "description": "Field-level validation errors, on `400` responses."
    }
  }
}
```

### 404 — The `chatId` does not exist, is inaccessible to the API key owner, or can no longer be loaded.

```json
{
  "type": "object",
  "required": [
    "success",
    "error"
  ],
  "properties": {
    "success": {
      "type": "boolean",
      "enum": [
        false
      ]
    },
    "error": {
      "type": "string",
      "description": "Human-readable error message."
    },
    "details": {
      "type": "array",
      "items": {
        "type": "object"
      },
      "description": "Field-level validation errors, on `400` responses."
    }
  }
}
```

### 429 — Rate limit exceeded. Wait for the duration specified in the Retry-After header before retrying.

```json
{
  "type": "object",
  "properties": {
    "error": {
      "type": "string",
      "description": "Human-readable error message with rate limit details."
    }
  }
}
```

### 500 — The turn could not be run.

```json
{
  "type": "object",
  "required": [
    "success",
    "error"
  ],
  "properties": {
    "success": {
      "type": "boolean",
      "enum": [
        false
      ]
    },
    "error": {
      "type": "string",
      "description": "Human-readable error message."
    },
    "details": {
      "type": "array",
      "items": {
        "type": "object"
      },
      "description": "Field-level validation errors, on `400` responses."
    }
  }
}
```
