Website profiles · Technology insights · Alternatives

doppio.sh

Generate PDFs and screenshots from HTML without running Puppeteer. Managed Chromium, direct S3 upload, webhooks, templates, and EU-hosted infrastructure.

Paid content
Visit website
Profile views 0 Outbound visits 0 Normal
Doppio Full homepage screenshot

At a glance

Category
Development
Language
English
Paid-content signal
Paid contentObserved
Registered
Unknown
Hosting
CloudflareInferred
HTTPS certificate trusted
PassedObserved
Last updated

Website review

This review may include AI-generated content and is not individually verified. Domain, certificate and other facts come from the observed data on this page.

What is Doppio?

Doppio is a hosted API that turns HTML, templates, or live app routes into PDFs and PNG screenshots, so you don't have to run and maintain your own headless Chromium or Puppeteer infrastructure. According to its site, it renders with a modern Chromium engine, supports Flexbox, Grid, webfonts, JavaScript, charts and Paged.js, and offers direct S3 upload, asynchronous renders with webhooks, and EU-hosted infrastructure. See Doppio.

Who it's for

  • Product and engineering teams that already generate documents (invoices, reports, booklets, statements) and want to drop a rendering stack they'd otherwise patch, scale and monitor.
  • Teams migrating off wkhtmltopdf, self-hosted Puppeteer, or PDF libraries that struggle with modern CSS or heavy pages.
  • Teams with data-residency needs, since the site emphasizes EU hosting and isolated renders.

What it does, concretely

The basic flow is one API call: send HTML or a URL, get back a PDF or PNG. From there, you can use templates with dynamic data, push finished files straight to your own S3-compatible bucket, or run long renders in the background and receive a webhook when they're done. The same API produces both PDFs and screenshots, which helps if you need, say, a report PDF and a share-image from the same page.

Trade-offs to weigh

A managed service like this trades control for lower operational burden. You avoid running browsers, but you depend on the provider's rendering engine version, its latency, and its availability (the site claims 99.995% uptime last year). If your documents require unusual browser flags, custom fonts installed at the OS level, or strict on-premise processing, self-hosting may still fit better.

A practical next step

Pick one real document your app already produces—ideally a heavy one with charts or custom fonts—and render it through the API's free tier before committing. Compare it against your current output for layout fidelity, render time, and how easily files land in your storage. If you also need screenshots or webhook-driven batch jobs, confirm those paths work in the same test rather than assuming they will.

How does Doppio compare to self-hosting Puppeteer or using wkhtmltopdf?

Doppio is a managed HTML-to-PDF and screenshot API positioned to replace both self-hosted Puppeteer and wkhtmltopdf. The trade-off is control: Doppio removes browser infrastructure and rendering quirks, while self-hosting keeps you in full control at the cost of maintenance.

What each option is best at

Option Rendering engine Who runs it Best fit Main trade-off
Doppio Modern Chromium, managed Vendor (EU-hosted infrastructure according to the site) Product teams that want one API call for PDFs and PNGs without a browser fleet Less low-level control; depends on a third-party service
Self-hosted Puppeteer Modern Chromium, you operate it Your team Teams needing custom browser behavior, internal-only rendering, or strict data residency they control You patch Chromium, tune autoscaling, and babysit render workers
wkhtmltopdf Older WebKit-based engine Your team Legacy pipelines with simple, static HTML Weak support for modern CSS like Flexbox and Grid, webfonts, and JavaScript-heavy pages

Where the differences show up

Rendering fidelity. Doppio states that Flexbox, Grid, webfonts, charts, JavaScript, and Paged.js work out of the box. Self-hosted Puppeteer can match this because it is also Chromium, but you own versioning and dependencies. wkhtmltopdf is the weakest here for modern layouts.

Operations. Doppio advertises no Chromium fleet to patch, no autoscaling to tune, and no render workers to manage, and cites 99.995% uptime last year. Self-hosting means handling traffic spikes, memory limits on heavy pages, and browser crashes yourself.

Delivery and workflow. Doppio lists direct S3 upload via presigned URLs, async rendering with webhooks, and template-based generation with dynamic data injection. With Puppeteer or wkhtmltopdf you build these pieces yourself, though Puppeteer gives you maximum flexibility to customize them.

Data handling. Doppio describes isolated renders, EU-hosted infrastructure, and privacy-first defaults. If you need documents to stay entirely within your own network, self-hosted Puppeteer remains the straightforward choice.

A practical next step

Pick based on your document complexity and team capacity. If your PDFs use modern CSS, charts, or client-side JavaScript and you do not want to run browser infrastructure, start with Doppio's free tier of 400 documents per month and test a representative template. If you have strict internal-only requirements or need deep browser customization, keep Puppeteer. Reserve wkhtmltopdf for simple legacy documents you are not ready to migrate. For a second managed option to compare against, see DocRaptor.

