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. The API renders the published version of the template. Each PDF costs one credit.
POST /api/v1/templates/{template_id}/generateRequest parameters
The body must be a JSON object with a data object holding your values; the other parameters are optional. An empty body is refused with a 422 (The request body is empty. Send a JSON object with a data field, for example {"data": {}}.), and so is a data that is not an object (The data field must be an object.).
| 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. Letters, numbers, dashes, underscores and dots only. |
url_expiry | integer | 60 | Expiry time in minutes for the temporary URL, from 1 to 1440. Only used when output is "url". A value outside this range is refused with a 422. |
metadata | object | None | Document properties to write into the PDF: title, author, subject, keywords, creator. Each overrides the template's own value and may use {{ variables }}. Basic plan and above |
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. The usage object counts the PDF you just generated.
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.8,
"pack_credits": 0
}
}Temporary URL
Returns a signed URL that allows downloading the PDF without authentication. The URL expires after the specified url_expiry (default: 60 minutes, maximum: 1440 minutes, that is 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.8,
"pack_credits": 0
}
}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. Set "output": "binary" in the body: sending Accept: application/pdf alone does not change the output, you would still get base64 JSON.
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
- 402: Monthly quota and prepaid credits both used up
- 403: The template belongs to another account, your email address is not verified, or the template uses a feature your plan does not include (the body gives
required_plan) - 404: Template not found (
{"message": "Template 999 not found."}) - 422: Validation error (check the
errorsobject in the response), or a Twig error in an HTML template. No credit is consumed - 429: Rate limit exceeded (60 requests per minute per team)
{
"message": "The output must be one of: base64, url, binary.",
"errors": {
"output": [
"The output must be one of: base64, url, binary."
]
}
}{
"message": "Twig error in the template, line 2: missing endif (the if opened here is never closed)",
"part": "template",
"line": 2,
"errors": {
"template": [
"Twig error in the template, line 2: missing endif (the if opened here is never closed)"
]
}
}