---
title: "Create Sheet"
method: POST
path: "/api/v1/workflows/{workflow_id}/sheets"
tags: ["Sheets"]
---

# Create Sheet

`POST /api/v1/workflows/{workflow_id}/sheets`

## Request

- Base URL: `http://localhost:3009`
- URL: `http://localhost:3009/api/v1/workflows/{workflow_id}/sheets`
- Auth: HTTP bearer

Adds a new sheet to the workflow identified by `workflow_id`. Returns the full sheet object. Pass the returned `sheet_id` as the `{sheet_id}` path parameter on every sheet-scoped endpoint (Add Inputs, Add Action, Add Data, Run Sheet, etc.).

**Routing data into the new sheet.** Sheets receive rows via the `send_to_sheet` action on another sheet in the same workflow. On the source sheet, add `send_to_sheet`, set `target_sheet_id` to the `sheet_id` returned here, and map source fields to the new sheet's input columns. To expand a `structured_array` (one row per array item), set `expand_from` on the `send_to_sheet` action. Full configuration: `/docs/action-detail/send_to_sheet.txt`.

## Path parameters

- `workflow_id` string, required

## Request body

- CreateSheetBody: Body for Create Sheet. Only `name` is required.
  - `name` string, required: Sheet name. Not required to be unique within a workflow.
  - `auto_run` boolean: When `true` (default), the sheet's action chain runs automatically whenever new data rows arrive — via Add Data Rows or via a `send_to_sheet` action on another sheet. When `false`, runs must be triggered explicitly with Run Rows.
  - `cache_enabled` boolean: When `true` (default), a row with input column values identical to a previously-run row reuses the previous row's outputs instead of re-running the action chain. Set to `false` to always re-run.
  - `cache_since` string, date: Earliest date (`YYYY-MM-DD`, UTC) from which cached runs are considered fresh. Ignored when `cache_enabled` is `false`. Default: `null` — all cached runs are considered fresh regardless of age.
  - `continue_on_fail` boolean: When `true`, a row keeps moving to the next action after an action fails on it. When `false` (default), the row stops at the failing action. Every action follows this setting unless it has its own `continue_workflow_if_action_fails`.

## Response `201`

Default Response

- object
  - `status` integer
  - `data` Sheet: A sheet in a workflow. Pass `sheet_id` as the `{sheet_id}` path parameter on every sheet-scoped endpoint.
    - `sheet_id` string, uuid, required: UUID of the sheet. Pass as `{sheet_id}` on every sheet-scoped endpoint, and as `target_sheet_id` when another sheet routes data here via `send_to_sheet`.
    - `workflow_id` string, uuid, required: UUID of the parent workflow this sheet belongs to.
    - `name` string, required: Sheet name as set at creation. Not required to be unique within a workflow.
    - `is_main_sheet` boolean, required: `true` for the workflow's main sheet — auto-created with the workflow, always present, cannot be deleted separately, and has `sheet_id === workflow_id`. `false` for additional sheets added via Create Sheet.
    - `auto_run` boolean, required: When `true` (default), the sheet's action chain runs automatically whenever new data rows arrive (via Add Data Rows or via a `send_to_sheet` action on another sheet). When `false`, runs must be triggered explicitly with Run Rows.
    - `cache_enabled` boolean, required: When `true` (default), a row with input column values identical to a previously-run row reuses the previous row's outputs instead of re-running the action chain. Matching compares every input column value on the row as a string, after variable references are resolved.
    - `cache_since` string, date, required: Earliest date (`YYYY-MM-DD`, UTC) from which cached runs are considered fresh. Runs performed on or after this date are reusable; runs performed before are ignored even when inputs match. Ignored when `cache_enabled` is `false`. `null` means all cached runs are considered fresh regardless of age.
    - `continue_on_fail` boolean, required: When `true`, a row keeps moving to the next action after an action fails on it. When `false` (default), the row stops at the failing action. Every action follows this setting unless it has its own `continue_workflow_if_action_fails`.

## Other responses

- `400`: Invalid request body
- `401`: Unauthorized — missing or invalid API key
- `403`: Forbidden. `code` says which permission refused: ROLE_FORBIDDEN (your role), INSUFFICIENT_SCOPE (the API key's scopes), WORKFLOW_FORBIDDEN (no access to the workflow), KEY_WORKFLOW_FORBIDDEN (the API key's workflow restriction).
- `404`: Workflow not found
- `429`: Too Many Requests — rate limit exceeded. Check `Retry-After` header for seconds until the limit resets.

---

[API](https://skmtc.dev/floqer/apis/floqer-public-api.md) - [All operations](https://skmtc.dev/floqer/apis/floqer-public-api/llms.txt) - [OpenAPI document](https://skmtc.dev/floqer/apis/floqer-public-api/revisions/fce50dc07b20?raw)
