Your First PDF
Step-by-step guide to generating your first PDF
This guide walks you through the full structure of a PDF generation request, explaining every parameter and showing you how to handle the response.
The API Endpoint
All PDF generation requests are sent as POST requests to:
POST https://api.docreate.io/api/pdf/external
A Complete Example
Here is a full cURL example that uses all available parameters:
curl -X POST https://api.docreate.io/api/pdf/external \
-H "Authorization: Bearer $DOCREATE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"html": "<div class=\"invoice\"><h1>Invoice #{{invoiceNumber}}</h1><p>Billed to: {{customerName}}</p><table><tr><th>Item</th><th>Amount</th></tr><tr><td>{{itemName}}</td><td>{{itemPrice}}</td></tr></table><p class=\"total\">Total: {{total}}</p></div>",
"css": ".invoice { font-family: Arial, sans-serif; padding: 40px; } h1 { color: #1a1a2e; border-bottom: 2px solid #e0e0e0; padding-bottom: 10px; } table { width: 100%; border-collapse: collapse; margin: 20px 0; } th, td { border: 1px solid #ddd; padding: 8px 12px; text-align: left; } th { background-color: #f5f5f5; } .total { font-size: 18px; font-weight: bold; text-align: right; }",
"data": {
"invoiceNumber": "2026-0042",
"customerName": "Acme Corp",
"itemName": "PDF Generation API - Pro Plan",
"itemPrice": "49.00 EUR",
"total": "49.00 EUR"
},
"headerHtml": "<div style=\"font-size: 10px; color: #999; text-align: center; width: 100%;\">DoCreate Invoice</div>",
"footerHtml": "<div style=\"font-size: 10px; color: #999; text-align: center; width: 100%;\">Page <span class=\"pageNumber\"></span> of <span class=\"totalPages\"></span></div>"
}' \
--output invoice.pdf
Request Body Parameters
The request body is a JSON object with the following fields:
html (required)
The HTML content of your document. This is the main body of the PDF. You can use any valid HTML, including tables, images (via URLs or base64), and complex layouts.
{
"html": "<h1>My Document</h1><p>Content goes here.</p>"
}
You can include template placeholders using double curly braces ({{variableName}}), which will be replaced with values from the data parameter.
css (optional)
CSS styles applied to the HTML content. Use this to control typography, colors, spacing, layout, and all other visual aspects of the document.
{
"css": "h1 { color: #333; font-size: 24px; } p { line-height: 1.6; }"
}
data (optional)
A JSON object containing key-value pairs used to replace template placeholders in your HTML. Every occurrence of {{key}} in your html, headerHtml, and footerHtml will be replaced with the corresponding value.
{
"data": {
"customerName": "Jane Doe",
"invoiceDate": "2026-02-17"
}
}
headerHtml (optional)
HTML content rendered at the top of every page. This is useful for company logos, document titles, or reference numbers. The header is rendered outside the main content area.
{
"headerHtml": "<div style=\"font-size: 10px; text-align: right; width: 100%; padding: 0 20px;\">Confidential</div>"
}
footerHtml (optional)
HTML content rendered at the bottom of every page. Commonly used for page numbers, dates, or legal disclaimers. You can use the special CSS classes pageNumber and totalPages to insert automatic page numbering.
{
"footerHtml": "<div style=\"font-size: 10px; text-align: center; width: 100%;\">Page <span class=\"pageNumber\"></span> of <span class=\"totalPages\"></span></div>"
}
Handling the Response
The API returns the generated PDF as a binary response with the content type application/pdf.
cURL
Use the --output flag to save the response to a file:
curl -X POST https://api.docreate.io/api/pdf/external \
-H "Authorization: Bearer $DOCREATE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"html": "<h1>Hello</h1>"}' \
--output document.pdf
JavaScript / Node.js
const response = await fetch("https://api.docreate.io/api/pdf/external", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.DOCREATE_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
html: "<h1>Hello</h1>",
css: "h1 { color: #333; }",
}),
});
if (!response.ok) {
throw new Error(`PDF generation failed: ${response.status}`);
}
// Save to file (Node.js)
const buffer = Buffer.from(await response.arrayBuffer());
fs.writeFileSync("document.pdf", buffer);
Python
import requests
response = requests.post(
"https://api.docreate.io/api/pdf/external",
headers={
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json",
},
json={
"html": "<h1>Hello</h1>",
"css": "h1 { color: #333; }",
},
)
response.raise_for_status()
with open("document.pdf", "wb") as f:
f.write(response.content)
Error Handling
If the request fails, the API returns a JSON error response instead of a PDF:
| Status Code | Meaning |
|---|---|
400 Bad Request | The request body is malformed or missing the required html field. |
401 Unauthorized | The API key is missing or invalid. |
429 Too Many Requests | You have exceeded your rate limit. Wait and retry. |
500 Internal Server Error | An unexpected error occurred during PDF rendering. |
Always check the response status code before processing the body:
if (!response.ok) {
const error = await response.json();
console.error("PDF generation error:", error);
}
Next Steps
- Explore the API Reference for the full specification.
- Learn how to create and manage Templates in the dashboard.