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

# Batch Generation

> Generate many outputs at once using CSV + templates (dashboard feature).

Batch generation is designed for producing **many** letters/cards/addresses in one run.

Today, batch generation is primarily a **dashboard feature** (it runs through session-authenticated endpoints under `/client/*`, not the public `/api/v1/*` API).

If you need batch generation via API-key auth, contact support.

## How it works

1. Upload a CSV.
2. Write a template using `{variable}` placeholders.
3. Pick output type:
   * `zip_png` — a ZIP of PNG pages
   * `zip_pdf` — a ZIP of per-row PDFs
   * `combined_pdf` — one PDF containing all pages (merged in order)
4. The server creates a batch job and generates up to a few **preview rows**.
5. A background worker claims queued jobs and produces the final artifacts.

## CSV + template rules

* CSV must include a **header row**.
* Column names are normalized:
  * trimmed, lowercased
  * spaces/hyphens become underscores
  * non `[a-z0-9_]` characters become underscores
* Template variables use `{variable_name}` syntax and are normalized the same way.

### Example: Thank you cards

**CSV file:**

```csv theme={null}
first_name,order_number,product
Sarah,ORD-12345,Blue Ceramic Vase
Michael,ORD-12346,Wooden Photo Frame
```

**Template:**

```text theme={null}
Dear {first_name},

Thank you so much for your recent order ({order_number}). We hope you love your {product}!

With gratitude,
The HandCraft Team
```

### Example: Address labels

**CSV file:**

```csv theme={null}
name,street,city,state,zip
John Smith,123 Main Street,Springfield,IL,62701
Jane Doe,456 Oak Avenue,Chicago,IL,60601
```

**Template:**

```text theme={null}
{name}
{street}
{city}, {state} {zip}
```

If a row is missing any required variable values, it is **skipped** and recorded in the batch report.

## Limits and retention

* **Maximum rows:** 5,000 per batch job
* **Output retention:** Files are available for download for 7 days after generation
* **File size:** Large batches may take several minutes to process

## Recommended approach

* Use `/preview` first to lock in a good set of `GenerateRequest` settings.
* Use batch for “production runs” once settings are stable.
* For address work, use `generation_type: "address"` and **manual** `font_size` (auto is not supported).
