Create PDF — Synchronous PDF Generation API
Generate a PDF from a template with a single synchronous call. The request blocks until the PDF is rendered and returns either a signed URL or the raw PDF bytes.
POST https://api.templatefox.com/v1/pdf/createAuthentication: API key in x-api-key header.
Credits: 1 credit per successful generation (refunded automatically if rendering fails).
For large documents, batch jobs, or webhook-driven flows, use create-pdf-async instead.
Request
Section titled “Request”Minimum required
Section titled “Minimum required”Only two body fields are strictly required:
| Field | Type | Description |
|---|---|---|
template_id | string | The 12-character ID of your template (copy from the templates dashboard). |
data | object | Key-value pairs to inject into the template. Keys must match {{variable}} placeholders in your design. |
curl -X POST https://api.templatefox.com/v1/pdf/create \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"template_id": "HMQywVpZxqAM",
"data": {
"customer_name": "John Doe",
"invoice_number": "INV-001",
"amount": "$1,234.56"
}
}' Or use one of our official SDKs — TypeScript, Python, Go, PHP, Ruby, Java, C#.
All parameters
Section titled “All parameters”| Field | Type | Required | Default | Description |
|---|---|---|---|---|
template_id | string | ✅ | — | 12-character template short ID. |
data | object | ✅ | — | Key-value data merged into the template. See Data Binding. |
export_type | string | — | "url" | "url" uploads the PDF to our CDN and returns a signed URL. "binary" returns the raw PDF bytes as application/pdf. |
expiration | integer | — | 86400 | URL expiration in seconds. Min: 60, max: 604800 (7 days). Only applies when export_type="url". |
filename | string | — | "document" | Custom filename (without .pdf extension). Alphanumeric, _, -, . only. Max 100 chars. |
store_s3 | boolean | — | false | Upload to your configured S3 bucket instead of our CDN. Requires an S3 integration. |
s3_filepath | string | — | — | Path prefix inside your S3 bucket. Overrides default_prefix. Max 500 chars. |
s3_bucket | string | — | — | Override the bucket name from your S3 integration (3–63 chars, lowercase). |
pdf_variant | string | — | — | Generate a standards-compliant PDF. Values: "pdf/a-1b", "pdf/a-2b", "pdf/a-3b". See PDF Standards. |
version | string | — | — | Template version tag (e.g. "prod") or numeric version (e.g. "3"). Omit to use the current draft. Max 50 chars. |
Response
Section titled “Response”export_type = "url" (default)
Section titled “export_type = "url" (default)”Returns JSON with a signed URL to the generated PDF.
{ "url": "https://cdn.templatefox.com/generated/abc123/invoice.pdf", "filename": "invoice-001.pdf", "credits_remaining": 99, "expires_in": 86400}| Field | Type | Description |
|---|---|---|
url | string | Signed URL to download the PDF (expires after expires_in seconds). |
filename | string | Final filename of the generated PDF. |
credits_remaining | number | Credits left in your team’s balance after this call. |
expires_in | number | Seconds until the signed URL expires. |
export_type = "binary"
Section titled “export_type = "binary"”Returns the raw PDF file with content type application/pdf. Useful when you want to stream the file directly to a user or store it yourself. expiration, filename, and S3 options are ignored.
Response headers:
Content-Type: application/pdfContent-Disposition: attachment; filename="HMQywVpZxqAM.pdf"X-Credits-Remaining: 99store_s3 = true
Section titled “store_s3 = true”When S3 upload is requested, the response describes where the file landed in your bucket instead of returning a URL:
{ "s3_bucket": "my-pdf-bucket", "s3_key": "invoices/2026/01/invoice-001.pdf", "filename": "invoice-001.pdf", "credits_remaining": 99}Example:
curl -X POST https://api.templatefox.com/v1/pdf/create \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"template_id": "HMQywVpZxqAM",
"data": { "customer_name": "John Doe" },
"store_s3": true,
"filename": "invoice-001",
"s3_filepath": "2026/01/"
}' PDF/A (archival)
Section titled “PDF/A (archival)”Set pdf_variant to produce a PDF that passes PDF/A compliance checks — useful for e-invoicing (Factur-X, ZUGFeRD), archival, or regulated industries.
curl -X POST https://api.templatefox.com/v1/pdf/create \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"template_id": "HMQywVpZxqAM",
"data": { "customer_name": "John Doe" },
"pdf_variant": "pdf/a-3b"
}' Binary response
Section titled “Binary response”Set export_type to "binary" to receive the raw PDF bytes directly — useful for streaming to the user or saving to disk without a CDN round-trip.
curl -X POST https://api.templatefox.com/v1/pdf/create \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
--output invoice.pdf \
-d '{
"template_id": "HMQywVpZxqAM",
"data": { "customer_name": "John Doe" },
"export_type": "binary"
}' Errors
Section titled “Errors”| Status | Error | When |
|---|---|---|
| 400 | BAD_REQUEST | The template is an image template — use create-image instead. |
| 401 | UNAUTHORIZED | Missing or invalid API key. |
| 402 | INSUFFICIENT_CREDITS | Your team’s credit balance is 0. |
| 403 | FORBIDDEN | The template does not belong to your team. |
| 404 | TEMPLATE_NOT_FOUND | template_id does not exist. |
| 429 | RATE_LIMIT_EXCEEDED | Rate limit hit (see response headers). |
| 500 | INTERNAL_ERROR | Rendering failed. Credit is automatically refunded. |
See the full list in the API Reference overview.