An API that turns HTML or a URL into a PDF
Send HTML (or a public URL), get a PDF. Page size, margins, headers, footers and page ranges are options, not extra products.
Get a free key Full referenceRequest and response
Send JSON with your key in the Authorization header. A good request returns the file itself with a Content-Type, an
X-Render-Usage header such as 12/1000, and X-Render-Cache: hit or miss. A bad one returns
JSON with a code, a plain sentence and a link to the docs.
curl
curl -X POST https://render.starhold.app/v1/pdf \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"html":"<h1>Invoice 42</h1><p>Thank you.</p>","page_size":"A4"}' \
-o out.pdf
JavaScript (fetch)
import { writeFile } from "node:fs/promises";
const res = await fetch("https://render.starhold.app/v1/pdf", {
method: "POST",
headers: { Authorization: "Bearer YOUR_API_KEY", "Content-Type": "application/json" },
body: '{"html":"<h1>Invoice 42</h1><p>Thank you.</p>","page_size":"A4"}',
});
if (!res.ok) throw new Error((await res.json()).error.message);
await writeFile("out.pdf", Buffer.from(await res.arrayBuffer()));
Python (requests)
import requests
body = '{"html":"<h1>Invoice 42</h1><p>Thank you.</p>","page_size":"A4"}'
res = requests.post("https://render.starhold.app/v1/pdf",
headers={"Authorization": "Bearer YOUR_API_KEY", "Content-Type": "application/json"},
data=body.encode(), timeout=35)
res.raise_for_status()
open("out.pdf", "wb").write(res.content)
PHP (curl ext)
<?php
$body = '{"html":"<h1>Invoice 42</h1><p>Thank you.</p>","page_size":"A4"}';
$ch = curl_init("https://render.starhold.app/v1/pdf");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $body,
CURLOPT_HTTPHEADER => ["Authorization: Bearer YOUR_API_KEY", "Content-Type: application/json"],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 35,
]);
$out = curl_exec($ch);
if (curl_getinfo($ch, CURLINFO_HTTP_CODE) !== 200) { die($out); }
file_put_contents("out.pdf", $out);
Go (net/http)
package main
import (
"io"
"net/http"
"os"
"strings"
"time"
)
func main() {
body := `{"html":"<h1>Invoice 42</h1><p>Thank you.</p>","page_size":"A4"}`
req, _ := http.NewRequest("POST", "https://render.starhold.app/v1/pdf", strings.NewReader(body))
req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
req.Header.Set("Content-Type", "application/json")
res, err := (&http.Client{Timeout: 35 * time.Second}).Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
if res.StatusCode != 200 {
io.Copy(os.Stderr, res.Body)
os.Exit(1)
}
out, _ := os.Create("out.pdf")
io.Copy(out, res.Body)
}
Main options
| Field | What it does |
|---|---|
url or html | exactly one; html up to 512 KB, with optional css |
page_size | A4, Letter, Legal, A3, A5 or Tabloid; or width and height as CSS lengths |
margin, landscape, scale | margins up to 100mm each; scale 0.1 to 2.0 |
header_html, footer_html | up to 16 KB each; Chromium classes pageNumber, totalPages, date, title, url |
page_ranges, media | for example 1-3,5; print or screen |
Pricing in short
Free is 50 renders a month. Hobby is $5 for 1,000, Pro is $19 for 10,000 and Scale is $49 for 50,000. Cache hits and failed renders do not count. Full pricing
Questions
How big can a PDF be?
Up to 20 MB and 200 pages. Beyond that you get an output_too_large error, never a cut-off file.
Can it render pages behind a login?
No. It renders public pages and HTML you send. See acceptable use.
What does the Free plan add?
A small watermark stamped on every page. Paid plans never have one.