# Render page images

Rasterize pages of stored PDFs into PNG data URLs — one record per page — for llm_complete's images.

## When to use it

Render stored PDF pages as image records for a later vision-capable step. Page images can use more processing and model budget than plain text. Limit the page set to the scope needed for the task.

## Add and configure

1. Add **Render page images** from the workflow step picker.
2. Give the step a recognisable name and connect its required inputs.
3. Set the options below. Nested names identify fields within an object or a list item.
4. Validate the recipe, inspect the test result, then run it on the intended data.

The step identifier used in the editor’s code view is `render_pages`.

## Settings

| Setting | Accepted value | Required | Default | What it controls |
| --- | --- | --- | --- | --- |
| Dpi (`dpi`) | integer; minimum 72; maximum 200 | No | 150 | Render resolution (72..200); `max_image_pixels` may reduce it. |
| Drop Fields (`drop_fields`) | list of string | No | ["text","meta_data"] | Input fields NOT carried onto the page records (top-level names). The default drops a segment's `text` and `meta_data` — the large fields. |
| Max Image Bytes (`max_image_bytes`) | integer; minimum 1024; maximum 8388608 | No | 2097152 | Decoded PNG size one page may have; a larger render is that record's `image_too_large` error. Bounds the step's memory with `max_pages_per_record`: a record's pages as base64 data URLs may not exceed 24 MiB (what one digest render call answers) nor 32 MiB (the step's image budget). |
| Max Image Pixels (`max_image_pixels`) | integer; minimum 10000; maximum 4000000 | No | 4000000 | Ceiling on one page's raster in pixels, applied by digest before rendering. |
| Max Pages Per Record (`max_pages_per_record`) | integer; minimum 1; maximum 8 | No | 8 | Pages one record may ask for (at most 8, digest's per-call ceiling); a record naming more is a per-record `too_many_pages` error. |
| Object Key Field (`object_key_field`) | string; minimum characters 1 | No | "object_key" | Record field (dotted path allowed) holding the store key of the PDF. |
| Output Field (`output_field`) | string; minimum characters 1 | No | "image" | Output field carrying the page's `data:image/png;base64,...` URL (`<output_field>_width` / `_height` carry its pixel size). The default is what llm_complete's `images.field` reads. |
| Pages (`pages`) | list of integer; minimum 1; minimum items 1; maximum items 8 or null | No | null | Static 1-based pages to render for EVERY record (distinct, at most max_pages_per_record). Exactly one of `pages_field` / `pages`. |
| Pages Field (`pages_field`) | string; minimum characters 1 or null | No | null | Record field (dotted path allowed) holding the 1-based page(s) to render: an integer or a list of integers — digest_extract's `page_number` renders each segment's page. Exactly one of `pages_field` / `pages`. |
| Endpoint (`source`) | object | Yes | Not specified | Object-store connection the PDFs live in — the same source as the digest_extract step that produced the records (digest reads the file by reference through it). |
| Catalog Slug (`source.catalog_slug`) | string or null | No | null | Catalog slug — mirrored for FE convenience (icon/label resolution). |
| Connection Id (`source.connection_id`) | string; format uuid or null | No | null | UUID of the Connection (integration row). |
| Display Name (`source.display_name`) | string or null | No | null | Human-readable label — the connection's display_name resolved server-side. |
| EndpointKind (`source.kind`) | "connection" | No | "connection" | Source location type. Select the supported source and provide its corresponding connection or app location. |

## Inputs and outputs

| Direction | Port | Content | Required | Multiple records |
| --- | --- | --- | --- | --- |
| Inputs | `in` | records | Yes | Yes |
| Outputs | `out` | records | Yes | Yes |

## Effects, testing, and recovery

Reads an external source.

The declared preview behaviour is to execute this step. Reads, processing, or model usage can therefore be real. Read [dry runs](/docs/workflows/dry-runs) before using a preview with live connections.

No duplicate-prevention key is declared for this step. The step declares safe replay for its supported recovery path.

## Example: Render each extracted segment's page for a vision model

Step settings:

```json
{
  "pages_field": "page_number",
  "source": {
    "catalog_slug": "platform_store",
    "connection_id": "33333333-3333-4333-8333-333333333333"
  }
}
```

## Example: Render the first two pages of every file at 96 dpi

Step settings:

```json
{
  "dpi": 96,
  "output_field": "page_image",
  "pages": [
    1,
    2
  ],
  "source": {
    "catalog_slug": "platform_store",
    "connection_id": "33333333-3333-4333-8333-333333333333"
  }
}
```

## Check the result

Inspect the selected run’s status, counts, errors, and output records. An empty collection can be a valid result, and a completed step can contain per-record failures where the step defines that behaviour. Check the next step’s expected record shape before publishing or delivering the result.
