> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://onepin.ai/docs/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://onepin.ai/docs/_mcp/server.

# Generate long-form audio

> Generate hours of audio in one Onepin run — upload a long script file, understand the per-node limits, and assemble the per-line output files using manifest.csv.

Long-form is just "many lines" — Onepin voices each line independently and delivers one audio file per line, plus a `manifest.csv` to stitch them in order. Chapters, courses, narration: same pipeline, bigger script.

## Upload the script as a file

Don't paste a book inline — [upload it](/docs/guides/upload-a-file) and point the Script node at the upload:

```python
created = client.uploads.create(filename="chapter-01.txt", category="script").data
# PUT the bytes, confirm, then:
node["config"] = {"input_type": "file", "source_language": "en-us",
                  "upload_ids": [upload_id]}
```

A `.txt` splits into lines; a `.pdf` is extracted to text, with wrapped paragraphs rejoined into one line each. One line = one audio file = one unit of validation and retry.

## Know the limits

| Limit         | Value                                                   |
| ------------- | ------------------------------------------------------- |
| Script file   | 10 MB, up to 50 files per Script node                   |
| Inline text   | 500,000 characters                                      |
| Lines per run | 100,000 — **10,000 when any validator is in the graph** |

For book-length projects, run **a chapter per run** (or per workflow): retries stay cheap, a failed run re-does one chapter instead of the book, and you stay well inside the validator cap.

## Estimate before you run

Long scripts are where cost surprises live — preview first:

```bash
onepin workflows preview-run "$WF"    # estimated credits, no execution
```

## Stitch the output

The export ZIP is ordered by the manifest:

```
sink_preview_1/en-us/…_line_000.mp3 … _line_NNN.mp3
manifest.csv    ← line order, text, language, file path
```

Concatenate in manifest order — for example with ffmpeg:

```bash
unzip -o chapter-01.zip
ls sink_preview_1/en-us/*.mp3 | sort | sed "s/^/file '/;s/$/'/" > list.txt
ffmpeg -f concat -safe 0 -i list.txt -c copy chapter-01.mp3
```

Runs are asynchronous — start the run and poll (`--watch` in the CLI); a long script takes minutes, not seconds. There's no per-run wall-clock limit; lines synthesize in parallel batches.

## Related

* [Upload a file](/docs/guides/upload-a-file) — the three-step upload flow
* [Validate every line](/docs/guides/validate-every-line) — quality-gating long content
* [Check usage](/docs/guides/check-usage) — watching credit consumption