# Generate file

Render an in-run value into PDF, CSV, XLSX, HTML, TXT, or Markdown and return a signed download URL.

## Overview

Generate file takes a value from the workflow context (by default `last_output`), renders it into the requested format, persists it to storage, and writes a short-lived signed URL to `ctx.file_url`. The next node can post that URL anywhere — Slack message, HTTP webhook, API response — without needing access to the file bytes. When the next node is **Send Email**, the file is attached automatically by default instead of sending only the link.

Rendering rules per format:

| Format | Input shape | Renderer |
| --- | --- | --- |
| `pdf` | Markdown / plain text | Markdown → HTML → WeasyPrint PDF |
| `html` | Markdown / plain text | Markdown → HTML (styled) |
| `markdown` | Any text | UTF-8 file |
| `txt` | Any text | UTF-8 file |
| `csv` | Array of dicts or raw CSV string | DictWriter |
| `excel` (`.xlsx`) | Array of dicts or raw CSV string | openpyxl |

The node also exposes `ctx.last_output_parsed` with `{format, filename, size_bytes, url, preview_url, public_id}` for downstream nodes that need more than the URL.

## Configuration

| Field | Description |
| --- | --- |
| `format` | One of `pdf`, `html`, `markdown`, `txt`, `csv`, `excel`. Default `pdf`. |
| `filename` | Template, default `report-{ts}`. `{ts}` resolves to a UTC `YYYYMMDD-HHMMSS` stamp. Extension is added automatically. |
| `inputField` | Context key to render. Default `last_output`. Use a state key (`report_data`) to pick a stashed value. |
| `label` | Optional label, stored in metadata. |

## Example

Monthly report PDF emailed to ops:

```
Agent (write report markdown)
  → Generate file (format: pdf, filename: ops-report-{ts})
  → Send Email (file is attached automatically)
```

CSV export:

```
Agent (return JSON array of dicts) → Generate file (format: csv, filename: leads-{ts})
```

## Gotchas

- Signed URLs are short-lived. Don't store them — regenerate if you need long-term access (the file row stays in the DB).
- For CSV/Excel, `inputField` **must** resolve to an array of dicts (uniform keys) or a raw CSV string. A free-form Markdown report will raise an error.
- PDF rendering goes through WeasyPrint and supports basic Markdown (tables, code, headings). Complex CSS / images won't render — keep templates simple.
- `{ts}` is the only built-in filename token. Use a **Set state** + a template to inject more (`order-{order_id}`).
- Files are scoped to the workflow owner. Cross-account download URLs are rejected by the signer.

---

*Source: https://agentbuilder.systalink.sn/docs/node-generate-file — human documentation.*
*Other language: [/docs-md/fr/node-generate-file.md](/docs-md/fr/node-generate-file.md).*
*Machine-readable index: [/llms.txt](/llms.txt).*
