> ## Documentation Index
> Fetch the complete documentation index at: https://docs.eigenpal.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Workflow steps

> The complete catalog of step types, each with a code-derived config and output schema.

Every step type the workflow engine supports has its own reference page. The
prose on each page is hand-written; the **Configuration** and **Output** schema
sections are generated from `STEP_SCHEMAS` in `@eigenpal/types`, so they always
match what the engine actually accepts and returns.

Steps fall into four categories, see [Workflows](/concepts/workflows) for how
they fit together.

## Full catalog

### AI steps

| Step                                       | Type                | Summary                                                                                                                                                                                                                                                                                                                                                                       |
| ------------------------------------------ | ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [Parse Document](/steps/ai/parse)          | `ai.parse`          | Extract text from documents (PDF, DOCX, images) using OCR or vision models                                                                                                                                                                                                                                                                                                    |
| [Extract Data](/steps/ai/extract)          | `ai.extract`        | Extract structured data from text using AI with a JSON schema                                                                                                                                                                                                                                                                                                                 |
| [Split Document](/steps/ai/split)          | `ai.split`          | Split a parsed document into named sections using an LLM. Consumes ai.parse output; emits per-section page ranges and text ready for downstream ai.extract via control.parallel\_map.                                                                                                                                                                                         |
| [Separate Documents](/steps/ai/segment)    | `ai.segment`        | Separate a concatenated batch (one big scan) into typed document instances using an LLM. Consumes ai.parse output and a type taxonomy; discovers an unknown number of documents in any order and emits per-document page ranges + text + type, ready for type-specific ai.extract via control.parallel\_map. The inverse of ai.split.                                         |
| [Classify](/steps/ai/classify)             | `ai.classify`       | Classify a document or text into one of a fixed label set using an LLM. Output exposes the picked label (constrained to the configured names), a coarse confidence, and a short justification. Pair with control.fail to reject documents that match an undesired label.                                                                                                      |
| [Label Pages](/steps/ai/classify-pages)    | `ai.classify-pages` | Assign zero or more labels to each page independently (multi-label) using an LLM. Consumes ai.parse output; emits per-page labels and a byLabel map (label -> page indices) that supports NON-contiguous selections. Feed byLabel.\<label> straight into ai.vision `pageIndices` to inspect scattered pages of a type (e.g. every signature or property-photo page).          |
| [Inspect Pages (Vision)](/steps/ai/vision) | `ai.vision`         | Inspect rendered page images with a vision model and return structured JSON matching a schema. The visual counterpart to Extract Data: use it for conclusions that live in the pixels rather than the text (is the document signed? are the photos usable?). Renders PDF, image, or Office/Word inputs; route to specific pages with an ai.split page range to keep it cheap. |

### Transform steps

| Step                                            | Type                      | Summary                                                                                                                                                                                                                                                                                           |
| ----------------------------------------------- | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [Set Value](/steps/transform/set)               | `transform.set`           | Set key-value pairs in the output object                                                                                                                                                                                                                                                          |
| [Remove Fields](/steps/transform/remove)        | `transform.remove`        | Remove specified fields from an object                                                                                                                                                                                                                                                            |
| [Combine Data](/steps/transform/combine)        | `transform.combine`       | Merge multiple objects or concatenate arrays                                                                                                                                                                                                                                                      |
| [Split Data](/steps/transform/split)            | `transform.split`         | Split a string by delimiter or extract keys from an object                                                                                                                                                                                                                                        |
| [Merge Inputs](/steps/transform/merge)          | `transform.merge`         | Merge multiple named inputs into a single output                                                                                                                                                                                                                                                  |
| [Fill Template](/steps/transform/template)      | `transform.template`      | Fill a DOCX template with data from previous steps. Select a template in the workflow builder or provide a template ID from your workspace.                                                                                                                                                       |
| [Embed PDF Text](/steps/transform/pdf-embed)    | `transform.pdf-embed`     | Embed OCR text layer into scanned PDFs/images to make them searchable                                                                                                                                                                                                                             |
| [XLSX to JSON](/steps/transform/xlsx-to-json)   | `transform.xlsx-to-json`  | Convert XLSX spreadsheet to JSON array of row objects for use in scripts or downstream steps                                                                                                                                                                                                      |
| [Script](/steps/transform/script)               | `transform.script`        | Execute a TypeScript function in a QuickJS sandbox. Input keys become the function's parameter list, in declaration order, and the required `: R` return-type annotation IS this step's output schema: `inputs: &#123; items, taxRate }` ⇒ `function script(items: …, taxRate: …): R &#123; … }`. |
| [Text Chunker](/steps/transform/text-chunker)   | `transform.text-chunker`  | Split long text into chunks with regex-anchored boundaries, overlap, and header preservation. Accepts raw text or a parsed-document object; chunks carry source page indexes when pages are provided.                                                                                             |
| [Regex Extract](/steps/transform/regex-extract) | `transform.regex-extract` | Pull named fields from text via regex patterns (deterministic counterpart to ai.extract). Accepts raw text or a parsed-document object; matches carry `_evidence.pageIndex` when pages are provided.                                                                                              |

### Action steps

| Step                                             | Type                     | Summary                                         |
| ------------------------------------------------ | ------------------------ | ----------------------------------------------- |
| [HTTP Request](/steps/action/http)               | `action.http`            | Make an HTTP request to an external API         |
| [Invoke Workflow](/steps/action/invoke-workflow) | `action.invoke-workflow` | Execute another workflow and return its output  |
| [Website Reader](/steps/action/website-reader)   | `action.website-reader`  | Fetch a webpage and convert content to markdown |

### Control steps

| Step                                        | Type                   | Summary                                                                                                                                                                                                                                  |
| ------------------------------------------- | ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [Condition](/steps/control/if)              | `control.if`           | Branch execution based on a condition expression                                                                                                                                                                                         |
| [Switch](/steps/control/switch)             | `control.switch`       | Multi-way routing: resolve an expression and run the first case whose value matches (else default). Cleaner than a nested control.if chain for routing an item to one of N pipelines by a discriminator field like a document type.      |
| [For Each](/steps/control/foreach)          | `control.foreach`      | Loop over an array and execute steps for each item                                                                                                                                                                                       |
| [Parallel Map](/steps/control/parallel_map) | `control.parallel_map` | Iterate over an array with concurrent execution up to a limit                                                                                                                                                                            |
| [Parallel](/steps/control/parallel)         | `control.parallel`     | Execute multiple branches concurrently                                                                                                                                                                                                   |
| [Wait](/steps/control/wait)                 | `control.wait`         | Pause workflow execution for a specified duration                                                                                                                                                                                        |
| [Fail](/steps/control/fail)                 | `control.fail`         | Terminate the workflow with a typed status code + message. With an optional condition, only fails when the condition is truthy; otherwise always fails when reached. Pair with ai.classify or any prior step to fail fast on bad inputs. |
