How to generate PDF documents in n8n for free using Carbone + SEO audit workflow example

Using self hosted Carbone and n8n (Docker)
August 27, 2025 by
How to generate PDF documents in n8n for free using Carbone + SEO audit workflow example
Alixsander Haj Saw
| No comments yet

Introduction

Generating PDF documents in n8n is possible using Carbone.

The solution allows you to generate PDF documents based on a template that we'll create using google docs. The docs template can be styled freely and will contain tags that will be replaced with our data before generating the PDF document.

Unfortunately the free version does not include HTML formatting, which would make turning content into a PDF file easy by turning the HTML format into the correct PDF formatting.

We will be using Docker to create 2 containers, one for n8n to create the workflows, and one for Carbone which will be used to generate the pdf document.

Make sure Docker Desktop is installed on your pc.


Creating n8n and Carbone containers

We'll be using docker compose to create our 2 containers. Create your working directory and within it create the compose.yml file and add the following directives to it:

services:
  n8n:
    image: docker.n8n.io/n8nio/n8n
    ports:
      - "5678:5678"
    volumes:
      - n8n_data:/home/node/.n8n

  carbone:
    image: carbone/carbone-ee
    ports:
      - "4000:4000"
    secrets:
      - source: carbone-publickey
        target: /app/config/key.pub
    environment:
      - LOG_LEVEL=info
      - CARBONE_EE_AUTHENTICATION=true
    volumes:
      - ./templates:/app/template

secrets:
  carbone-publickey:
    file: key.pub

volumes:
  n8n_data:

In this above compose.yml file we are specifying 2 containers, one for n8n and one for Carbone.

The volumes will ensure the data remain persistent even after shutting down and starting the containers, in case of n8n, the workflows and credentials will remain persistent in the volume. In case of Carbone, our template will remain persistent.

We are also making sure that the 2 containers are on the same network.

Before starting these containers, we need to create the necessary keys and tokens to enable authentication with our Carbone container.


Create your template

Carbone uses a template to generate the pdf file, the template should contain certain tags that are replaced with the matching JSON keys.

You can create the template using google docs, then download the doc as Microsoft Word.

For example, inside the google doc, the following tags within the document:
{d.titlemain}
{d.intromain}

Will be replaced with the values inside JSON:

"data": {
"titlemain": "On-Page SEO Analysis",
"intromain": "This document outlines the On-Page SEO tasks required to improve the webpage's search engine visibility and user engagement based on a thorough analysis."
}

You can also provide a list value in JSON and loop over it in the template using the following format:
{d.critlist[i]}

{d.critlist[i+1]}

and the corresponding JSON would be:

"critlist": [
"1. Optimize the title tag to include primary keywords and ensure it's under 60 characters.",
"2. Improve meta descriptions to be compelling and within 160 characters, incorporating relevant keywords."
]

Here is an example template that you can download, add it to the same directory as the compoe.yml file, we will use it later in our workflow:

Click Here to View the Template Example on Google Docs


Carbone key/token authentication

Bellow commands are using git bash on Windows

Now we need to generate a private and public keys, then well generate a token signed by our private key. We will later use that token to generate documents using our Carbone container.

Make sure you are located in the same directory as compose.yml file.

To generate both the private and public keys run the following:

openssl ecparam -genkey -name secp521r1 -noout -out key.pem
openssl ec -in key.pem -pubout -out key.pub

With the keys created, we can start the containers by running:

docker compose up -d

Carbone uses JSON web token, to generate one we will need to install step. It can be installed on Windows using winget by running the following command:

winget install Smallstep.step

If the above does not work, then install step manually using:

curl -LO https://dl.smallstep.com/cli/docs-cli-install/latest/step_windows_amd64.zip
unzip step_windows_amd64.zip -d .

Now we can set the tokens expiration time and generate it. In our case we are setting the expiration time to of our token to 100 days:

current_time=$(date +%s)
expiration_time=$(($current_time + 864000))

step crypto jwt sign --alg ES512 --iss=carbone-user --subtle --aud=carbone-ee --exp=$expiration_time --key=key.pem

If you did the manual step installation, then run step from the downloaded file:

./step_windows_amd64/bin/step.exe crypto jwt sign \
  --alg ES512 \
  --iss carbone-user \
  --subtle \
  --aud carbone-ee \
  --exp "$expiration_time" \
  --key key.pem

After running the step command, you'll see the token printed out, save it as we'll need it in the next steps. Example token:

Now let's add our template to Carbone, we can do so using the curl command:

export API_TOKEN="your_api_token_here"

curl --location --request POST "http://localhost:4000/template" \
  --header "carbone-version: 4" \
  --header "Expect:" \
  --header "Content-Type: multipart/form-data" \
  --header "Authorization: Bearer $API_TOKEN" \
  --form "template=@/c/Users/you_user/path/to/SEO-Template.docx"

This should output the template ID like so:

Save both the templateID and the token we will use both of them in our workflow.


Generating PDF using n8n Workflow

Below is an SEO audit workflow, it creates Off-page and On-page audits, adds them to the PDF template, then sends it using Gmail. You can remove the Gmail node and download the file directly to your machine from the node previous to the Gmail node.

Things to modify in this workflow:

  • Add the OpenAI key/credentials to the OpenAi chat nodes.
  • Add your token and templateId we previously generate in the "Generate Template Using JSON" nodes.
  • Add your google credentials in the Gmail node if you'd like to send the report to the email provided.

After you've completed the following, you should be able to execute the workflow and receive the SEO report to the email provided in the form.


Sign in to leave a comment