HTML to PDF API
Post an HTML string, get back a PDF and a signed link to download it.
The ASHDOCS HTML to PDF API takes the HTML you already have, renders it on our servers and returns a PDF. Send the markup in one POST request; the response carries a signed download URL that stays valid for an hour. There is nothing to install, no browser to keep patched and no print server to babysit.
It is the same endpoint the dashboard's HTML to PDF tool uses, so a template you test in the browser behaves the same way when you call it from curl, Node, Python or an HTTP step in an automation tool.
curl -X POST https://www.ashdocs.com/api/v1/tools/html-to-pdf \
-H "X-API-Key: ash_test_..." \
-F 'options={"html":"<h1>Invoice 42</h1><p>Total due: 120.00 USD</p>"}'const form = new FormData();
form.append("options", JSON.stringify({
html: "<h1>Invoice 42</h1><p>Total due: 120.00 USD</p>",
}));
const res = await fetch("https://www.ashdocs.com/api/v1/tools/html-to-pdf", {
method: "POST",
headers: { "X-API-Key": "ash_test_..." },
body: form,
});
const job = await res.json();
console.log(job.output_files[0].url);import json
import requests
r = requests.post(
"https://www.ashdocs.com/api/v1/tools/html-to-pdf",
headers={"X-API-Key": "ash_test_..."},
data={"options": json.dumps({"html": "<h1>Invoice 42</h1><p>Total due: 120.00 USD</p>"})},
)
print(r.json()["output_files"][0]["url"]){
"job_id": "job_8c1f2e7a9b3d",
"request_id": "req_5d0a4c9e1f27",
"tool_key": "html-to-pdf",
"status": "completed",
"output_files": [
{
"filename": "output.pdf",
"size": 8214,
"url": "<signed URL, valid for 1 hour>",
"expires_at": "2026-10-09T13:00:00+00:00"
}
],
"credits_consumed": 0,
"is_test": true
}Response trimmed; values illustrative. Test keys report 0 credits; a live key reports 1.
Templates with data
Put {{ variables }} and {% for %} loops in your HTML and send a data object. Values are HTML-escaped, and a missing variable fails the request before any credit is used.
Print CSS that works
@page rules, @font-face, flexbox and page breaks are honored. The page size comes from your CSS; URL→PDF supports A4 and Letter.
Large documents queue
HTML of 2 MB or more is accepted as a background job: you get a 202 with a job ID to poll, and webhooks report completion on paid plans.
How the HTML to PDF API renders your page
Most documents are rendered with WeasyPrint, a CSS layout engine built for paged media. Documents of 512 KB of HTML or more switch to headless Chromium, which is faster on very long files. In both cases JavaScript does not run: WeasyPrint has no script engine, and the Chromium context is created with JavaScript turned off. Build the final markup before you send it.
Because the HTML arrives as a string, there is no page address for relative links to resolve against. Reference images and fonts by absolute https URL or embed them as data URIs. Your CSS controls the paper: set @page { size: A4; margin: 18mm } or size: Letter, and the default is A4 when you set nothing.
Every PDF is checked before the request succeeds: it must be non-empty and structurally valid, and in template mode any leftover {{ }} placeholder fails the job instead of shipping a document with a hole in it.
- Request fields:
html(required),data(template values),strict(default true) andliteral_mode(print braces as-is). - Response: the job record with
output_files[].url, a signed link that expires after one hour. - Cost: 1 credit per PDF on a live key; test keys never use credits.
Convert a URL instead of HTML
When the page already lives on the web, call POST /api/v1/tools/url-to-pdf with a url. That route always uses headless Chromium, waits for the network to go quiet and for web fonts to load, and scrolls the page so lazy-loaded images appear before printing.
URL→PDF accepts format (A4, Letter, Legal, A3 or A5), landscape, margin_mm (0 to 50), scale (0.1 to 2), media (screen or print), viewport, wait_until and wait_extra_ms. Private and cloud-metadata addresses are refused, including when a public URL redirects to one.
From code or from an automation tool
Any HTTP client works: the endpoint takes a multipart or form field named options holding JSON, and the X-API-Key header. From Zapier, Make or n8n, an HTTP step calls the endpoint today; the packaged ASHDOCS apps for those platforms are available on request while their public listings are finished.
Add "output": "url" to the options to get a flat body with file_url, expires_at and credits_charged, which is easier to map in a no-code step than the full job record.
Frequently asked questions
How do I convert HTML to PDF with an API?
Send a POST request to https://www.ashdocs.com/api/v1/tools/html-to-pdf with your API key in the X-API-Key header and a form field named options containing JSON such as {"html": "<h1>Hello</h1>"}. The response includes output_files[0].url, a signed link to the PDF that is valid for one hour. To fill a template, add a data object and use {{ variable }} placeholders in the HTML.
Does it support CSS and web fonts?
Yes. The renderer supports CSS paged media, including @page size and margins, page breaks and @font-face web fonts, along with flexbox and simple grid layouts. Load fonts and images from absolute URLs or data URIs, because HTML sent as a string has no base address for relative paths, and note that JavaScript does not run.
Can I convert a URL instead of HTML?
Yes. POST /api/v1/tools/url-to-pdf takes a url and renders the live page in headless Chromium, with format set to A4, Letter, Legal, A3 or A5. It waits for fonts and lazy-loaded images, and refuses private network addresses.
Is there a free tier?
Yes. The Free plan includes 100 credits per month, and each HTML to PDF conversion uses 1 credit. Conversions made with a test key use none, so you can tune your templates for free.
Plans
- 100 credits per month
- 1 seat
- No webhooks
- 1,500 credits per month
- 1 seat
- Webhooks
- 10,000 credits per month
- 3 seats
- Webhooks
- 30,000 credits per month
- 5 seats
- Webhooks
- 100,000 credits per month
- 10 seats
- Webhooks
Test keys are free, never expire and never use credits; plan rate limits apply. Webhooks are on paid plans. Issuing an invoice uses 1 credit. No per-seat fees. See full pricing.