RendShot

n8n Integration — Generate Images Without Puppeteer

Replace the n8n Puppeteer node with a single HTTP Request node. Generate images from HTML with RendShot in any n8n workflow.

n8n is a workflow automation platform that connects apps, APIs, and databases with visual flows. If you're currently using the Puppeteer community node to generate images or take screenshots, RendShot is a simpler drop-in alternative: one HTTP Request node, no Docker, no Chromium, works on n8n Cloud and self-hosted alike.

Prerequisites

Step 1: Add an HTTP Request Node

In your workflow, add an HTTP Request node and configure it as follows:

Basic settings:

FieldValue
MethodPOST
URLhttps://api.rendshot.ai/v1/image
AuthenticationHeader Auth

Authentication — Header Auth:

FieldValue
NameAuthorization
ValueBearer rs_live_YOUR_KEY

Body:

Set Body Content Type to JSON, then use the following body structure:

{
  "html": "<div style=\"font-family:sans-serif;padding:40px;background:#1a1816;color:white\"><h1>Hello World</h1></div>",
  "width": 1200,
  "height": 630,
  "format": "png"
}

Supported values for format are png, jpeg, and webp. Width and height default to 1200 and 630 if omitted.

The node will return a JSON response with a url field pointing to the hosted image:

{
  "id": "img_01abc...",
  "url": "https://assets.rendshot.ai/img/01abc....png",
  "width": 1200,
  "height": 630,
  "format": "png",
  "created_at": "2026-04-03T10:00:00.000Z"
}

Step 2: Use Dynamic Data from Previous Nodes

The real power comes from injecting data from earlier nodes — Airtable rows, RSS items, webhook payloads — directly into your HTML.

Say an Airtable Trigger node fires when a new row is created, with fields title, author, and category. In the HTTP Request node body, reference them with n8n expressions:

{
  "html": "<div style=\"font-family:sans-serif;padding:48px;background:#1a1816;color:#fff;width:1200px\"><p style=\"color:#6b8f5e;font-size:14px;text-transform:uppercase;letter-spacing:2px\">{{ $json.category }}</p><h1 style=\"font-size:48px;margin:16px 0\">{{ $json.title }}</h1><p style=\"color:#635c53\">By {{ $json.author }}</p></div>",
  "width": 1200,
  "height": 630,
  "format": "png"
}

n8n evaluates the {{ }} expressions before sending the request, so RendShot receives a fully resolved HTML string.

Tips for building HTML in n8n:

  • Use the Expression editor (the = button next to the field) for multi-line HTML — it gives you a larger input area.
  • Escape double quotes inside JSON strings as \", or use a Set node to build the HTML string separately before passing it to the HTTP Request node.
  • If your HTML is complex, use a Code node to build the string with JavaScript template literals, then reference {{ $json.html }} in the body.
// Code node — build HTML, output as { html: "..." }
const title = $input.first().json.title;
const author = $input.first().json.author;

return [{
  json: {
    html: `
      <div style="font-family:sans-serif;padding:48px;background:#1a1816;color:#fff">
        <h1 style="font-size:48px">${title}</h1>
        <p style="color:#635c53">By ${author}</p>
      </div>
    `
  }
}];

Step 3: Use the Image URL in the Next Node

The HTTP Request node output contains {{ $json.url }}. Wire this to any downstream node.

Slack — post image in a channel:

In a Slack node (Send Message), set the Text field to:

New post image: {{ $json.url }}

Or attach it as a block:

{
  "type": "image",
  "image_url": "{{ $json.url }}",
  "alt_text": "Generated image"
}

Email (Gmail / SMTP) — embed in message body:

<img src="{{ $json.url }}" width="600" alt="Report" />

Airtable / Notion — update a field:

Map {{ $json.url }} to an attachment or URL field in an Airtable or Notion update node.

Example Workflows

Airtable new row → image → Slack

  1. Airtable Trigger — fires when a new article row is created
  2. HTTP Request — sends html built from title, author, cover_color fields to /v1/image
  3. Slack — posts the url to #content-team with the article link

Use case: automatically generate a social card for every new piece of content without opening a design tool.

RSS feed → OG image → CMS update

  1. RSS Feed Read — polls a feed every hour
  2. HTTP Request — renders an OG image from the item's title and pubDate
  3. HTTP Request (second) — PATCHes the CMS API with the new og_image URL

Use case: keep OG images current for a curated link newsletter without manual work.

Weekly cron → report image → email digest

  1. Cron — triggers every Monday at 08:00
  2. HTTP Request — fetches stats from your internal API
  3. Code node — formats the numbers into an HTML dashboard card
  4. HTTP Request — renders the card to /v1/image
  5. Gmail — sends the image as an inline attachment to the team

Use case: a weekly snapshot of key metrics delivered to inboxes, no BI tool required.

URL Screenshots

To capture a screenshot of a live URL instead of rendering HTML, use the /v1/screenshot endpoint:

{
  "url": "https://example.com",
  "width": 1280,
  "height": 800,
  "full_page": false
}

Everything else — authentication, the response url field, wiring to downstream nodes — works identically to the /v1/image endpoint.

Why Not the Puppeteer Node?

The n8n Puppeteer community node works, but comes with meaningful operational overhead:

Puppeteer nodeRendShot
n8n CloudNot available (self-hosted only)Works everywhere
SetupRequires Docker + Chromium (~400 MB)No setup, just an API key
MemoryLeaks on long-running workflowsStateless HTTP call
FontsPlatform-dependent, often missingLoaded automatically
MaintenanceManual Chromium updatesHandled by RendShot
Timeout handlingManual page timeout configServer-side, 30s default

If you're on n8n Cloud, the Puppeteer node is not available at all — RendShot is the straightforward path. If you're self-hosted, switching to RendShot removes a Docker dependency and the memory management burden from your n8n instance.

Troubleshooting

401 Unauthorized

Your API key is missing or incorrect. Double-check that:

  • The Header Auth name is exactly Authorization (capital A)
  • The value is Bearer rs_live_YOUR_ACTUAL_KEY with no extra spaces
  • The key hasn't been deleted from the Dashboard

400 Bad Request

The request body is malformed. Common causes:

  • html field is missing or empty
  • JSON is invalid — check that double quotes inside the HTML string are escaped as \"
  • An unsupported format value (only png, jpeg, webp are accepted)

Enable Include Response Body in the HTTP Request node settings to see the full error message from the API:

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "html is required",
    "status": 400
  }
}

Timeout / no response

The default n8n HTTP Request timeout is 300 seconds, which is more than enough. If you see timeouts:

  • Check that your HTML doesn't reference large external resources (images, fonts from slow CDNs)
  • Simplify the HTML — deeply nested elements or large inline SVGs can increase render time
  • Increase the Timeout setting in the HTTP Request node options if needed

See the API Reference for all request parameters, response fields, rate limits, and error codes.

On this page