# How to use Gotenberg with n8n to convert HTML to PDF

Gotenberg with n8n: use the HTTP Request node to turn HTML into PDFs in a workflow, or skip the server with a hosted API and one JSON call.

**Quick answer.** In n8n, add one **HTTP Request** node that POSTs `{"html": "..."}` to `https://html-pdf.com/v1/pdf` with your key, and set the response format to File. The same request as curl looks like this.

```bash
curl -X POST https://html-pdf.com/v1/pdf \
  -H "Authorization: Bearer $HTML_PDF_KEY" \
  -H "Content-Type: application/json" \
  -d '{"html": "<h1>Hello</h1>", "format": "A4"}' \
  -o out.pdf
```

## Option A: your own Gotenberg

This option walks you through calling a Gotenberg server you run yourself. You need a Gotenberg instance that n8n can reach (see [self-host Gotenberg with Docker](https://html-pdf.com/self-host-gotenberg-docker) or [deploy it on Railway](https://html-pdf.com/deploy-gotenberg-railway)). If both run in the same Docker network, the URL is usually `http://gotenberg:3000`.

### 1. Turn your HTML into a file named index.html

Gotenberg's HTML route only accepts an uploaded file called **`index.html`**. Here is how to create it in n8n.

1. Build your HTML (for example in a **Code** or **Set** node) into a field such as `html`.
2. Add a **Convert to File** node with operation *Move String to File*, source property `html`, file name `index.html` and MIME type `text/html`. This creates binary data (by default in the `data` property).

### 2. Send it to Gotenberg

Add an **HTTP Request** node with these settings.

- **Method:** POST
- **URL:** `http://gotenberg:3000/forms/chromium/convert/html`
- **Authentication:** Basic Auth, if you enabled it on Gotenberg
- **Send Body:** on → **Body Content Type:** Form-Data
- **Body parameter:** type *n8n Binary File*, name `files`, input data field `data`
- Optional extra form fields such as `paperWidth`, `paperHeight`, `marginTop`, `landscape`…
- **Options → Response → Response Format:** File

The output item now carries the PDF as binary data. It is ready for Gmail, Google Drive, S3 or a webhook response.

### Common errors

- **400 / "no index.html"** means the binary file name isn't exactly `index.html`.
- **Images missing.** Reference them by absolute `https://` URL, or upload them as extra `files`.
- **Timeouts.** Large documents need a higher Gotenberg `--api-timeout` and a higher n8n request timeout.

## Option B: skip the server (one JSON call)

This option gets you PDFs with no file conversion step and nothing to host. With [html-pdf.com](https://html-pdf.com) you need a single **HTTP Request** node.

- **Method:** POST
- **URL:** `https://html-pdf.com/v1/pdf`
- **Headers:** `Authorization: Bearer <your API key>`
- **Body Content Type:** JSON
- **Body:** `{"html": "{{ $json.html }}", "format": "A4"}` (or `{"url": "https://..."}` for a web page)
- **Response Format:** File

Prefer a link instead of binary data? Add `"response": "url"` to the body and use `{{ $json.url }}` downstream. The link stays valid for 24 hours.

You get 100 free pages, then pay from $0.005 per page, and credits never expire. For the full walkthrough, see [HTML to PDF in n8n](https://html-pdf.com/guides/n8n).

[Get a free API key](https://html-pdf.com/login) · [API reference](https://html-pdf.com/docs)

## FAQ

### How do I convert HTML to PDF in n8n?

Use an **HTTP Request** node. Either upload an `index.html` file to your own Gotenberg server, or POST JSON with your HTML to `https://html-pdf.com/v1/pdf` and set the response format to File.

### Why does Gotenberg return "no index.html"?

Gotenberg's HTML route needs the uploaded file to be named exactly `index.html`. Set that file name in the **Convert to File** node.

### Is there a free way to generate PDFs in n8n without a server?

Yes. html-pdf.com gives you 100 free credits once, with no card, and 1 credit = 1 PDF page. Purchased credits never expire.

### Can n8n get a download link instead of a binary PDF?

Yes. Add `"response": "url"` to the JSON body and read `{{ $json.url }}` in the next node. The link lasts 24 hours.
