Image Generation API

Image generation API: HTML, a URL or JSON in — PNG out

The same engine that prints your PDFs also renders pictures. Social visuals, ad banners, OG images and personalised graphics, produced from a template and a payload instead of by hand.

  • 50 free renders/month
  • No credit card
  • PNG, JPG, WebP

What is an image generation API?

An image generation API turns markup and data into image files over HTTP. You send HTML, a URL or a template ID together with JSON values; the service renders the result in a real browser and returns a PNG, JPG or WebP. It replaces the headless browser, the font handling and the image pipeline you would otherwise run yourself.

Key facts

InputHTML, a URL, or a stored template filled with JSON
OutputPNG (default), JPEG, WebP
EndpointsPOST /v1/images/from-html, /from-url, /from-template
Default viewport1280 × 720, overridable per request
Resolutionscale 1–3 for retina output
Exact sizeswidth and height with fit: contain, cover or fill
Transparencytransparent for PNG and WebP, omit_background for screenshots
Render timeMedian 216 ms, p95 516 ms1
Engine2026.4 on Chromium 153, JavaScript enabled by default
PriceIncluded in every plan. From €15 / month for 3,000 renders, auto top-ups from €6 per 1,000 — see pricing

One call, one image

Store a layout once, then send the values that change. The response carries a signed URL, or the file itself when you ask for "delivery": "binary".

curl https://api.dynamicdocumentapi.com/v1/images/from-template \
  -H "Authorization: Bearer $DYNAMIC_DOCUMENT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "template_id": "tpl_summer_sale",
    "data": { "title": "Summer Sale", "discount": "40%" },
    "image": {
      "format_options": { "quality": 90 },
      "width": 1080, "height": 1080, "fit": "cover",
      "scale": 2
    },
    "delivery": "binary"
  }' \
  --output sale.png

