<!-- BusyBot node reference — https://busybot.net/tools/aws-textract/ -->

> Node: AWS Textract (`aws_textract`) · Action (binary) · v1
> Category: Utility · Credentials: AWS (`aws`)
> Updated: 2026-08-16

# AWS Textract

> Extract text, tables, forms, and expense data from documents using AWS Textract

## Overview

The AWS Textract tool uses Amazon Textract to extract structured data from documents and images. It supports three operations: Analyze Expense — extract receipt/invoice fields like vendor name, totals and dates from PNG/JPEG images; Detect Text — detect and extract all text lines from a document image; and Analyze Document — extract forms (key-value pairs) and tables from document images. For single-page documents (PNG/JPEG) it uses the synchronous APIs. For multi-page PDFs it uses the asynchronous start/get APIs with polling.

**Category:** Utility  
**Tool Name:** `aws_textract`  
**Version:** 1

**Appearance:** Icon: `lucide-Server` | Color: `#FF9900`

## Node Type

**Action (Binary)** — handles file/binary data operations

## Input / Output

| Direction | Port(s) |
|-----------|--------|
| Input | `Input` |
| Output | `Output`, `Error` |

## Credentials

This tool requires **AWS** credentials.
See the [Credentials Guide](https://busybot.net/credentials/aws/) for setup instructions.

### Operations

| Operation | Value | Description |
|-----------|-------|-------------|
| Analyze Document | `analyzeDocument` | Extract forms (key-value pairs) and tables from a document image |
| Analyze Expense | `analyzeExpense` | Analyze a receipt or invoice image and extract structured expense data |
| Detect Text | `detectText` | Detect and extract all text from a document image |

### Parameters

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| Input Data Field Name | `string` | Yes | `data` | The name of the input binary property containing the document or image to analyze. Supported formats: PNG, JPEG for synchronous; PDF, PNG, JPEG, TIFF for asynchronous. Names are case-sensitive — see the upstream node's Binary Data panel for the exact names to use. |
| Feature Types | `multiOptions` | No | `['FORMS', 'TABLES']` | The types of analysis to perform on the document. _(shown when Operation is `analyzeDocument`)_ |
| | | | | Options: `FORMS` (extract key-value pairs — form fields), `TABLES` (extract table data) |
| Simplify | `boolean` | No | `true` | Whether to return a simplified version of the response instead of the raw Textract API data. |
| Options | `collection` | No | `{}` | Advanced settings, mostly governing the asynchronous PDF path. |
| — Use Async for PDF | `boolean` | No | `true` | Whether to use the asynchronous API with S3 for multi-page PDF documents. When disabled, sends document bytes directly (limited to single-page images). |
| — S3 Bucket | `string` | No | — | S3 bucket name for async processing. Required when processing multi-page PDFs. The document must be uploaded to this bucket first. |
| — S3 Object Key | `string` | No | — | S3 object key for async processing. If empty, uses the original file name from the binary property. |
| — S3 Object Version | `string` | No | — | S3 object version ID for async processing (optional). |
| — Max Poll Time (Seconds) | `number` | No | `300` | Maximum seconds to wait for async job completion before timing out. |
| — SNS Topic ARN | `string` | No | — | SNS topic ARN for async job completion notification (optional). |
| — SNS Role ARN | `string` | No | — | IAM role ARN that Textract assumes to publish to the SNS topic (required if SNS Topic ARN is set). |
| Max Concurrency | `number` | No | `5` | Maximum number of items to process concurrently. Keep low due to Textract API rate limits. |

Parameter values on this node are used exactly as typed — `{{ … }}` expressions are not evaluated here, so set the binary field name, bucket and object key to literal values rather than to expressions.

## Output Data

One output item per input item. The extraction result is merged into the item JSON at the top level, so the incoming fields stay addressable alongside it, and the input binary is forwarded unchanged — on error items too, so a retry branch still has the document.

Which shape you get depends on **Simplify**.

### Simplify on (the default)

**Detect Text** produces the whole document as one string plus the individual lines:

```json
{
  "text": "INVOICE\nAcme Supplies Ltd\nTotal 128.40",
  "lineCount": 3,
  "lines": ["INVOICE", "Acme Supplies Ltd", "Total 128.40"]
}
```

`text` joins the lines with newlines in reading order, `lines` is the same content as an array, and `lineCount` is its length. Only whole lines are returned; individual words and their coordinates are dropped.

**Analyze Document** produces form fields and tables:

```json
{
  "keyValuePairs": {
    "Full Name": "Jane Doe",
    "Signed": "SELECTED"
  },
  "tables": [
    {
      "rows": [
        ["Item", "Qty", "Price"],
        ["Widget", "2", "19.98"]
      ]
    }
  ]
}
```

- `keyValuePairs` — one property per detected form field, the printed label as the property name and the filled-in text as the value. A checkbox or radio button contributes its selection status (`SELECTED` / `NOT_SELECTED`) instead of text. Fields whose label came back empty are skipped.
- `tables` — one entry per detected table. Each has a `rows` array, and each row is an array of cell strings ordered left to right. Header rows are not distinguished from body rows; the first row is simply the first row Textract found.

**Analyze Expense** flattens the receipt onto the item directly. Every summary field Textract identified becomes a property on the output item: the field's type label is the property name and its detected text is the value, giving a flat object with no wrapper. Fields Textract could not label are skipped, and if a document contains several expense records their fields are merged into that one flat object — repeated field names overwrite each other, so the last one wins.

Because the property names come from the document rather than from this node, run one document through and inspect the output before writing downstream expressions against it.

### Simplify off

The raw Amazon Textract response is merged instead, with the SDK's transport metadata (`$metadata`) removed:

- **Detect Text** and **Analyze Document** return Textract's `Blocks` array — every page, line, word, key-value set, table, cell and selection element as its own block, with block type, confidence, geometry and the relationship IDs that link them, plus the document metadata. On the asynchronous path the blocks from every result page are concatenated into one array, so a long PDF still arrives as a single item.
- **Analyze Expense** returns Textract's `ExpenseDocuments` array — one entry per receipt or invoice found, each with its summary fields and line-item groups, and each field carrying its type, label, value and confidence.

Turn Simplify off when you need confidence scores or bounding-box geometry; leave it on when you just want the values.

## Usage Examples

- Extract text from a scanned document image
- Analyze a receipt to get vendor name and total
- Extract tables from a PDF document
- Parse form fields from an image
- OCR a JPEG invoice to get line items

## Example Configuration

Pull vendor, total and date off a receipt image attached to the item:

```json
{
  "type": "aws_textract",
  "parameters": {
    "operation": "analyzeExpense",
    "binaryPropertyName": "data",
    "simplify": true
  }
}
```

OCR a scanned page and keep the plain text:

```json
{
  "type": "aws_textract",
  "parameters": {
    "operation": "detectText",
    "binaryPropertyName": "data",
    "simplify": true,
    "maxConcurrency": 5
  }
}
```

Extract form fields and tables from a single-page image:

```json
{
  "type": "aws_textract",
  "parameters": {
    "operation": "analyzeDocument",
    "binaryPropertyName": "data",
    "featureTypes": ["FORMS", "TABLES"],
    "simplify": true
  }
}
```

Process a multi-page PDF that already sits in S3, allowing ten minutes for the job:

```json
{
  "type": "aws_textract",
  "parameters": {
    "operation": "analyzeDocument",
    "binaryPropertyName": "data",
    "featureTypes": ["TABLES"],
    "simplify": true,
    "maxConcurrency": 1,
    "options": {
      "useAsyncForPdf": true,
      "s3Bucket": "table-extraction-bucket",
      "s3ObjectKey": "reports/q3-report.pdf",
      "maxPollTime": 600
    }
  }
}
```

Get the full block-level response with confidences and geometry:

```json
{
  "type": "aws_textract",
  "parameters": {
    "operation": "detectText",
    "binaryPropertyName": "data",
    "simplify": false
  }
}
```

### Error Handling

| Mode | Behavior |
|------|----------|
| **stop** | Halts workflow on first error |
| **continue** | Skips failed items, passes successful ones through |
| **errorPort** | Routes failed items to Error output port |

## Tips

Extract text, tables, forms, and expense data from document images and PDFs using Amazon Textract.

### Key notes

- **The document always comes from binary data.** The named binary property must exist on the item — put a Download, Read File or S3 node in front of this one.
- **PDFs take the asynchronous route, and it needs S3.** A PDF is processed asynchronously only when Use Async for PDF is on *and* an S3 Bucket is set; upload the file to that bucket first. Without a bucket the document bytes are sent directly, which only works for single-page input.
- **S3 Object Key defaults to the file name** carried on the binary property, so you can leave it empty when you uploaded the file under its original name.
- **The node waits for the job.** Asynchronous runs are polled until Textract reports success or Max Poll Time (default 300 seconds, maximum 900) elapses, at which point the item errors. Raise it for long documents. Setting the SNS options registers a completion notification with Textract, but the node still waits on the job rather than returning early.
- **Feature Types only applies to Analyze Document.** Select `FORMS` for key-value pairs, `TABLES` for tabular data, or both.
- **Keep Max Concurrency low.** Textract rate-limits per account, and the default of 5 is deliberately conservative; drop to 1 for long asynchronous PDF jobs.
- **Region comes from the credential.** The S3 bucket must live in the same region as the AWS credential the node uses.