The HTML to PDF field, compared honestly
Eight vendors on fourteen capability rows, every cell read from the vendor's own documentation before it was written, and our own missing cells printed with the vendor to choose instead. This is not a ranking: there is no score and no winner, because the right column depends on the row you came for.
The matrix
The marks: ✓ means the vendor's own docs state it with a named parameter or endpoint; ✗ means the vendor's documented list is complete and the capability is not on it; ◐ means half, the engine can do it but the knob, the mode or the paperwork is not all there. Where a check could not settle a cell, the cell says so instead of guessing.
| Capability | webcapture | PDFShift | DocRaptor | Gotenberg | Urlbox | Browserless | ScreenshotOne | APITemplate.io |
|---|---|---|---|---|---|---|---|---|
| Output formats Format lists come from each vendor's documented parameters (checked 2026-10-03 to 2026-10-05). | ✓ pdf, png, jpeg, webp, markdown | ✓ pdf, png, jpeg, webp; markdown not offered | ✓ pdf only | ✓ pdf, png, jpeg, webp; markdown not offered | ✓ pdf, png, jpeg, webp, markdown (format=md) | ✓ pdf; png, jpeg, webp via options.type; markdown on /smart-scrape, not /pdf | ✓ pdf, png, jpeg, webp, markdown, plus gif, jp2, tiff, avif, heif | ✓ pdf, png, jpeg; webp not offered |
| Rendering engine Where a vendor's docs stay silent about the engine, the cell says so rather than guessing. | ✓ Chromium, disclosed | ✓ Chromium, disclosed | ✓ Prince, disclosed (not a browser engine) | ✓ Chromium for HTML; LibreOffice for office documents | ✓ Chromium, with a per-request engine_version pin (stable, latest, experimental) | ✓ the endpoint path names the engine (Chrome, Chromium, Edge); no per-request version pin | ✗ not disclosed | ✗ engine not named; a rendering_engine_version knob offers 97 or 153 |
| Price at the measured band Each vendor's own published numbers: the hosted rows from our rate card (checked 2026-09-11, PDFShift re-checked 2026-10-03), Urlbox and Browserless pricing pages captured 2026-10-04. | ✓ one render per document, any size: Pro 0.38 cents at 5,000 ($19); Scale about 0.197 cents at 35,000 ($69) | ✓ one credit per 5Mb of output: 0.396 cents at 25,000; a 14Mb document costs 3 credits | ✓ 2.98 cents at 5,000 | ✓ free, self-hosted: the cost is your own container ops | ✓ from $49 for 5,000 renders (0.98 cents), and a render is also spent per 30 seconds of render time and per 5Mb | ✓ per browser-time unit, not per document: $25 for 20,000 units, one unit being up to 30 seconds of browser time | ✓ 0.79 cents at 10,000 screenshots | ✓ 0.63 cents at 3,000 |
| Free tier | ✓ 50 renders a month, the full API, commercial use fine, the same 60-second timeout as paid | ✓ 50 a month with a 30-second timeout; a keyless trial gives 100 watermarked credits | ✓ 5 documents a month plus unlimited watermarked test documents | ✗ no hosted service at all: you run it | ✗ no free plan, by explicit policy | ✓ 1,000 units, sessions capped at 2 minutes | ✓ 100 screenshots | ✓ 50 a month |
| Calling modes: sync, async polling, webhooks | ✓ sync by default; a wait=false 202 ticket with poll and download URLs; HMAC-signed webhooks on Pro and Scale | ✓ sync by default; async needs a webhook; the spec has no polling endpoint (re-checked 2026-10-03) | ✓ sync, async with a status URL, and webhooks | ✓ webhooks; no polling | ✓ sync and async with a statusUrl; webhooks | ◐ /pdf and /screenshot answer synchronously; id polling exists on /crawl and /agent/run, not on document conversion | ✓ webhooks; no polling | ✓ webhooks; no polling |
| Wait controls | ✓ settle up to 10,000ms; waitFor on a css selector; waitForNetwork holds for a quiet network (networkidle) | ✓ delay; wait_for (selector or function name); wait_for_network | ◐ a page function (docraptorJavaScriptFinished) signals readiness; no millisecond delay | ✓ waitDelay and waitForExpression | ✓ wait_for and a millisecond delay | ✓ waitForSelector, waitForFunction, waitForTimeout | ✓ wait_for_selector and delay | ◐ a generation delay; no wait selector |
| Injection: css and javascript | ✓ css and javascript as inline strings, up to 20,000 characters each | ✓ css and javascript | ✗ no caller css or script; a prince_options javascript switch exists but takes no caller script | ✗ none | ✓ css and js | ✓ addStyleTag and addScriptTag | ✓ styles and scripts | ✗ none |
| PDF post-processing | ✓ a centered text watermark, metadata (title, author, subject, keywords), AES-256 encryption; encryption needs qpdf on the deployment and answers 503 without it | ✓ watermark, metadata, encryption | ◐ metadata and encryption; no watermark | ✓ watermark, encryption, metadata | ◐ metadata (pdf_title and friends); no watermark, no encryption | ✗ none of the three in the documented schema | ✗ none | ✗ none |
| Sandbox and test modes | ✓ a sandbox mode that spends no quota and stamps a watermark footer; the free web tool renders keyless and unwatermarked | ✓ a sandbox, plus a keyless trial of 100 watermarked credits | ✓ test mode with unlimited watermarked documents | ✗ nothing hosted: your container is the test bench | ◐ a sandbox, but it counts against the monthly quota | ◐ an API playground that needs your own token | not observed in their docs as of the 2026-10-03 check | ✓ |
| Source fetch controls (headers, cookies, auth) | ✓ custom headers, basic auth, and cookies pinned to the source hostname; the cookie jar never survives the render | ✓ http_headers, cookies, auth | ✓ | ✓ | ✓ header, cookie, authorization | ✓ setExtraHTTPHeaders, cookies, authenticate | ✓ | ✗ |
| Compliance posture (HIPAA) | ◐ a zero-residue phi mode is shipped and BAA-gated: it answers 403 until an executed BAA exists on the account; the BAA chain is not signed yet | ✓ is_hipaa with a BAA | ✓ HIPAA, SOC 2 and GDPR documented | not observed in their docs as of the 2026-10-03 check; nothing is hosted to certify, the data stays in your own containers | not observed in their docs as of the 2026-10-04 check; SOC 2 Type II and GDPR are documented | ◐ a security band on their pricing page advertises SOC 2 Type II, GDPR and an available HIPAA BAA (2026-10-04); the API spec names no HIPAA mode | ✗ | ✗ |
| Artifact retention and export | ✓ artifacts kept 7 days on free and pro, 30 on scale; export pushes to a caller-signed presigned PUT URL and no cloud credential is stored; sync base64 receipts on request | ✓ S3 delivery through customer credentials stored on their side; a filename turns the response into a JSON url with the file kept two days | ✗ no storage export | ✗ the bytes come straight back; nothing stored | ✓ use_s3 and s3_presigned_url storage options | ✗ no storage export | ✓ storage export | ✓ storage export |
| Self-hosting | ✗ hosted only; if you can host it yourself, Gotenberg below is the honest free answer | ✗ | ✗ | ✓ free and open source; you run the container and carry the ops | ✗ | ✗ | ✗ | ✗ |
| Stored templates | ✗ headers and footers are per-request HTML, not stored templates (see the own-gaps list below) | ✓ /templates CRUD plus generate | not observed in their HTTP reference (checked 2026-10-03) | ✗ | ✗ per-request header and footer HTML only, no template CRUD | ✗ | ✗ | ✓ list, get and update endpoints |
How the prices were read
One line per vendor, at or nearest the band a growing product actually buys at, straight from each vendor's published numbers with the check date on the row. The billable unit matters as much as the number: this service bills one rendered document of any size, PDFShift meters output size, Urlbox meters both render time and output size, and Browserless sells blocks of browser time, so a slow or heavy document changes their bill and not this one.
The headline gaps
A matrix with one honest column is worth more than a full one, so our own ✗ cells get their own list, each with the vendor that carries the capability today:
- PDF/A and PDF/UA conformance: if you need archival or accessibility conformance, DocRaptor or self-hosted Gotenberg carry it today.
- HTML output (markdown yes, HTML no): ScreenshotOne, Urlbox and Browserless all document an html output on their APIs.
- Stored template APIs: APITemplate and CraftMyPDF are template-first tools; the stored template is their product, not a bolt-on.
- PDF merge: Api2Pdf or Gotenberg merge PDFs after the render.
- E-invoice output (ZUGFeRD, Factur-X): APITemplate's einvoice path is built for it.
- Image formats beyond png, jpeg and webp (gif, jp2, tiff, avif, heif): ScreenshotOne carries all five.
- A signed HIPAA BAA: not offered until the operator program completes; DocRaptor and pdfshift carry BAAs today.
- An engine version pin and a caller-set timeout: pdfshift exposes both.
Where to go next
Deep on PDFShift? webcapture vs PDFShift prices the two rate cards against each other and the migration manual moves a script in one line. Shopping at zero? the free HTML to PDF API page prices the $0 route in detail. The full parameter surface is in the docs and every price is on the pricing page.
Method
Every cell was read from the vendor's own documentation before it was written: PDFShift's OpenAPI spec and live docs (re-checked 2026-10-03), DocRaptor's API reference, Gotenberg's routes and modules, Urlbox's options reference (2026-10-04), Browserless's OpenAPI spec (2026-10-04), ScreenshotOne's options table, and APITemplate's API reference; webcapture's rows come from our own docs and rate card. Checked 2026-10-05; webcapture's Pro and Scale prices checked 2026-10-24.
- webcapture: API documentation; pricing.
- PDFShift: API documentation; pricing.
- DocRaptor: API documentation; pricing.
- Gotenberg: API documentation.
- Urlbox: API documentation; pricing.
- Browserless: API documentation; pricing.
- ScreenshotOne: API documentation; pricing.
- APITemplate.io: API documentation; pricing.
Corrections and missing-row reports go to hello@webcapture.io.
Render your first page in seconds
Mint a key, POST a URL, and the finished document comes back in the same response; pass ?wait=false for a job ticket with poll and download URLs. The first 50 renders a month are free, and there is no credit card. Not ready for a key? The free URL to PDF tool renders public pages without one.