HTML to PDF API
One endpoint — POST /api/v1/convert — converts documents to and from PDF.
Provide the source three ways, and choose how the result comes back.
Authenticate with your API key: Authorization: Bearer YOUR_API_KEY.
Input — pick one
1. Raw HTML string (recommended for html_to_pdf)
curl -X POST "https://api.saypdf.com/api/v1/convert?output=inline" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-o out.pdf \
-d '{
"typeConvert": "html_to_pdf",
"source": { "html": "<h1>Invoice #123</h1><p>Total: $42.00</p>" },
"output": "inline"
}'
2. A URL (fetched server-side)
curl -X POST "https://api.saypdf.com/api/v1/convert" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{ "typeConvert": "html_to_pdf", "source": { "url": "https://example.com/invoice/123" } }'
Relative assets (CSS/images/fonts) resolve against the page URL automatically.
For raw HTML with relative assets, pass
source.baseUrl.3. A file upload (binary documents) or base64
# multipart upload
curl -X POST "https://api.saypdf.com/api/v1/convert" \
-H "Authorization: Bearer $API_KEY" \
-F "file=@report.docx" -F "typeConvert=word_to_pdf"
# base64 (include a filename so the format is known)
-d '{ "typeConvert": "excel_to_pdf", "source": { "base64": "<...>", "filename": "data.xlsx" } }'
Raw-string inputs apply to text conversions:
html → html_to_pdf,
text → txt_to_pdf,
svg → svg_to_pdf. All other conversions accept file, url, or base64.
Output — output = url · inline · json
| Mode | Returns |
|---|---|
url (default) | { fileId, url, pages } — a link to download the result. |
inline | The result bytes, streamed back (no polling). Runs synchronously. |
json | Structured data for spreadsheet/csv/text results, e.g. { data: { rows: [...] } }. |
# Extract an invoice straight to JSON
curl -X POST "https://api.saypdf.com/api/v1/convert" \
-H "Authorization: Bearer $API_KEY" \
-F "file=@invoice.pdf" -F "typeConvert=invoice_to_excel" -F "output=json"
# → { "success": true, "data": { "format": "spreadsheet", "rows": [ { ... } ] } }
Render options (html_to_pdf)
All optional; defaults give clean A4 output.
| Field | Default | Example |
|---|---|---|
format | A4 | Letter, Legal, A3 |
landscape | false | true |
margin | 15mm | "20mm" or { top, right, bottom, left } |
printBackground | true | false |
displayHeaderFooter | true | false |
scale | 1 | 0.8 |
{
"typeConvert": "html_to_pdf",
"source": { "html": "<h1>Report</h1>" },
"options": { "format": "Letter", "landscape": true, "margin": "20mm" },
"output": "inline"
}
JavaScript
const res = await fetch("https://api.saypdf.com/api/v1/convert?output=inline", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.SAYPDF_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
typeConvert: "html_to_pdf",
source: { html: renderInvoiceHtml(order) },
output: "inline",
}),
});
const pdf = Buffer.from(await res.arrayBuffer()); // store / email
Python
import requests
r = requests.post(
"https://api.saypdf.com/api/v1/convert",
headers={"Authorization": f"Bearer {API_KEY}"},
json={"typeConvert": "html_to_pdf",
"source": {"html": html_string},
"output": "inline"},
)
open("out.pdf", "wb").write(r.content)
Notes
- Max input size: 60 MB.
inlineandjsonalways run synchronously.urlmode supports"async": trueto return afileIdimmediately; pollGET /api/v1/convert/{id}/status.- Multipart uploads work exactly as before — this is purely additive.