How do I generate my first PDF from HTML using the Doppio API?

Send one authenticated POST to Doppio's sync render endpoint with a JSON body that tells it what to load and that you want a PDF back. In the page's own example, the request goes to https://api.doppio.sh/v1/render/pdf/sync with a Bearer token, and the body sets page.pdf.printBackground to true and gives a page.goto.url pointing at the HTML page to render, waiting until networkidle0 so late-loading assets finish.

A practical first run

  1. Put your HTML somewhere reachable by URL (a staging route, a signed URL, or a Doppio template) rather than pasting large markup on the first attempt.
  2. Keep the first payload minimal: the URL, printBackground: true, and the wait condition. Add headers, viewport or margins only after you see a clean result.
  3. Check the returned PDF for the things that usually break: webfonts, background colors, charts drawn by JavaScript, and page breaks.
  4. Then move to your real workflow — async rendering with a webhook for heavy pages, or direct upload to your own S3 bucket via presigned URLs if you don't want files passing through your app.

Choosing between sync and async

Situation Better fit Why
Short page, user waiting on a download Sync call One request, response in seconds
Long report, charts, many pages Async + webhook Avoids request timeouts; you get called back when ready
Large files you store yourself Direct S3 upload File lands in your bucket, not routed through your server

For a first test, a short invoice-style page with a webfont and a background color is a good probe: it exercises the fidelity claims (Flexbox, Grid, webfonts, JavaScript, Paged.js) without a long render. If your team already runs headless Chrome, compare the effort of patching a Chromium fleet and tuning autoscaling against a single API call — that operational trade-off, plus EU hosting and isolated renders for sensitive documents, is the main reason the page says teams switch.

Next step: read the quickstart on Doppio and run the example call against a test page before wiring it into production.

Can Doppio upload generated PDFs directly to my own S3 bucket?

Yes. Doppio can push generated PDFs straight to your own S3 bucket using presigned URLs, so the file lands in storage you control rather than being routed through your app first. The site describes this as "direct S3 upload" and lists it alongside webhooks and EU-hosted infrastructure as a core capability.

What this changes in practice

  • Your app stays lean. You request a render, and the output goes to your bucket. You avoid building a download-then-reupload step, which matters when documents are large or produced in bursts.
  • Your storage rules still apply. Because delivery uses presigned URLs, access is scoped to the bucket and credentials you configure. Retention, encryption and lifecycle policies remain yours to set.
  • It pairs well with async rendering. For heavy pages or high volume, you can run renders in the background and use a webhook to learn when the file is ready in S3, instead of holding a request open.

A concrete scenario

An invoicing team generates month-end statements for thousands of customers. They render asynchronously, have each PDF written directly to their bucket, and receive a webhook per completed batch. A separate job then emails signed links from their own storage. No PDF bytes pass through the application servers.

When direct upload is the wrong fit

If you need to post-process files in memory before storage — watermarking, merging, virus scanning — a direct-to-bucket flow adds a retrieval step. In that case, returning the file to your service first may be simpler.

Next step: confirm the exact S3-compatible targets and credential setup in the Doppio documentation, then test one render against a non-production bucket before wiring it into a live workflow. For broader context on managed rendering APIs, see Doppio.

How does Doppio handle asynchronous rendering and webhooks for complex documents?

Doppio treats async rendering as a background job: you submit a render request, and instead of holding the HTTP connection open, the service processes it and calls back to a URL you specify when the file is ready. This is aimed at heavy or slow documents—long reports, chart-heavy pages, or HTML that needs extra time for JavaScript and fonts to settle—where a synchronous request could time out or block your app.

How the pieces fit

  • Sync vs. async: The page's example uses the synchronous endpoint (/render/pdf/sync) for a quick one-call render. Async is the alternative for complex jobs, where you fire the request and move on.
  • Webhooks: You register a callback URL, and Doppio notifies it once the render completes, so your system reacts to the finished document rather than polling.
  • Direct S3 upload: Output can be pushed straight to your own bucket via presigned URLs, so the webhook can signal "done" while the file lands in your storage rather than passing through your app.
  • Templates: Dynamic data can be injected into saved templates, which suits batch or per-user documents generated in the background.

A concrete scenario

A billing team generates monthly statements: hundreds of multi-page PDFs with charts and webfonts. Rather than looping sync calls that may stall, they submit each render asynchronously, let Doppio upload results to their S3 bucket, and use the webhook to mark each statement as ready in their database and trigger an email. The webhook becomes the handoff point between rendering and delivery.

Decision criteria