# sale.png is 2160 x 2160 pixels: 1080 at scale 2
const res = await fetch("https://api.dynamicdocumentapi.com/v1/images/from-template", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.DYNAMIC_DOCUMENT_API_KEY}`,
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    template_id: "tpl_summer_sale",
    data: { title: "Summer Sale", discount: "40%" },
    image: { width: 1080, height: 1080, fit: "cover", scale: 2 }
  })
});

const { files } = await res.json();
console.log(files[0].url); // signed, valid for one hour
import os, requests

res = requests.post(
    "https://api.dynamicdocumentapi.com/v1/images/from-template",
    headers={"Authorization": f"Bearer {os.environ['DYNAMIC_DOCUMENT_API_KEY']}"},
    json={
        "template_id": "tpl_summer_sale",
        "data": {"title": "Summer Sale", "discount": "40%"},
        "image": {"width": 1080, "height": 1080, "fit": "cover", "scale": 2},
    },
    timeout=60,
)
res.raise_for_status()
print(res.json()["files"][0]["url"])
<?php
$ch = curl_init("https://api.dynamicdocumentapi.com/v1/images/from-template");
curl_setopt_array($ch, [
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => [
    "Authorization: Bearer " . getenv("DYNAMIC_DOCUMENT_API_KEY"),
    "Content-Type: application/json",
  ],
  CURLOPT_POSTFIELDS => json_encode([
    "template_id" => "tpl_summer_sale",
    "data" => ["title" => "Summer Sale", "discount" => "40%"],
    "image" => ["width" => 1080, "height" => 1080, "fit" => "cover", "scale" => 2],
  ]),
]);
$out = json_decode(curl_exec($ch), true);
echo $out["files"][0]["url"];

Authentication is a bearer token. The same three inputs — HTML, URL, template — exist for PDFs under /v1/pdf/…, so a layout you already print can also be photographed.

Three ways in

From a template

Store the layout once, send only the values. Templates use Jinja syntax, format dates and currencies per locale through ICU, render QR codes and barcodes, and keep every published version — so you can pin a version and roll back a design change.

Best for campaign graphics, certificates and anything produced thousands of times with different data.

From your HTML

Send markup and CSS and get the rendered result. Your application already produces the layout — React, Django, Rails, Laravel — and the API only takes the picture.

Fonts come from the engine catalogue, from your template assets, or from a remote @font-face through the proxy.

From a URL

Point the API at a page and get a screenshot. full_page captures beyond the viewport, clip_selector narrows it to one element, and pages behind a login are reachable with cookies, headers or basic_auth.

Credentials are only sent to the same registrable domain, and there is no CSS injection on URL capture.

Sizes, scale and transparency

OptionValuesWhat it does
format_optionsquality, progressive, losslessCompression for JPEG and WebP
transparenttrue / falseTransparent background, PNG and WebP only
scale1–3Device scale factor: 2 doubles the pixels without touching your CSS
width, heightpixelsResize the output; aspect ratio is kept unless both are set
fitcontain · cover · fillHow the render is placed inside those dimensions
viewportdefault 1280 × 720The browser window the page is laid out in
full_pagetrue / falseCapture the whole page, not just the viewport
clip_selectorCSS selectorCapture a single element
omit_backgroundtrue / falseDrop the page background on a screenshot
waitload · networkidle · selector · ready_flag · delayWhen the picture is taken

A 1080 × 1080 design at scale: 2 returns 2160 × 2160 pixels. The layout does not change — only the number of pixels. That is the difference between an image that survives a retina display and one that does not.

Waiting for the page to be ready

A picture taken too early is worse than a slow one. The engine always waits for the load event, then for web fonts, image decoding and two rendered frames. Beyond that you choose:

  • networkidle — a 500 ms quiet window on the network, for pages that fetch their own data.
  • selector — wait until an element exists, up to 500 characters of CSS selector.
  • ready_flag — your page sets a flag when it is finished. The honest choice for charts and async data.
  • delay — a fixed pause, 0 to 10,000 ms, when nothing better is available.

With strict: true a timeout fails the render; with false you get the warning wait_timeout and an image anyway. Timeout is configurable up to 300 seconds, default 30.

Image API, headless browser or design tool?

This APIYour own ChromiumDesign tool with an export
SetupAn HTTP callBrowser, fonts, sandbox, queue, autoscalingManual, per image
Per-image cost at volumeFrom €0.005, falling to €0.0016Servers plus the time to keep them aliveA person's time
Same layout as a PDFYes, one templateYou build it twiceNo
Fits in a pipelineYes, with webhooks and asyncYes, once you build itNo
Full creative freedomHTML and CSSHTML and CSSYes, but by hand

When this API is not the right tool

If you need one beautiful image and never another, a design tool wins — an API is worth it when the same layout gets filled again and again. If your visuals are photographs rather than layouts, an image editing service fits better than a renderer. And if policy forbids sending content to a third party, self-hosting Chromium is the honest answer.

What it costs

Images are included in every plan, on the same allowance as PDFs: €15 a month for 3,000 renders, €47 for 15,000, €119 for 50,000, €319 for 200,000 — billed annually. That is €0.005 per image on the entry plan and €0.0016 on the largest one. One render is one image at one output size, whatever the pixel dimensions; every format of that size is included.

Paid plans top up automatically when they run low: 1,000 renders at €6 to €2 per 1,000, depending on the plan. On the free plan, render packs cover the same work without a subscription: €50 for 10,000 renders, €200 for 50,000, €750 for 250,000, valid 12 months.

For social cards there is a cheaper path than calling the API per post: a signed render link (from Starter) is a URL you put straight in the og:image tag. It renders on the first request and is served from cache after that, so it costs one render no matter how often crawlers, chat apps and timelines fetch it.

The free plan includes 50 renders a month with no credit card, and it uses the same engine, so a prototype behaves exactly like production. Full numbers are on the pricing page.

1 Median render time 216 ms, p95 516 ms, measured over 1,664 successful renders: queue plus processing in the worker, excluding network time and API overhead.

FAQ

Frequently asked questions

What is an image generation API?

An image generation API turns markup and data into image files over HTTP. You send HTML, a URL or a template ID together with JSON values, and the service renders the result in a real browser and returns a PNG, JPG or WebP file. It replaces the headless browser and the image pipeline you would otherwise run yourself.

Which image formats are supported?

PNG is the default. JPEG and WebP are available, with quality, progressive and lossless settings through format_options. PNG and WebP also support a transparent background.

How do I get a retina image?

Set scale to 2 or 3. The device scale factor multiplies the pixel output without changing your CSS layout, so a 1080 × 1080 design at scale 2 returns 2160 × 2160 pixels.

Can I take a screenshot of a whole web page?

Yes. Send the URL to the image endpoint and set full_page to true to capture beyond the viewport, or use clip_selector to capture one element. The viewport defaults to 1280 × 720.

How fast is a render?

Median render time is 216 ms and p95 is 516 ms, measured over 1,664 successful renders as queue plus processing in the worker, excluding network time.

What does image generation cost?

Images are included in every plan. Paid plans start at €15 a month for 3,000 renders billed annually, and the free plan includes 50 renders a month. One render is one image at one output size, and PDFs and images draw on the same allowance. See pricing.

Can the same template produce a PDF and an image?

Yes. Templates are stored once and rendered to either output. You send the same JSON to the PDF template endpoint or the image endpoint and get a document or a picture from the same layout.

Render your first image free

50 renders a month on the free plan, no credit card, auto top-ups on paid plans, no browser to run.

Start free