Skip to main content
POST
/
v1
/
workflows
/
blocks
from retab import Retab

client = Retab()

# A typical extract block with a JSON schema config
block = client.workflows.blocks.create(
    workflow_id="wf_abc123xyz",
    id="extract-1",
    type="extract",
    label="Extract Invoice Fields",
    position_x=320,
    position_y=0,
    config={
        "model": "gpt-5",
        "json_schema": {
            "type": "object",
            "properties": {
                "invoice_number": {"type": "string"},
                "total": {"type": "number"},
            },
        },
    },
)

print(block.id)
{
  "id": "extract-1",
  "workflow_id": "wf_abc123xyz",
  "type": "extract",
  "label": "Extract Invoice Fields",
  "position_x": 320,
  "position_y": 0,
  "width": null,
  "height": null,
  "config": {
    "model": "gpt-5",
    "json_schema": {
      "type": "object",
      "properties": {
        "invoice_number": { "type": "string" },
        "total": { "type": "number" }
      }
    }
  },
  "parent_id": null,
  "updated_at": "2026-05-01T14:30:00Z"
}
Add a new block to a workflow’s draft graph. The create route is flat: send workflow_id in the request body. You provide the block ID — it must be unique within the workflow. Pick something descriptive (e.g. extract-invoice, classifier-language) so edges and assertions stay readable. The config shape depends on type. See Workflow Blocks for the per-type config reference. A few invariants the API enforces:
  • Input blocks (start_document, start_json) cannot be placed inside containers — parent_id must be null for them.
  • parent_id is reserved for placing blocks inside container blocks (while_loop, for_each).
from retab import Retab

client = Retab()

# A typical extract block with a JSON schema config
block = client.workflows.blocks.create(
    workflow_id="wf_abc123xyz",
    id="extract-1",
    type="extract",
    label="Extract Invoice Fields",
    position_x=320,
    position_y=0,
    config={
        "model": "gpt-5",
        "json_schema": {
            "type": "object",
            "properties": {
                "invoice_number": {"type": "string"},
                "total": {"type": "number"},
            },
        },
    },
)

print(block.id)
{
  "id": "extract-1",
  "workflow_id": "wf_abc123xyz",
  "type": "extract",
  "label": "Extract Invoice Fields",
  "position_x": 320,
  "position_y": 0,
  "width": null,
  "height": null,
  "config": {
    "model": "gpt-5",
    "json_schema": {
      "type": "object",
      "properties": {
        "invoice_number": { "type": "string" },
        "total": { "type": "number" }
      }
    }
  },
  "parent_id": null,
  "updated_at": "2026-05-01T14:30:00Z"
}

Authorizations

Api-Key
string
header
required

Body

application/json

Create a new block in a workflow.

workflow_id
string
required

Workflow to create the block in.

type
enum<string>
required

Block type

Available options:
start_document,
start_json,
note,
parse,
edit,
extract,
split,
classifier,
conditional,
api_call,
function,
while_loop,
for_each,
merge_dicts
id
string | null

Block ID. Omit to let the server generate one (recommended). Block IDs must be unique across your organization, not just within a workflow — reusing a custom id like 'block_extract' in more than one workflow fails with 409.

label
string
default:""

Display label

Maximum string length: 200
position_x
number
default:0

X position

position_y
number
default:0

Y position

width
number | null

Block width

height
number | null

Block height

config
Config · object

Block configuration

parent_id
string | null

ID of parent container block (while_loop, for_each)

Response

Successful Response

Public live workflow block object.

id
string
required
workflow_id
string
required

Foreign key to workflow

type
enum<string>
required

Block type (extract, parse, classifier, etc.)

Available options:
start_document,
start_json,
note,
parse,
edit,
extract,
split,
classifier,
conditional,
api_call,
function,
while_loop,
for_each,
merge_dicts,
while_loop_sentinel_start,
while_loop_sentinel_end,
for_each_sentinel_start,
for_each_sentinel_end
updated_at
string<date-time>
required
label
string
default:""

Display label for the block

position_x
number
default:0

X position on canvas

position_y
number
default:0

Y position on canvas

width
number | null

Block width for resizable blocks

height
number | null

Block height for resizable blocks

config
Config · object

Block-specific configuration

parent_id
string | null

ID of parent container (while_loop, for_each)

declarative_path
string | null

Canonical declarative block path used to reconcile imported specs.

declarative_source_block_id
string | null

Authored declarative block id before import-time id regeneration.

resolved_schemas
Resolved Schemas · object

Schemas resolved for this block from the workflow graph.