HTMLCSStoImage HTML-to-PDF Conversion: Setup and Page Size Options
Generate PDFs from HTML or a public webpage with HTMLCSStoImage. Configure Letter, A4, Legal, or custom page sizes, margins, scale, and print backgrounds.
Direct answer: send a POST request to https://hcti.io/v1/image with HTML or a public webpage URL and a pdf_options object. Set page_width and page_height with units, then configure margins, scale, and background printing as needed. Add "format": "pdf" to the request to receive a URL ending in .pdf. Request that URL to render and retrieve the PDF. The API uses HTTP Basic authentication: your API ID is the username and API key is the password. See the official PDF options documentation and API guide.
1. Choose a PDF page size
Use explicit width and height strings in the unit that matches the recipient’s paper standard. For portrait orientation, width is the shorter dimension; swap the values for landscape. The documented units are pixels (px), inches (in), centimeters (cm), millimeters (mm), and points (pt). For print documents, the docs recommend inches or millimeters.
| Size | Width × height | Common fit |
|---|---|---|
| Letter | 8.5 × 11 in | US standard documents |
| A4 | 210 × 297 mm | International standard documents |
| Legal | 8.5 × 14 in | Longer legal documents |
| A5 | 148 × 210 mm | Smaller documents |
These are dimensions, not automatic named presets: pass the width and height explicitly in pdf_options. For landscape Letter, for example, use 11in by 8.5in. The official examples use Letter and A4 dimensions and margin values.
2. Set up the request
- Get the API ID and API key from your HTML/CSS to Image dashboard.
- Keep both credentials on the server; the API key should be treated like a password.
- Send either
htmlorurl(not both), optionally withcss, and setformattopdf. - Use the returned URL to retrieve the PDF. The service renders and saves the PDF when that URL is requested.
HTML/CSS to Image documents JSON or form data for the creation request. The examples below use JSON and environment variables so credentials are not embedded in source code. The POST returns a JSON object containing a URL and ID. See the API request and authentication documentation.
cURL: create an A4 PDF and download it
export HCTI_API_ID='YOUR_API_ID'
export HCTI_API_KEY='YOUR_API_KEY'
response=$(curl --fail-with-body --silent --show-error \
-u "$HCTI_API_ID:$HCTI_API_KEY" \
-H 'Content-Type: application/json' \
-d '{
"html": "<!doctype html><html><head><meta charset=\"utf-8\"></head><body><h1>Monthly report</h1><p>PDF generated from HTML.</p></body></html>",
"css": "body { font-family: Arial, sans-serif; font-size: 12pt; } @media print { .no-print { display: none; } }",
"format": "pdf",
"pdf_options": {
"page_width": "210mm",
"page_height": "297mm",
"margins": ["20mm", "15mm", "20mm", "15mm"],
"print_background": true,
"scale": 1
}
}' \
https://hcti.io/v1/image)
printf '%s\n' "$response"
pdf_url=$(printf '%s' "$response" | python3 -c 'import json,sys; print(json.load(sys.stdin)["url"])')
curl --fail-with-body --silent --show-error "$pdf_url" -o report.pdf
Replace the sample HTML and CSS with the document you need. For a public page, replace the html property with "url": "https://example.com/report"; the API requires either html or url. Do not send both. A URL must be fully qualified and public for the service to fetch it, according to the API parameter documentation.
Python: create a PDF, then save its bytes
import os
import requests
api_id = os.environ["HCTI_API_ID"]
api_key = os.environ["HCTI_API_KEY"]
payload = {
"html": "<!doctype html><html><head><meta charset='utf-8'></head>"
"<body><h1>Monthly report</h1><p>PDF generated from HTML.</p></body></html>",
"css": "body { font-family: Arial, sans-serif; font-size: 12pt; }",
"format": "pdf",
"pdf_options": {
"page_width": "210mm",
"page_height": "297mm",
"margins": ["20mm", "15mm", "20mm", "15mm"],
"print_background": True,
"scale": 1,
},
}
created = requests.post(
"https://hcti.io/v1/image",
json=payload,
auth=(api_id, api_key),
timeout=60,
)
created.raise_for_status()
pdf_url = created.json()["url"]
pdf = requests.get(pdf_url, timeout=60)
pdf.raise_for_status()
with open("report.pdf", "wb") as output:
output.write(pdf.content)
Node.js: create a PDF, then save it
This example uses Node.js built-in fetch and Buffer (Node.js 18 or newer). Set HCTI_API_ID and HCTI_API_KEY in the server environment.
import { writeFile } from 'node:fs/promises';
const apiId = process.env.HCTI_API_ID;
const apiKey = process.env.HCTI_API_KEY;
if (!apiId || !apiKey) throw new Error('Set HCTI_API_ID and HCTI_API_KEY');
const auth = Buffer.from(`${apiId}:${apiKey}`).toString('base64');
const response = await fetch('https://hcti.io/v1/image', {
method: 'POST',
headers: {
Authorization: `Basic ${auth}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
html: `<!doctype html><html><head><meta charset="utf-8"></head><body><h1>Monthly report</h1><p>PDF generated from HTML.</p></body></html>`,
css: 'body { font-family: Arial, sans-serif; font-size: 12pt; }',
format: 'pdf',
pdf_options: {
page_width: '210mm',
page_height: '297mm',
margins: ['20mm', '15mm', '20mm', '15mm'],
print_background: true,
scale: 1,
},
}),
});
if (!response.ok) throw new Error(`Create request failed: ${response.status} ${await response.text()}`);
const { url } = await response.json();
const pdfResponse = await fetch(url);
if (!pdfResponse.ok) throw new Error(`PDF download failed: ${pdfResponse.status}`);
await writeFile('report.pdf', Buffer.from(await pdfResponse.arrayBuffer()));
3. Configure PDF options
| Option | Accepted value | How to use it |
|---|---|---|
page_width |
Dimension string with a unit | Set the paper width, for example "8.5in" or "210mm". |
page_height |
Dimension string with a unit | Set the paper height, for example "11in" or "297mm". |
margins |
Four dimension strings | Order is top, right, bottom, left. Example: ["0.5in", "0.5in", "0.5in", "0.5in"]. |
scale |
Number from 0.1 to 2; default 1 | Use a smaller value to shrink oversized content; check legibility and layout after changing it. |
print_background |
Boolean; default false | Set true if CSS backgrounds, gradients, or colors should appear in the PDF. |
These names, types, defaults, and supported units are documented in the official PDF options reference. Margins reduce the content area inside the selected page dimensions, so account for them when designing a fixed-width layout.
Letter, A4, and landscape examples
// Letter portrait
"pdf_options": {
"page_width": "8.5in",
"page_height": "11in",
"margins": ["0.5in", "0.5in", "0.5in", "0.5in"],
"print_background": true
}
// A4 portrait
"pdf_options": {
"page_width": "210mm",
"page_height": "297mm",
"margins": ["20mm", "15mm", "20mm", "15mm"],
"print_background": true
}
// Letter landscape
"pdf_options": {
"page_width": "11in",
"page_height": "8.5in",
"margins": ["0.5in", "0.5in", "0.5in", "0.5in"],
"print_background": true
}
4. Pick the PDF output flow
There are two documented flows, and both render the PDF when the resulting PDF URL is requested:
- Request a PDF URL directly: include
"format": "pdf"on creation. The returned URL already ends in.pdf. - Convert an existing image URL: create the image normally, then append
.pdfto its returned URL.
The format parameter selects the extension in the URL returned during creation; it does not change the stored image definition. For a new PDF workflow, setting format explicitly makes the intended output clear. See the format reference and PDF flow examples.
5. Make HTML and CSS print-ready
- Use print-specific CSS for content that should differ from a screen layout. The docs show
@media printrules and hiding elements such as.no-print. - Set
print_background: trueif the design depends on background fills, gradients, or colors; it defaults tofalse. - Give the content reasonable margins. The docs suggest 0.5–1 inch for printable documents, while their A4 example uses 20 mm top and bottom and 15 mm left and right.
- Check headings, tables, and wide elements against the printable area. If content is too large, adjust the CSS or page dimensions; scale is available from 0.1 through 2.
- Render a representative page before generating a large batch. The vendor documentation recommends checking page size before bulk generation.
For example, add @media print { .no-print { display: none; } body { font-size: 12pt; } } to the CSS. A lower scale can shrink a wide layout, but it also makes text smaller. The documentation provides scale as a fit control; inspect the resulting PDF for your content rather than assuming one value fits every page.
6. Troubleshoot common problems
| Symptom | Likely cause | What to check |
|---|---|---|
| Creation request returns 400 | The request is missing required HTML or URL, or the payload is malformed. | Send exactly one of html or url; check JSON syntax and content type. The API guide documents a 400 response when HTML is required. |
| 401 response | Credentials are absent or invalid. | Use the API ID as Basic-auth username and API key as password; confirm both environment variables are set. |
| 403 response | The credential lacks the required permission. | Check the API key’s permissions in the account configuration. |
| 429 response | The account’s image-credit limit has been exceeded. | Check account usage and plan limits before retrying; repeated identical calls will not fix a depleted quota. |
| Returned URL is not a PDF URL | The create request did not set format to pdf. |
Set "format": "pdf", or append .pdf to the created image URL as described by the docs. |
| PDF request fails after creation | The PDF is rendered when its URL is requested, or the returned URL was not retrieved correctly. | Check that the create call succeeded, parse the response’s url, and make a GET request to that URL. Check the download response status separately. |
| Background colors or gradients are absent | print_background defaults to false. |
Set "print_background": true. |
| Content is clipped or too small | Page dimensions, margins, layout width, or scale do not suit the document. | Confirm width and height units, check the top/right/bottom/left margin order, and adjust CSS or scale. Recheck text size if reducing scale. |
| Page looks different from the browser version | Screen styles may not be appropriate for print output. | Add print media rules and hide screen-only controls with a print rule such as .no-print { display: none; }. |
The API guide documents the authentication errors, permission errors, and image-credit-limit example; the PDF reference describes when rendering occurs and the relevant options. Consult the API guide and PDF options page for current details.
7. Performance, reliability, and cost considerations
- Rendering flow: PDF rendering and saving happen when the returned PDF URL is requested, so treat creation and file retrieval as separate HTTP steps. Check both responses.
- Retries: distinguish a transient network/download failure from an authentication, permission, malformed-request, or quota error. Fix the request or account condition before retrying those errors. Avoid unbounded retry loops.
- Batch generation: render a representative document and validate page size before scaling up, as the vendor recommends. Keep enough account credits for the intended workload.
- Cost: the reviewed PDF setup documentation does not specify per-PDF pricing. Check the current account plan and usage terms before estimating production cost; do not infer a price from the page-size settings.
- Output validation: check page dimensions, page breaks, fonts, image loading, and background printing on representative documents. The documentation gives configuration guidance, not independent benchmark or compatibility results.
Or skip the browser setup
If your job is to capture a webpage as an image or PDF rather than build a custom HTML document, ScreenshotNeo is a website screenshot API and MCP server for developers. Its API accepts a URL in one GET request and can return a PDF. For a PDF response, use the documented API configuration in the ScreenshotNeo docs; this minimal request shows the one-call pattern with the PDF output format:
curl -G "https://api.screenshotneo.com/v1/shot" \
-d access_key=YOUR_API_KEY \
--data-urlencode url=https://stripe.com \
-d format=pdf \
-o page.pdf
ScreenshotNeo removes cookie banners, newsletter popups, and chat widgets before capture. Bot checks, blank pages, and failed loads are never billed, and response headers report the page verdict and billing status. Its MCP server lets AI agents take screenshots. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots.
Sign up free for 1,000 screenshots a month, with no card required.
FAQ
Can I generate a PDF from a public webpage?
Yes. Send the fully qualified public page as url instead of html, and include PDF options. The API guide says to use either url or html, not both.
Does setting PDF dimensions control every page break?
The options set page dimensions, margins, scale, and background printing. The reviewed reference does not describe a separate page-break parameter, so use print CSS and inspect the output for the content you generate.
Can I use a custom paper size?
Yes. Provide width and height strings using a supported unit such as millimeters, inches, centimeters, pixels, or points.
Do I need to create an image first and then convert it?
No. Set format to pdf during creation to receive a PDF URL directly. The alternate documented flow appends .pdf to an image URL.
Why is the returned URL not itself the PDF file?
The creation response supplies a URL. According to the PDF reference, the PDF is rendered and saved separately when that URL is requested, so make a second request to download it.