Situation Better fit
Single short document, user waiting Sync endpoint
Long or JS-heavy render, many at once Async + webhook
Files should live in your own storage Direct S3 upload
Per-user or batched documents Templates with data injection

One practical caution: webhook-driven flows need idempotent handlers and retry logic, since callbacks can arrive more than once or after a delay. Treat the webhook as a notification, then verify the object exists in S3 before acting. For teams weighing alternatives, DocRaptor and PDFShift also offer HTML-to-PDF APIs worth comparing on async and storage behavior.

Is Doppio's infrastructure EU-hosted and suitable for sensitive document workflows?

Yes. Doppio states that its infrastructure is EU-hosted and privacy-first, and it lists isolated renders and direct S3 upload as ways to keep sensitive document workflows under control. For a team handling contracts, invoices or HR letters, that combination is the relevant claim: rendering happens on managed infrastructure rather than on your own Chromium fleet, and output can go straight to a bucket you control.

What the page supports, and what it does not

  • EU hosting: explicitly stated as a product feature.
  • Isolation: "isolated renders" is mentioned as part of the sensitive-document story.
  • Storage control: presigned uploads push files to your own S3-compatible bucket, so you decide where finished documents live.
  • Not stated: specific data-retention periods, subprocessor lists, or a named compliance certification. If your workflow falls under GDPR obligations or sector rules, confirm those details directly before relying on the hosting claim alone.

A practical test

Take one real document type with personal data, render it through the API, and verify three things: where the file lands, how long any intermediate copy exists, and whether your legal team accepts the hosting region. That check matters more than the marketing summary. Teams comparing managed rendering options may also look at DocRaptor or PDFShift for regional and compliance differences, but confirm each provider's own documentation rather than assuming parity.

Related questions

More questions →
PDF Invoices in Legal Billing: What to Include and When to Use Them

A PDF invoice in legal billing is a fixed-format document that presents the fees and costs owed on a matter in a layout that looks the same on every device. It is the digital equivalent of a printed bill: readable, portable, and easy to attach to an email or upload to a client portal. Its main limitation is that it is not machine-readable in the way a LEDES file is, so a client's e-billing system cannot automatically ingest it. PDF works best for flat-fee matters, small or one-off engagements, and clients who do not run an automated billing platform.

What "PDF" means in a legal billing context

When a billing tool offers to send an invoice "in PDF," it is generating a rendered document rather than a structured data file. The distinction matters:

  • PDF is a presentation format. A human reads it. Line items, totals, and matter details appear as text and tables on a page.
  • LEDES (Legal Electronic Data Exchange Standard) is a structured, delimited text format. An e-billing system parses it, validates it against outside counsel guidelines, and routes it for review.
  • Email delivery is a transport method, not a format. You can email a PDF, email a LEDES file, or email a link to an online invoice.

These three are often confused because a single invoice can combine them: a LEDES file delivered by email, or a PDF attached to an email. The format is what the client's systems can read; the delivery method is how it arrives.

When a PDF invoice is the right choice

PDF is usually appropriate when the client does not require electronic submission through a billing platform. Common scenarios:

  • Flat-fee and fixed-price matters. When the invoice is one or two lines, a structured file adds no value.
  • Small businesses and individuals. Clients without an accounts payable system can open a PDF and pay from it.
  • Retainers and replenishment requests. A simple statement of the retainer balance is easy to read as a PDF.
  • Pro bono or courtesy bills. Where no formal e-billing review applies.
  • Backup documentation. Even when a LEDES file is submitted, a PDF is often attached for the reviewer's convenience.

If the client has outside counsel guidelines requiring LEDES submission, a PDF alone will typically be rejected or returned for manual entry. Check the client's billing requirements before choosing the format.

PDF versus LEDES versus emailed invoice: a quick comparison

Factor PDF LEDES Email (as delivery)
Machine-readable No Yes N/A
Accepted by e-billing platforms Rarely Yes Depends on attachment
Setup effort Low Higher (mapping fields) Low
Best for Flat fees, small clients, backup Corporate and insurer clients Any format
Risk Manual re-entry by client Format rejection if fields are wrong Lost or filtered messages

Core elements of a compliant legal PDF invoice

A PDF invoice should stand on its own. If a client's AP department picks it up with no context, it should still answer who, what, when, and how much.

Firm and client identification

  • Firm name, address, and contact details
  • Tax or VAT identification number where applicable
  • Client name and billing contact
  • Invoice number and invoice date
  • Client matter number or reference

Matter and timekeeper detail

  • Matter name and description
  • For each timekeeper: name, initials, and billing rate
  • Time entries with date, narrative description, and time recorded in tenths of an hour
  • Clear separation of fee earners if rates differ

Fees, expenses, and totals

  • Fees subtotal
  • Disbursements and expenses, itemized with dates
  • Taxes applied
  • Prior payments, credits, or trust retainer applied
  • Total amount due and currency

