Batch Processing
Batch Processing
Generate multiple PDFs in a single API call with async processing and job status tracking. Ideal for bulk operations like invoice generation, report batches, or mail merges.
Endpoints
| Method | Endpoint | Description |
|---|---|---|
| POST | /v1/pdf/batch |
Create batch generation job |
| GET | /v1/pdf/jobs/:id |
Get job status and results |
| GET | /v1/pdf/jobs |
List all jobs |
| DELETE | /v1/pdf/jobs/:id |
Cancel or delete a job |
Create Batch Job
POST /v1/pdf/batch
Request Body
{
"items": [
{
"id": "invoice_001",
"html": "<h1>Invoice 001</h1><p>Customer: John Doe</p>"
},
{
"id": "invoice_002",
"template_id": "tpl_abc123",
"variables": {
"customer_name": "Jane Smith",
"total": 250.00
}
}
],
"options": {
"format": "A4",
"print_background": true
},
"callback_url": "https://your-app.com/webhooks/pdf-batch",
"merge_output": false
}
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
items |
array | Yes | Array of PDF generation requests (max 100) |
items[].id |
string | Yes | Unique identifier for this item |
items[].html |
string | Conditional* | Raw HTML content |
items[].template_id |
string | Conditional* | Template ID |
items[].variables |
object | No | Variables for template |
items[].options |
object | No | Override global options for this item |
options |
object | No | Default options for all items |
callback_url |
string | No | Webhook URL for completion notification |
merge_output |
boolean | No | Merge all PDFs into single file (default: false) |
* Each item requires either html or template_id
Response
{
"success": true,
"data": {
"job_id": "job_xyz789",
"status": "processing",
"total_items": 2,
"created_at": "2024-01-15T10:30:00Z",
"estimated_completion": "2024-01-15T10:31:00Z"
}
}
Get Job Status
GET /v1/pdf/jobs/:id
curl https://lightningpdf.dev/api/v1/pdf/jobs/job_xyz789 \
-H "Authorization: Bearer lpdf_your_api_key"
Response (Processing)
{
"success": true,
"data": {
"job_id": "job_xyz789",
"status": "processing",
"progress": {
"completed": 1,
"failed": 0,
"total": 2,
"percentage": 50
},
"created_at": "2024-01-15T10:30:00Z",
"started_at": "2024-01-15T10:30:05Z"
}
}
Response (Completed)
{
"success": true,
"data": {
"job_id": "job_xyz789",
"status": "completed",
"progress": {
"completed": 2,
"failed": 0,
"total": 2,
"percentage": 100
},
"results": [
{
"id": "invoice_001",
"status": "success",
"pdf": "JVBERi0xLjQKJeLjz9MK...",
"generation_time_ms": 234
},
{
"id": "invoice_002",
"status": "success",
"pdf": "JVBERi0xLjQKJeLjz9MK...",
"generation_time_ms": 187
}
],
"created_at": "2024-01-15T10:30:00Z",
"started_at": "2024-01-15T10:30:05Z",
"completed_at": "2024-01-15T10:30:45Z",
"total_time_ms": 40000
}
}
Response (Merged Output)
When merge_output: true, completed job returns single PDF:
{
"success": true,
"data": {
"job_id": "job_xyz789",
"status": "completed",
"merged_pdf": "JVBERi0xLjQKJeLjz9MK...",
"total_pages": 4,
"generation_time_ms": 450
}
}
Job Statuses
| Status | Description |
|---|---|
pending |
Job created, waiting to start |
processing |
PDFs are being generated |
completed |
All items processed successfully |
partial |
Some items failed, others succeeded |
failed |
All items failed |
cancelled |
Job was cancelled |
List Jobs
GET /v1/pdf/jobs
Query Parameters
| Parameter | Type | Description |
|---|---|---|
status |
string | Filter by status |
page |
integer | Page number (default: 1) |
limit |
integer | Results per page (default: 20, max: 100) |
curl "https://lightningpdf.dev/api/v1/pdf/jobs?status=completed&page=1&limit=10" \
-H "Authorization: Bearer lpdf_your_api_key"
Response
{
"success": true,
"data": {
"jobs": [
{
"job_id": "job_xyz789",
"status": "completed",
"total_items": 2,
"created_at": "2024-01-15T10:30:00Z",
"completed_at": "2024-01-15T10:30:45Z"
}
],
"pagination": {
"page": 1,
"limit": 10,
"total": 1,
"total_pages": 1
}
}
}
Cancel or Delete Job
DELETE /v1/pdf/jobs/:id
Cancels a processing job or deletes a completed job's results.
curl -X DELETE https://lightningpdf.dev/api/v1/pdf/jobs/job_xyz789 \
-H "Authorization: Bearer lpdf_your_api_key"
Response
{
"success": true,
"message": "Job cancelled successfully"
}
Webhooks
When you provide a callback_url, LightningPDF will POST to that URL when the job completes:
Webhook Payload
{
"event": "batch.completed",
"job_id": "job_xyz789",
"status": "completed",
"progress": {
"completed": 2,
"failed": 0,
"total": 2
},
"completed_at": "2024-01-15T10:30:45Z"
}
Webhook Signature
Every webhook includes an X-LightningPDF-Signature header for verification:
import hmac
import hashlib
def verify_webhook(payload, signature, secret):
expected = hmac.new(
secret.encode(),
payload.encode(),
hashlib.sha256
).hexdigest()
return hmac.compare_digest(signature, expected)
# Usage
if verify_webhook(request.body, request.headers['X-LightningPDF-Signature'], WEBHOOK_SECRET):
# Process webhook
pass
Complete Example: Bulk Invoice Generation
import requests
import base64
import time
API_KEY = "lpdf_your_api_key"
BASE_URL = "https://lightningpdf.dev/api/v1"
def generate_bulk_invoices(template_id, customers):
# Prepare batch items
items = []
for customer in customers:
items.append({
"id": f"invoice_{customer['id']}",
"template_id": template_id,
"variables": {
"invoice_number": customer['invoice_number'],
"customer_name": customer['name'],
"items": customer['items'],
"total": customer['total']
}
})
# Create batch job
response = requests.post(
f"{BASE_URL}/pdf/batch",
headers={
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
},
json={
"items": items,
"options": {
"format": "Letter",
"print_background": True
}
}
)
job_id = response.json()["data"]["job_id"]
print(f"Batch job created: {job_id}")
# Poll for completion
while True:
status_response = requests.get(
f"{BASE_URL}/pdf/jobs/{job_id}",
headers={"Authorization": f"Bearer {API_KEY}"}
)
job_data = status_response.json()["data"]
status = job_data["status"]
if status in ["completed", "partial", "failed"]:
break
progress = job_data["progress"]
print(f"Progress: {progress['completed']}/{progress['total']} ({progress['percentage']}%)")
time.sleep(2)
# Download results
if status == "completed":
results = job_data["results"]
for result in results:
pdf_bytes = base64.b64decode(result["pdf"])
filename = f"{result['id']}.pdf"
with open(filename, "wb") as f:
f.write(pdf_bytes)
print(f"Saved {filename}")
return job_data
# Usage
customers = [
{
"id": 1,
"invoice_number": "INV-001",
"name": "Acme Corp",
"items": [{"description": "Widget", "quantity": 10, "price": 25}],
"total": 250.00
},
{
"id": 2,
"invoice_number": "INV-002",
"name": "Tech Inc",
"items": [{"description": "Gadget", "quantity": 5, "price": 50}],
"total": 250.00
}
]
generate_bulk_invoices("tpl_abc123", customers)
Merged Output Example
Generate a single merged PDF from multiple pages:
curl -X POST https://lightningpdf.dev/api/v1/pdf/batch \
-H "Authorization: Bearer lpdf_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"items": [
{"id": "page1", "html": "<h1>Page 1</h1>"},
{"id": "page2", "html": "<h1>Page 2</h1>"},
{"id": "page3", "html": "<h1>Page 3</h1>"}
],
"merge_output": true
}'
Error Handling
Individual items can fail without failing the entire batch:
{
"success": true,
"data": {
"job_id": "job_xyz789",
"status": "partial",
"results": [
{
"id": "invoice_001",
"status": "success",
"pdf": "JVBERi0xLjQKJeLjz9MK..."
},
{
"id": "invoice_002",
"status": "failed",
"error": {
"code": "template_not_found",
"message": "Template tpl_invalid does not exist"
}
}
]
}
}
Credit Usage
Batch jobs consume credits per successful PDF:
- Each successful item = 1 credit
- Failed items = 0 credits
- Merged output = 1 credit per source PDF + 1 credit for merge
Best Practices
- Use unique IDs: Make item IDs meaningful (e.g.,
invoice_123,receipt_456) - Limit batch size: Keep batches under 100 items for optimal performance
- Implement webhooks: Don't poll excessively; use webhooks for production
- Handle partial failures: Check individual item statuses, not just overall job status
- Cache results: Job results are available for 24 hours