Generate a PDF
Send your data to the API and get a PDF back in the format you need.
Overview
To generate a PDF, send a POST request to the generate endpoint with the ID of the template you want to use and a JSON body containing the data to inject into the template.
POST /api/v1/templates/{template_id}/generateRequest parameters
All parameters are optional. If you send an empty body, the PDF will be generated with the template's default values.
| Parameter | Type | Default | Description |
|---|---|---|---|
data | object | {} | Key-value pairs to inject into the template variables. |
output | string | "base64" | Output format: base64, url, or binary. |
filename | string | "document.pdf" | Filename for the generated PDF. Alphanumeric, dashes, underscores, and dots only. |
url_expiry | integer | 60 | Expiry time in minutes for the temporary URL (1–1440). Only used when output is "url". |
sign | boolean | false | Reserved for an upcoming release. Currently ignored on every plan. |
Output formats
Base64 (default)
Returns the PDF content as a base64-encoded string in a JSON response. Suitable for most integrations.
curl -X POST https://pdfstork.com/api/v1/templates/1/generate \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"data": { "name": "Jane Doe" },
"output": "base64"
}'{
"success": true,
"pdf": "JVBERi0xLjQKJeLj...",
"filename": "document.pdf",
"size": 12345,
"usage": {
"current": 42,
"limit": 5000,
"percentage": 0.84
}
}Temporary URL
Returns a signed URL that allows downloading the PDF without authentication. The URL expires after the specified url_expiry (default: 60 minutes, max: 24 hours).
curl -X POST https://pdfstork.com/api/v1/templates/1/generate \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"data": { "name": "Jane Doe" },
"output": "url",
"url_expiry": 120
}'{
"success": true,
"url": "https://de-s3.storage.bunnycdn.com/pdfapi-pdfs/pdfs/abc123.pdf?X-Amz-Signature=...",
"filename": "document.pdf",
"expires_at": "2026-03-30T12:00:00Z",
"size": 12345,
"usage": {
"current": 42,
"limit": 5000,
"percentage": 0.84
}
}Binary
Returns the raw PDF bytes directly. Use this if you want to pipe the response to a file or stream it to the user.
curl -X POST https://pdfstork.com/api/v1/templates/1/generate \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-o invoice.pdf \
-d '{
"data": { "name": "Jane Doe" },
"output": "binary"
}'The response includes these headers:
Content-Type: application/pdfContent-Disposition: attachment; filename="document.pdf"Content-Length: 12345
Code examples
JavaScript (fetch)
const response = await fetch(
'https://pdfstork.com/api/v1/templates/1/generate',
{
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_TOKEN',
'Content-Type': 'application/json',
'Accept': 'application/json',
},
body: JSON.stringify({
data: { name: 'Jane Doe', amount: '€1,200.00' },
output: 'url',
}),
}
);
const { url } = await response.json();
console.log('Download your PDF:', url);PHP (cURL)
$ch = curl_init('https://pdfstork.com/api/v1/templates/1/generate');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_TOKEN',
'Content-Type: application/json',
'Accept: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'data' => ['name' => 'Jane Doe', 'amount' => '€1,200.00'],
'output' => 'base64',
]),
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
file_put_contents('invoice.pdf', base64_decode($response['pdf']));Usage tracking
Every successful response includes a usage object showing your current monthly consumption. You can also check your usage at any time via the dedicated endpoint:
curl https://pdfstork.com/api/v1/usage \
-H "Authorization: Bearer YOUR_TOKEN"See Rate Limits & Quotas for details on quotas per plan.
Error handling
Common error responses:
- 401 — Missing or invalid API token
- 403 — You don't have access to this template
- 404 — Template not found
- 422 — Validation error (check the
errorsobject in the response) - 429 — Rate limit exceeded (60 requests/minute)
{
"message": "The output field is invalid.",
"errors": {
"output": [
"The output must be one of: base64, url, binary."
]
}
}