Payment terms

  • Due date and payment window
  • Accepted payment methods
  • Remittance details or a payment link
  • Late-payment terms if the engagement letter specifies them

A useful test: hand the PDF to someone who has never seen the matter and ask them to confirm the amount due and the period covered. If they hesitate, the invoice is missing something.

Practical limitations to plan around

PDF invoices shift work to the recipient. Someone at the client has to read the document and key the data into their system, which introduces delay and transcription errors. PDFs also cannot be validated against billing guidelines automatically, so a reviewer may reject a line item that a LEDES rule would have caught before submission.

Two habits reduce the friction:

  1. Send a consistent template. Clients learn where to find the total, the matter number, and the payment terms.
  2. Keep a LEDES version in reserve. If a client later adopts an e-billing platform, you can convert rather than rebuild.

Choosing between PDF, LEDES, and email delivery

Work from the client's requirements backward:

  • Does the client mandate LEDES submission? If yes, PDF is a supplement, not a substitute.
  • Is the matter flat-fee or very small? PDF is usually sufficient.
  • Does the client have no billing system? PDF delivered by email or portal is the simplest path.
  • Is the invoice complex with many timekeepers and expenses? A structured format reduces disputes, even if the client accepts PDF.

When in doubt, ask the client's billing contact which format they prefer and whether a PDF attachment is acceptable alongside any required file. That one question prevents most rejected invoices.

Easy Legal Billing supports sending or scheduling invoices in LEDES, email, or PDF formats, which lets you match the format to each client's requirements rather than forcing one approach across every matter.

What Is a PDF Generation API and How Do You Use One?

A PDF generation API takes HTML, a URL, or template data and returns a rendered PDF file, so you don't have to run a headless browser yourself. Use one when you need reliable, pixel-accurate documents (invoices, reports, booklets) at variable volume and would rather not operate a Chromium fleet. Doppio, for example, exposes a single render endpoint, supports direct S3 upload and async webhooks, and offers a free tier of 400 documents/month with no credit card required.

What the API actually does

You send a payload describing the page to render; the service runs it through a modern Chromium engine and hands back a PDF (or a PNG screenshot from the same API). The core inputs are:

  • Source: raw HTML, a URL to load, or a saved template with injected data.
  • Render options: things like printBackground, and navigation options such as waitUntil: ['networkidle0'] so the render waits for resources to settle.
  • Delivery: the response itself, a webhook callback, or a push to your own S3-compatible bucket via presigned URLs.

Doppio's docs describe this as "one API call" from HTML or a URL to a production-ready file, with Flexbox, Grid, webfonts, charts, JavaScript, and Paged.js supported out of the box.

Managed API vs. self-hosted Puppeteer or wkhtmltopdf

The decision usually comes down to operations burden versus control.

Dimension Managed PDF API (e.g., Doppio) Self-hosted Puppeteer / wkhtmltopdf
Infrastructure Vendor runs managed Chromium You patch, scale, and monitor browsers and workers
Scaling Handled by the provider You tune autoscaling and render workers
Rendering fidelity Modern Chromium; CSS/JS/webfonts supported Depends on your version; wkhtmltopdf lags on modern CSS
Delivery options Response, webhook, direct S3 upload You build each path
Data handling Isolated renders; EU-hosted option Fully under your control
Cost model Per-usage (check current pricing) Engineering time plus compute

Choose the managed API when document generation is not your core product and traffic spikes or heavy pages would otherwise require babysitting render workers. Choose self-hosting when you need full control over the runtime or have constraints the vendor can't meet. Doppio states it is EU-hosted and privacy-first, which matters if document residency is a requirement.

The typical request flow

  1. Authenticate with a bearer token in the Authorization header.
  2. Build the payload with a page object containing pdf options and a goto block (URL plus navigation options), or a template reference.
  3. Choose sync or async: a synchronous call returns the file; async runs complex renders in the background and calls your webhook when done.
  4. Deliver the result to your app, a webhook workflow, or S3-compatible storage.

A minimal synchronous call, based on Doppio's published example:

const response = await fetch('https://api.doppio.sh/v1/render/pdf/sync', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer <YOUR_API_KEY>',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    page: {
      pdf: { printBackground: true },
      goto: {
        url: 'https://example.doppio.sh/information-booklet.html',
        options: { waitUntil: ['networkidle0'] }
      }
    }
  })
});

Expected result: a PDF response you can save or stream. Verify by opening the file and checking that backgrounds, fonts, and any charts rendered.

