Quick Start
Generate your first PDF in under 5 minutes. All you need is an API key.
Make your first API call
Send a POST request with your template choice and data.
curl -X POST https://api.docujson.com/v1/generate \
-H "Content-Type: application/json" \
-H "X-API-Key: dj_your_api_key" \
-d '{
"templateId": "invoice-basic",
"data": {
"invoiceNumber": "INV-001",
"client": { "name": "Meridian Technologies" },
"items": [
{ "description": "Consulting", "quantity": 1, "unitPrice": 5000, "amount": 5000 }
],
"total": 5000
}
}'Get your PDF
The API returns a hosted URL to your generated PDF. The URL never expires.
{
"success": true,
"pdfUrl": "https://storage.docujson.com/invoice-1234567890.pdf",
"templateId": "invoice-basic",
"generatedAt": "2026-02-10T12:00:00.000Z"
}Authentication
All API requests require authentication via an API key. Keys use the format dj_<uuid> and are created from your dashboard.
You can pass the key using either header:
# Recommended: X-API-Key header
curl -H "X-API-Key: dj_your_api_key" https://api.docujson.com/v1/generate
# Alternative: Authorization Bearer header
curl -H "Authorization: Bearer dj_your_api_key" https://api.docujson.com/v1/generateKeep your API key secure
Never expose your API key in client-side code. Only use it from server-side scripts, automation platforms, or scripting extensions like Airtable.
Generate PDF
/api/v1/generateGenerate a PDF document from a template and data. Returns a hosted PDF URL by default.
Request Body
| Parameter | Type | Required | Description |
|---|---|---|---|
| templateId | string | Required | Template to use: invoice-basic, weekly-report, calendar-schedule, or kpi-dashboard |
| data | object | Required | Data to populate the template. See Template Payloads section for schemas. |
| options | object | Optional | PDF output options (format, orientation, margins). See PDF Options section. |
| outputFormat | string | Optional | "url" (default), "base64", or "buffer". See Output Formats section. |
| webhook | object | Optional | Async delivery. Object with url (string) and optional headers (object). See Webhooks section. |
Response
| Parameter | Type | Required | Description |
|---|---|---|---|
| success | boolean | Required | Whether the request succeeded |
| pdfUrl | string | Optional | Hosted PDF URL (when outputFormat is "url") |
| base64 | string | Optional | Base64-encoded PDF (when outputFormat is "base64") |
| templateId | string | Required | The template that was used |
| generatedAt | string | Required | ISO 8601 timestamp |
Response Headers
| Parameter | Type | Required | Description |
|---|---|---|---|
| X-Generation-Time-Ms | number | Required | Time taken to generate the PDF in milliseconds |
| X-PDF-Size-Bytes | number | Required | Size of the generated PDF in bytes |
| X-Usage-Remaining | number | Required | Remaining PDF generations for the current billing period |
Example
const response = await fetch('https://api.docujson.com/v1/generate', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': 'dj_your_api_key',
},
body: JSON.stringify({
templateId: 'weekly-report',
data: {
reportTitle: 'Engineering Weekly Status',
versionAsOf: '02/10/2026',
projects: [
{
title: 'Platform Migration',
status: 'In Progress',
progress: 68,
releaseDate: '03/15/2026',
},
],
},
options: {
format: 'Letter',
orientation: 'portrait',
},
}),
});
const { success, pdfUrl } = await response.json();
console.log(pdfUrl); // https://storage.docujson.com/...List Templates
/api/v1/templatesReturns all available templates. No authentication required.
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| category | string | Optional | Filter by category: calendar, report, dashboard, invoice |
| id | string | Optional | Get a specific template by ID |
Example Response
{
"templates": [
{
"id": "invoice-basic",
"name": "Basic Invoice",
"description": "Clean, professional invoice template...",
"category": "invoice",
"version": "1.0.0"
},
{
"id": "weekly-report",
"name": "Weekly Project Report",
"description": "Professional weekly status report...",
"category": "report",
"version": "1.0.0"
},
{
"id": "calendar-schedule",
"name": "Project Calendar",
"description": "Multi-month calendar view...",
"category": "calendar",
"version": "1.0.0"
},
{
"id": "kpi-dashboard",
"name": "KPI Dashboard",
"description": "One-page metrics dashboard...",
"category": "dashboard",
"version": "1.0.0"
}
],
"total": 4,
"categories": ["calendar", "report", "dashboard", "invoice", "certificate", "custom"]
}Template Schema
/api/v1/templates/:id/schemaReturns the JSON schema and default PDF options for a specific template. Use this to validate your data before calling the generate endpoint.
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | string | Required | Template ID (e.g., invoice-basic, weekly-report) |
Example
curl https://api.docujson.com/v1/templates/invoice-basic/schema{
"templateId": "invoice-basic",
"templateName": "Basic Invoice",
"schema": {
"type": "object",
"required": ["invoiceNumber", "items", "client"],
"properties": {
"invoiceNumber": { "type": "string", "description": "Invoice number" },
"items": { "type": "array", "items": { ... } },
"client": { "type": "object", "properties": { ... } }
}
},
"defaultOptions": {
"format": "Letter",
"orientation": "portrait",
"margin": { "top": "0.75in", "right": "0.75in", "bottom": "0.75in", "left": "0.75in" }
}
}Output Formats
Control how the generated PDF is delivered using the outputFormat field.
urlDefaultReturns a hosted PDF URL via Vercel Blob Storage. The URL is permanent and never expires. Best for Airtable attachment fields, email links, and most integrations.
base64Returns the PDF as a base64-encoded string in the JSON response body. Useful when you need to process the PDF directly without downloading it.
bufferReturns the raw PDF binary as the response body with Content-Type: application/pdf. Ideal for direct file downloads or piping to storage.
{
"templateId": "invoice-basic",
"data": { ... },
"outputFormat": "base64"
}
// Response:
{
"success": true,
"base64": "JVBERi0xLjQKJeLjz9MKMSAwIG9ia...",
"templateId": "invoice-basic",
"generatedAt": "2026-02-10T12:00:00.000Z"
}PDF Options
Customize the PDF output using the options field. These override template defaults.
| Parameter | Type | Required | Description |
|---|---|---|---|
| format | string | Optional | "Letter" (default), "A4", or "Legal" |
| orientation | string | Optional | "portrait" (default) or "landscape" |
| margin | object | Optional | Custom margins: { top, right, bottom, left } as CSS strings (e.g., "0.5in", "10mm") |
| displayHeaderFooter | boolean | Optional | Show header/footer in the PDF |
| headerTemplate | string | Optional | Custom HTML header template |
| footerTemplate | string | Optional | Custom HTML footer template |
{
"templateId": "kpi-dashboard",
"data": { ... },
"options": {
"format": "A4",
"orientation": "landscape",
"margin": { "top": "0.5in", "right": "0.5in", "bottom": "0.5in", "left": "0.5in" }
}
}Webhooks
For long-running PDF generation, use webhooks to receive the result asynchronously. DocuJSON will POST the result to your URL when the PDF is ready.
Webhooks are available on the Pro plan and above. This is the recommended pattern when using platforms with short timeouts (Airtable 30s, Zapier 30s).
// Request
{
"templateId": "calendar-schedule",
"data": { ... },
"webhook": {
"url": "https://hooks.zapier.com/your-catch-hook",
"headers": {
"X-Webhook-Secret": "your-secret-value"
}
}
}When the PDF is ready, DocuJSON sends a POST request to your webhook URL:
// Webhook payload (POST to your URL)
{
"success": true,
"pdfUrl": "https://storage.docujson.com/calendar-abc123.pdf",
"templateId": "calendar-schedule",
"generatedAt": "2026-02-10T12:00:00.000Z"
}Error Handling
All errors return a JSON response with success: false and an error message.
| Status | Error | Description |
|---|---|---|
| 400 | Missing required field: templateId | Request body is missing templateId |
| 400 | Missing required field: data | Request body is missing data object |
| 400 | Template 'x' not found | Invalid template ID. Returns list of available templates. |
| 400 | Invalid data for template | Data doesn't match the template schema. Returns validationErrors array. |
| 401 | Missing API key | No X-API-Key or Authorization header provided |
| 401 | Invalid or inactive API key | API key is incorrect or has been deactivated |
| 403 | Template 'x' is not enabled | Template exists but isn't enabled for your workspace |
| 403 | Workspace is suspended | Your workspace has been suspended |
| 429 | Monthly PDF generation limit reached | You've hit your plan's monthly limit. Returns limit, used, and remaining. |
| 500 | PDF generation failed | Internal error during rendering. Returns details. |
Error Response Example
// 400 - Validation Error
{
"success": false,
"error": "Invalid data for template",
"validationErrors": [
"Missing required field: invoiceNumber",
"Missing required field: items"
]
}
// 429 - Rate Limited
{
"success": false,
"error": "Monthly PDF generation limit reached",
"limit": 100,
"used": 100,
"remaining": 0
}Template Payloads
Complete example payloads for each template. Use the Schema API to get the full JSON schema for validation.
Basic Invoice
invoice-basicFreeRequired fields: invoiceNumber, items, client
{
"templateId": "invoice-basic",
"data": {
"invoiceNumber": "INV-2026-001",
"invoiceDate": "2026-02-10",
"dueDate": "2026-03-10",
"company": {
"name": "Northwind Consulting",
"address": "742 Evergreen Terrace, Suite 200",
"email": "billing@northwind.io",
"phone": "(555) 867-5309"
},
"client": {
"name": "Meridian Technologies",
"address": "1600 Innovation Blvd",
"email": "accounts@meridiantech.com"
},
"items": [
{ "description": "Web Development", "quantity": 40, "unitPrice": 150, "amount": 6000 },
{ "description": "Design Review", "quantity": 8, "unitPrice": 125, "amount": 1000 }
],
"subtotal": 7000,
"tax": 630,
"total": 7630,
"notes": "Payment due within 30 days",
"paymentInstructions": "Wire to: Bank of America, Routing: 123456789"
}
}Weekly Report
weekly-reportFreeRequired fields: projects
{
"templateId": "weekly-report",
"data": {
"reportTitle": "Engineering Weekly Status",
"versionAsOf": "02/10/2026",
"projects": [
{
"title": "Platform Migration",
"status": "In Progress",
"releaseDate": "06/15/2026",
"answerPrint": "05/01/2026",
"progress": 68,
"stakeholders": {
"studio": {
"creativeExec": "Maria Chen",
"productionExec": "David Park"
},
"production": {
"director": "Sarah Kim",
"producers": "Alex Rivera, Jordan Lee"
}
},
"milestones": [
{ "name": "Architecture Review", "startDate": "03/15/2026", "status": "Pending" },
{ "name": "Load Testing", "startDate": "04/15/2026", "status": "Pending" }
],
"updates": {
"thisWeek": { "id": "W-012", "text": "Completed database schema migration for users service" },
"lastWeek": { "id": "W-011", "text": "API gateway configuration finalized and deployed" }
}
}
]
}
}Calendar Schedule
calendar-scheduleProRequired fields: months
{
"templateId": "calendar-schedule",
"data": {
"projectTitle": "Product Launch 2026",
"orientation": "Landscape",
"masthead": ["02.10.26", "PRODUCT LAUNCH", "RELEASE SCHEDULE", "12 WEEKS"],
"palette": {
"dev": "#7c3aed",
"review": "#ea580c",
"milestone": "#b45309"
},
"legend": {
"dev": "Development Sprint",
"review": "Stakeholder Review",
"milestone": "Key Milestone"
},
"months": [
{ "y": 2026, "m": 3 },
{ "y": 2026, "m": 4 },
{ "y": 2026, "m": 5 }
],
"events": [
{ "date": "2026-03-15", "kind": "milestone", "text": "Feature Freeze" },
{ "date": "2026-05-01", "kind": "milestone", "text": "Launch Day" }
],
"ranges": [
{ "start": "2026-04-01", "end": "2026-04-12", "kind": "review", "label": "QA Testing" },
{ "start": "2026-03-01", "end": "2026-03-20", "kind": "dev", "label": "Sprint 4" }
]
}
}KPI Dashboard
kpi-dashboardProRequired fields: title, metrics
{
"templateId": "kpi-dashboard",
"data": {
"title": "Q1 2026 Performance Dashboard",
"subtitle": "January - March 2026",
"metrics": [
{ "label": "Revenue", "value": "$1.2M", "change": "+12%", "trend": "up" },
{ "label": "Active Users", "value": "8,432", "change": "+5%", "trend": "up" },
{ "label": "Churn Rate", "value": "2.1%", "change": "-0.3%", "trend": "down" },
{ "label": "NPS Score", "value": "72", "change": "+4", "trend": "up" }
],
"sections": [
{ "title": "Key Wins", "content": "Launched new pricing tier, expanded to EU market" },
{ "title": "Focus Areas", "content": "Reduce onboarding time, improve API latency" }
]
}
}Rate Limits
PDF generation is rate-limited per workspace based on your plan.
| Plan | Monthly Limit | Templates | Webhooks |
|---|---|---|---|
| Free | 100 PDFs | 2 templates | -- |
| Pro | 1,000 PDFs | All templates | Included |
| Business | 10,000 PDFs | All + custom | Included |
When you hit your limit, the API returns a 429 status with your current usage. Limits reset on the 1st of each month. View full pricing
Ready to Get Started?
Create your free account and generate your first PDF in minutes.