What to check before adopting

  • CSS/JS and webfont support: confirm your layout (Grid, Flexbox, custom fonts, client-side charts) renders correctly; test a representative page, not a toy one.
  • Isolation and hosting region: ask whether renders are isolated and where data is hosted, especially for sensitive documents.
  • Delivery paths: verify webhook reliability and S3 presigned-URL upload if you need files in your own bucket.
  • Pricing and limits: check the pricing page for current tiers; Doppio advertises 400 documents/month free and 99.995% uptime last year, but confirm terms before committing.
  • Scale signals: Doppio cites 50M+ documents per year across 4000+ teams—useful context, not a guarantee for your workload.

Troubleshooting common render failures

  • Blank or partial pages: resources hadn't loaded. Use waitUntil: ['networkidle0'] or wait for a specific selector.
  • Missing backgrounds or images: enable printBackground and confirm assets are reachable from the render environment (not behind auth).
  • Fonts wrong: ensure webfonts load over the network or are embedded; test with the exact font files you ship.
  • Timeouts on heavy pages: move to the async endpoint with a webhook instead of holding a synchronous connection.

Start with one real document, confirm fidelity and delivery, then scale volume—rather than building a rendering stack you'd have to maintain.

What Is OpenAPI-Generated API Documentation and How Does It Work?

OpenAPI-generated API documentation is reference documentation that is produced automatically from an OpenAPI description file rather than written by hand. You write (or generate) a machine-readable specification of your API — endpoints, parameters, request bodies, responses, schemas, and auth — and a documentation tool reads that file and renders a browsable, often interactive reference site. The spec becomes the single source of truth; the docs become a build artifact.

This differs from manually written docs in one fundamental way: with hand-written docs, the prose is the source of truth and the API is described separately. With spec-driven docs, the API description is the source, and every page, table, and code sample is derived from it.

How the workflow actually runs

A typical spec-driven documentation pipeline has five stages:

  1. Author or generate the spec. You either write an OpenAPI document by hand (YAML or JSON), or generate it from code annotations, framework metadata, or a design-first editor. Design-first means the spec is written before implementation; code-first means it is extracted from existing code.
  2. Validate and lint. The spec is checked against the OpenAPI schema and against style rules — consistent naming, required descriptions, no undocumented 4xx responses, no orphaned schemas.
  3. Bundle and transform. Multi-file specs are combined, $ref pointers are resolved, and the document is optionally split into per-tag or per-version outputs.
  4. Render. A documentation tool converts the spec into HTML: an endpoint list, a sidebar of operations, parameter tables, response schemas, and a "try it" console.
  5. Publish and version. The rendered site is deployed, and each API version gets its own snapshot so consumers can read docs matching the version they call.

Steps 2 through 5 are usually automated in CI. If the spec fails validation, the docs build fails — which is the point.

Spec-driven vs. hand-written documentation

Dimension OpenAPI-generated Hand-written
Source of truth The spec file The prose
Consistency with the API High, if the spec is accurate Drifts as the API changes
Effort per endpoint Low after setup Repeated for every endpoint
Narrative and tutorials Weak; needs separate pages Strong
Code samples Generated per language from schemas Written and maintained manually
Customization Bounded by the tool's templates Unlimited
Failure mode Accurate spec, poor docs, or stale spec Beautiful docs that describe an API that no longer exists

The practical conclusion most teams reach: generate the reference, write the guides. Reference material is repetitive and mechanical, which is exactly what generation is good at. Conceptual explanations, migration notes, and tutorials carry judgment that a spec cannot express.

What you get out of the box

Generated reference pages commonly include:

  • An operation list grouped by tag or path, with HTTP method and path.
  • Parameter tables showing name, location (path, query, header, cookie), type, required flag, and description.
  • Request and response schemas rendered as expandable trees, including nested objects and arrays.
  • Authentication details pulled from the securitySchemes section.
  • Interactive request consoles that let a reader send a real call from the browser.
  • Generated code samples in several languages, derived from the same schemas.
  • Multiple output formats, such as a static site, a single HTML file, or a mock server.

Because all of these come from one document, changing a field name in the spec updates the parameter table, the schema tree, and every code sample at once.

Where spec-driven documentation breaks down

Generation is not free. The trade-offs are real:

Spec quality becomes documentation quality. A field with no description produces a table row with an empty cell. A vague summary produces a vague heading. Tools can enforce presence of descriptions via linting, but they cannot enforce that the description is useful.

Customization has limits. If you need a page that does not map to an OpenAPI concept — a conceptual overview, a pricing explanation, a comparison of two endpoints — you write it outside the generator and link to it.

Not everything is expressible. Webhooks, streaming responses, long-polling behavior, and complex multi-step flows are awkward or impossible to describe fully in OpenAPI. Those need prose.

The spec can go stale. If the spec is maintained separately from the implementation, it drifts just like hand-written docs. The mitigation is to generate the spec from code, or to test the implementation against the spec in CI.

Interactive consoles need care. A "try it" button that hits a production API with real credentials is a security and rate-limit problem. Point it at a sandbox, or disable it.

Deciding whether to adopt it

Adopt spec-driven reference documentation if most of these are true:

  • Your API has more than a handful of endpoints, or changes frequently.
  • You ship client SDKs or code samples in more than one language.
  • Multiple teams consume the API and need a consistent, always-current reference.
  • You already have, or are willing to maintain, an OpenAPI description.

Stay with hand-written docs, or a hybrid, if:

  • Your API is small and stable, and the reference fits on one page.
  • Your documentation is mostly conceptual and contains little endpoint-level detail.
  • You cannot commit to keeping the spec in sync with the implementation.

A reasonable middle path: generate the reference from the spec, and hand-write the getting-started guide, authentication walkthrough, and error-handling page. Link the two directions so readers can move from concept to endpoint and back.

A minimal starting checklist

  1. Produce one valid OpenAPI document for a single API version.
  2. Add a linter with rules for descriptions, operation IDs, and error responses.
  3. Wire the docs build into CI so a failing spec fails the build.
  4. Render the reference and review it as a reader, not as the author.
  5. Write the two or three conceptual pages the generator cannot produce.
  6. Version the published docs alongside the API version.

The core idea is simple: describe the API once, in a format both machines and humans can read, and let the reference documentation fall out of that description. Everything else — tooling, hosting, interactivity — is a detail on top of that decision.

What Is an HTML to PNG API and How Does It Work?

An HTML to PNG API is a hosted rendering service that accepts HTML markup or a URL, renders it in a managed headless browser, and returns a PNG image. Use one when you need repeatable, pixel-accurate screenshots of pages you don't control the browser for — invoices, dashboards, social cards, report snapshots — without operating your own Chromium fleet. Doppio, for example, exposes a render endpoint that accepts a page configuration with a target URL and returns the rendered file; the same API also produces PDFs, so PNG screenshots and documents can share one integration.

The core workflow

Every HTML to PNG API follows the same three-stage pattern:

  1. Input — you send either raw HTML (often a template with injected data) or a URL for the service to load.
  2. Render — the service loads the page in a real browser engine, executes CSS, JavaScript, and webfonts, and waits for the page to reach a stable state.
  3. Output — you receive a PNG, either in the API response (synchronous) or delivered later to your app, a webhook, or object storage.

In Doppio's API, the request body carries a page object. For a PDF render the example sets page.pdf.printBackground and page.goto.url with a waitUntil option of networkidle0; the PNG path uses the same goto targeting with an image output instead of pdf. The waitUntil value is the single most important input for image quality — it tells the renderer when the page is "done."

What determines output quality

The rendered PNG is only as good as the browser's ability to finish the page before capture. Four factors dominate:

  • CSS and layout engine. Modern Chromium handles Flexbox, Grid, webfonts, charts, and JavaScript, per Doppio's documentation. Older engines (wkhtmltopdf) frequently break on modern layout, which is why teams migrate.
  • JavaScript execution. Client-side charts and lazy-loaded content need time to run. If the capture fires before scripts finish, you get blank regions.
  • Webfonts. Custom fonts load asynchronously; a capture taken too early falls back to system fonts and shifts layout.
  • Viewport and device pixel ratio. The viewport width determines responsive breakpoints, and the pixel ratio determines sharpness. A narrow viewport can trigger a mobile layout you didn't intend; a ratio of 1 produces soft text on high-DPI displays.

Synchronous vs. asynchronous rendering

Mode How it works Best for Trade-off
Synchronous Request blocks until the PNG is returned Small, fast pages; interactive previews Timeouts on heavy pages
Asynchronous + webhook Request returns immediately; the service calls your endpoint when the file is ready Complex renders, batch jobs, traffic spikes You must handle callbacks and retries

Doppio supports both: synchronous rendering for quick jobs and async with webhooks for "complex renders in the background," plus direct upload to your own S3 bucket via presigned URLs. Choose async when pages are heavy or when you're generating many images at once — a synchronous call that exceeds the timeout returns nothing useful.

Selection criteria

When comparing HTML to PNG APIs, check the same dimensions for each:

  • Fidelity — does it run a current Chromium engine with JavaScript, webfonts, and modern CSS?
  • Capture scope — can you take a full-page screenshot as well as a fixed viewport? Confirm the option exists before committing.
  • Delivery — response body, webhook, or direct-to-storage. Direct S3 upload avoids routing large binaries through your app.
  • Wait controls — configurable waitUntil conditions (e.g., networkidle0) and explicit delays for animation-heavy pages.
  • Privacy and hosting — isolated renders and EU-hosted infrastructure matter if screenshots contain customer data. Doppio advertises EU-hosted, privacy-first defaults.
  • Operational load — a managed service removes Chromium patching, autoscaling, and render-worker maintenance.

Doppio's published figures — 400 free documents per month, no credit card required, 99.995% uptime last year, 4,000+ teams — are useful signals, but verify current limits and pricing on its pricing page before relying on them.

Troubleshooting blank, clipped, or incomplete PNGs

Most bad screenshots trace to one of these causes:

  • Blank image — the capture fired before the page rendered. Set waitUntil to networkidle0 or add an explicit delay after load.
  • Missing assets — images, fonts, or stylesheets blocked by authentication or CORS. If rendering a private URL, ensure the service can reach it; otherwise render from HTML with assets inlined or publicly hosted.
  • Clipped content — the viewport is smaller than the page. Request a full-page capture or set the viewport to the content's dimensions.
  • Wrong layout — the viewport width triggered an unintended breakpoint. Match the viewport to the device you're emulating.
  • Soft or blurry text — device pixel ratio too low. Increase it for retina-quality output.
  • Timeout on sync calls — the page is too heavy. Switch to async with a webhook.

A practical check: render the same page twice, once with a short wait and once with networkidle0. If the outputs differ, your wait condition is the problem, not the API.

What Is an HTML to PDF API and When Should You Use One?

An HTML to PDF API is a hosted service that accepts HTML markup or a URL, renders it in a managed browser engine, and returns a finished PDF. Use one when you need reliable, pixel-accurate documents (invoices, reports, statements, booklets) but don't want to build and operate a Chromium rendering fleet yourself. Doppio, for example, renders HTML with managed Chromium and delivers PDFs or PNG screenshots from a single API call, with direct S3 upload, async webhooks, and EU-hosted infrastructure.

How the core workflow works

The pattern is the same across providers:

  1. You send a request containing either raw HTML or a URL to a page your app already serves.
  2. The service loads that page in a real browser engine, waits for the conditions you specify (network idle, specific selectors, fonts), and prints it to PDF.
  3. You receive the file in the response, at a webhook callback, or directly in your own storage bucket.

Because the renderer is a modern Chromium build, CSS features like Flexbox and Grid, webfonts, JavaScript-driven charts, and pagination libraries such as Paged.js work without extra configuration. That fidelity is the main reason teams move away from older converters.

Managed API vs. self-hosted Puppeteer or wkhtmltopdf

Dimension Managed HTML to PDF API Self-hosted Puppeteer wkhtmltopdf
Ops burden None; provider patches and scales Chromium You patch Chromium, tune autoscaling, babysit render workers You maintain the binary and its dependencies
Rendering fidelity Modern Chromium: Flexbox, Grid, webfonts, JS, charts Modern Chromium, but you own the configuration Dated engine; modern CSS often breaks
Scaling Handled by provider during traffic spikes Your responsibility; heavy pages strain workers Your responsibility; limited concurrency
Isolation Isolated renders per job You must design isolation yourself Process-level isolation only
Best fit Teams that want documents without browser infrastructure Teams with strict control or existing browser infra Legacy pipelines with simple HTML

Choose a managed API when document generation is a feature, not your core infrastructure. Choose self-hosted Puppeteer when you already run browser automation at scale and need full control. Treat wkhtmltopdf as a legacy option only for simple, static markup.

The three integration patterns

Synchronous calls suit interactive or low-latency needs: send the request, get the PDF back in the same response. Doppio's sync endpoint (/v1/render/pdf/sync) works this way.

Async jobs with webhooks suit complex or heavy renders. You submit the job, the service renders in the background, and your endpoint is called when the file is ready. This avoids holding connections open for slow pages.

Direct S3 upload pushes the finished file straight to your own bucket using presigned URLs, so large documents never pass through your application servers.

A minimal first request

You need an API key, a page URL (or inline HTML), and a few print options. This example renders a hosted page to PDF with background graphics enabled and waits until network activity settles:

const response = await fetch('https://api.doppio.sh/v1/render/pdf/sync', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    page: {
      pdf: { printBackground: true },
      goto: {
        url: 'https://example.doppio.sh/information-booklet.html',
        options: { waitUntil: ['networkidle0'] }
      }
    }
  })
});
  • printBackground: true keeps background colors and images, which are dropped by default in print output.
  • waitUntil: ['networkidle0'] tells the renderer to wait until network requests have quieted, so late-loading fonts, images, and chart scripts appear in the PDF.

Verify success by checking the response status and opening the returned file: confirm fonts loaded, charts rendered, and page breaks fall where you expect. If you use webhooks, confirm your endpoint received the callback and the file landed in storage.

Common failure points to check

  • Authentication errors (401/403): confirm the Authorization header uses Bearer followed by a valid key, with no stray whitespace.
  • Render timeouts: heavy pages or long-running scripts exceed limits. Trim client-side work, or switch to an async job with a webhook.
  • Missing fonts or assets: relative asset paths break when rendering a URL from a different origin. Use absolute URLs or inline critical CSS and fonts.
  • Blank or unstyled output: background graphics are off by default in print; set printBackground and verify waitUntil covers your slowest resource.
  • Webhook delivery issues: make sure your endpoint is publicly reachable, responds quickly with a 2xx, and handles retries idempotently.

When to use one

Adopt an HTML to PDF API when you generate documents from templates or app routes, need modern CSS fidelity, and would rather not run browser infrastructure. Doppio's published figures—50M+ documents per year across 4,000+ teams and 99.995% uptime last year—describe the scale it is built for, and its free tier of 400 documents per month with no credit card required is enough to validate a first integration. Check the pricing page for current plan details before committing to production volume.

Website Overview

Page metadata, canonical configuration and social previews work together to provide more consistent search and sharing presentation.

Domain and Registration

Unknown

DNS and Email

Nameservers are provided by Cloudflare, indicating managed DNS hosting. MX records point to the infomaniak.ch email service. No CNAME was found; the observed records resolve directly to addresses. SPF and DMARC are configured. DKIM status is unknown. TXT records include verification markers for Google. Such markers may also remain after a service stops being used.

TLS and Certificates

The public key uses EC with 256 bits. The server supplied a complete certificate chain. No organization name is present in the certificate; the available fields are consistent with domain validation. The certificate was issued within the Google Trust Services cloud or CDN ecosystem. The certificate's total validity is about 90 days, consistent with a short renewal cycle.

HTTP and Browser Security

The response lacks these common security headers: HSTS, CSP, Permissions-Policy. No X-Powered-By header was found, reducing one common source of backend fingerprinting information. The cf-ray response header indicates a CDN or caching proxy in the delivery path. No obvious internal addresses or debug information were found in the headers. The Server header identifies cloudflare without an exact version.

Technology Stack Analysis

The public page identifies Cloudflare without precise versions, leaving fewer clues for version-specific scanning.

Search and Social Sharing

Twitter Card metadata is configured. JSON-LD includes Organization data, helping describe the organization as an entity. The page declares 1 language or regional alternatives using hreflang. The title has 55 characters, within a common display range. A meta description is present, with 153 characters.

Hosting and Email

DNSCloudflare
HostingCloudflare
Emailinfomaniak.ch
Approximate IP geolocation (inferred; a CDN or proxy may differ from the origin server) Location unknown Inferred 104.21.89.23

Registration details

RDAP / WHOIS

Unknown

DNS records

DNS

TypeNameValueTTLPriority
Adoppio.sh104.21.89.23300—
Adoppio.sh172.67.136.82300—
AAAAdoppio.sh2606:4700:3030::6815:5917300—
AAAAdoppio.sh2606:4700:3031::ac43:8852300—
MXdoppio.shmta-gw.infomaniak.ch3005
NSdoppio.shjake.ns.cloudflare.com86400—
NSdoppio.shlila.ns.cloudflare.com86400—
TXTdoppio.shbrevo-code:dcb53029d2061553ccf67f7e5bad7f9d300—
TXTdoppio.shgoogle-site-verification=VJBGIP06Hjw1L4_pnDyoOvQovTKbZGWe3MDeKSSzIzk300—
TXTdoppio.shv=spf1 include:spf.infomaniak.ch -all300—
DMARC_dmarc.doppio.shv=DMARC1; p=reject;300—

TLS and certificates

TLS / SSL

AssessmentNormal configuration
Supported protocolsTLSv1.2、TLSv1.3
Negotiated protocolTLSv1.3
Certificate subjectdoppio.sh
IssuerGoogle Trust Services
Valid until2026-12-16T12:30 · Remaining when checked: 50 days
Verification detailsCertificate trust: Passed · Hostname match: Passed

HTTP response headers

HTTP

HeaderValue
content-typetext/html
cache-controlpublic, max-age=0, must-revalidate
servercloudflare
x-frame-optionsSAMEORIGIN
x-content-type-optionsnosniff
referrer-policysame-origin

Identified technologies

Cloudflare

Pages, Search and Sharing

Meta descriptionGenerate PDFs and screenshots from HTML without running Puppeteer. Managed Chromium, direct S3 upload, webhooks, templates, and EU-hosted infrastructure.
Canonical URLhttps://doppio.sh/
LanguageEnglish (default)
Twitter Cardsummary_large_image
All bots 1 allowed · 0 disallowed
  • Allow/

User reviews (0)

  • No reviews yet.