Loading DocuJSON
Loading docs
Create templates from prompts, screenshots, references, and sample JSON. Map the fields, publish, then generate PDFs with an API your developers can read.
Generate your first PDF in under 5 minutes. All you need is an API key.
Use the AI Template Builder to draft a layout from a prompt, screenshot, reference PDF, or sample JSON. Or start from a public template like invoice-basic.
Send a POST request with your template ID and data.
curl -X POST https://api.docujson.com/v1/generate \
-H "Authorization: Bearer dj_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"templateId": "invoice-basic",
"data": {
"invoice_number": "INV-0001",
"issue_date": "2026-04-13",
"due_date": "2026-05-13",
"from": { "name": "Your Company" },
"to": { "name": "Customer Corp" },
"line_items": [
{ "description": "Consulting", "quantity": 10, "unit_price": 150 }
],
"tax_rate": 0.0875
}
}'A standard HTTPS URL. Download it, email it, or store it according to your retention requirements.
{
"success": true,
"pdfUrl": "https://blob.vercel-storage.com/...",
"templateId": "invoice-basic",
"generatedAt": "2026-04-13T12:00:00.000Z"
}All API requests require authentication via an API key. Keys use the format dj_<uuid> and are created from your dashboard. Only a SHA-256 hash of the key is stored on our side.
You can pass the key using either header:
# Recommended: Authorization Bearer header
curl -H "Authorization: Bearer dj_your_api_key" https://api.docujson.com/v1/generate
# Also supported: X-API-Key header
curl -H "X-API-Key: dj_your_api_key" https://api.docujson.com/v1/generateKeep your API key secure
Never expose your API key in client-side code. Use it from server-side scripts, automation platforms, or scripting extensions like Airtable.
The AI Template Builder is how you go from an idea to a published, mapped template. It is a creation workflow, not the standard runtime generation path. Inputs are accepted as a prompt, a screenshot, a reference PDF or HTML document, or sample JSON.
/api/v1/generateGenerate a PDF document from a published template and data. Returns a hosted PDF URL by default.
| Parameter | Type | Required | Description |
|---|---|---|---|
| templateId | string | Required | Template to use. Public templates: invoice-basic, weekly-report, calendar-schedule, kpi-dashboard. Or a custom published templateId. |
| data | object | Required | Data that matches the template schema. See Template Payloads below. |
| options | object | Optional | PDF output options (format, orientation, margins). See PDF Options. |
| outputFormat | string | Optional | "url" (default), "base64", or "buffer". See Output Formats. |
| webhook | object | Optional | Async delivery. Object with url (string) and optional headers (object). See Webhooks. |
| Parameter | Type | Required | Description |
|---|---|---|---|
| success | boolean | Required | Whether the request succeeded |
| pdfUrl | string | Optional | Hosted PDF URL (when outputFormat is "url"). See PDF Delivery URLs for the two URL shapes returned by Hobby/Starter vs Business/Enterprise/HIPAA workspaces. |
| base64 | string | Optional | Base64-encoded PDF (when outputFormat is "base64") |
| templateId | string | Required | The template that was used |
| generatedAt | string | Required | ISO 8601 timestamp |
| Parameter | Type | Required | Description |
|---|---|---|---|
| X-Generation-Time-Ms | number | Required | Time taken to generate the PDF (ms) |
| X-PDF-Size-Bytes | number | Required | Size of the generated PDF (bytes) |
| X-Usage-Remaining | number | Required | Remaining PDF generations for the current billing period |
| X-RateLimit-Limit | number | Required | Requests allowed per minute |
| X-RateLimit-Remaining | number | Required | Requests left in this window |
| X-RateLimit-Reset | number | Required | Unix timestamp when the window resets |
const response = await fetch('https://api.docujson.com/v1/generate', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer dj_your_api_key',
},
body: JSON.stringify({
templateId: 'weekly-report',
data: {
reportTitle: 'Engineering Weekly Status',
versionAsOf: '04/13/2026',
projects: [
{
title: 'Platform Migration',
status: 'In Progress',
progress: 68,
releaseDate: '05/15/2026',
},
],
},
options: {
format: 'Letter',
orientation: 'portrait',
},
}),
});
const { success, pdfUrl } = await response.json();
console.log(pdfUrl);The pdfUrl in your response comes in one of two shapes, determined automatically by your workspace plan and compliance settings. Either way, the URL is the canonical handle to your PDF — store it, share it, or fetch it.
Public Vercel Blob URL. Fetch with any HTTP client — no auth header required.
https://<blob-host>.public.blob.vercel-storage.com/<id>.pdfProxied through DocuJSON. The API returns the proxy URL instead of the raw Blob URL; every fetch must include your x-api-key (or be a logged-in dashboard session), and when configured the proxy enforces a signed ?t=<jwt>TTL. The underlying Blob is stored at a guess-resistant UUID path on a public Vercel Blob host — treat the raw Blob URL as a secret and never share or log it. Private object storage for sensitive tiers is future infra work; today the security boundary is the proxy.
https://api.docujson.com/v1/pdfs/<id>// Hobby / Starter workspace
{
"success": true,
"pdfUrl": "https://blob.vercel-storage.com/invoice-abc123.pdf",
"templateId": "invoice-basic",
"generatedAt": "2026-04-13T12:00:00.000Z"
}
// Business / Enterprise / HIPAA-enabled workspace
{
"success": true,
"pdfUrl": "https://api.docujson.com/v1/pdfs/abc123",
"templateId": "invoice-basic",
"generatedAt": "2026-04-13T12:00:00.000Z"
}If your workspace returns proxy URLs, follow-up downloads must carry the same x-api-key header. Sharing the URL with someone who cannot authenticate will produce a 401.
curl -L -o invoice.pdf \
-H "x-api-key: dj_your_api_key" \
https://api.docujson.com/v1/pdfs/abc123Why two shapes?
Higher-tier and regulated workspaces require that PDF artifacts cannot be accessed by anyone who guesses or intercepts the URL. The proxy enforces the same access controls as the generate endpoint and records each download in the audit log. Lower tiers keep the simpler direct-URL flow.
/api/v1/templatesReturns all available templates. No authentication required for public templates.
| Parameter | Type | Required | Description |
|---|---|---|---|
| category | string | Optional | Filter by category: calendar, report, dashboard, invoice |
| id | string | Optional | Get a specific template by ID |
{
"templates": [
{ "id": "invoice-basic", "name": "Basic Invoice", "category": "invoice", "version": "1.0.0" },
{ "id": "weekly-report", "name": "Weekly Project Report", "category": "report", "version": "1.0.0" },
{ "id": "calendar-schedule", "name": "Project Calendar", "category": "calendar", "version": "1.0.0" },
{ "id": "kpi-dashboard", "name": "KPI Dashboard", "category": "dashboard", "version": "1.0.0" }
],
"total": 4,
"categories": ["calendar", "report", "dashboard", "invoice", "certificate", "custom"]
}/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.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | string | Required | Template ID (e.g., invoice-basic, weekly-report) |
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" }
}
}Control how the generated PDF is delivered using the outputFormat field.
urlDefaultReturns a hosted PDF URL. Hobby and Starter workspaces receive a public Vercel Blob URL; Business, Enterprise, and HIPAA-enabled workspaces receive an auth-gated proxy URL that requires the same x-api-key on fetch. See PDF Delivery URLs.
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-04-13T12:00:00.000Z"
}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" }
}
}For long-running PDF generation, include a webhook.url in your request. DocuJSON will POST the result to your URL when the PDF is ready.
Webhooks are available on Starter 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://blob.vercel-storage.com/calendar-abc123.pdf",
"templateId": "calendar-schedule",
"generatedAt": "2026-04-13T12:00:00.000Z"
}Standard HTTP status codes. Error bodies follow this shape:
{
"error": {
"code": "invalid_template_data",
"message": "Field 'invoice_number' is required",
"request_id": "req_xyz789"
}
}Include request_id when filing a support ticket — it makes debugging much faster.
| 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 Authorization or X-API-Key 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. |
| 500 | PDF generation failed | Internal error during rendering. Returns details. |
PDF generation is rate-limited per workspace based on your plan. Every response includes rate-limit headers so you can adapt your client.
| Plan | Monthly PDFs | Templates | Webhooks |
|---|---|---|---|
| Hobby | 100 | All public | — |
| Starter | 1,000 | All + custom uploads | Included |
| Business | 10,000 | All + AI builder | Included |
| Enterprise | 100,000+ | Custom | Included |
When you hit your limit, the API returns a 429 with your current usage. Limits reset on the 1st of each month. View full pricing
Complete example payloads for each public template. Use the Schema API to get the full JSON schema for validation.
invoice-basicHobbyRequired fields: invoiceNumber, items, client
{
"templateId": "invoice-basic",
"data": {
"invoiceNumber": "INV-2026-001",
"invoiceDate": "2026-04-13",
"dueDate": "2026-05-13",
"company": {
"name": "Northwind Consulting",
"address": "742 Evergreen Terrace, Suite 200",
"email": "billing@northwind.io"
},
"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
}
}weekly-reportHobbyRequired fields: projects
{
"templateId": "weekly-report",
"data": {
"reportTitle": "Engineering Weekly Status",
"versionAsOf": "04/13/2026",
"projects": [
{
"title": "Platform Migration",
"status": "In Progress",
"releaseDate": "06/15/2026",
"progress": 68,
"milestones": [
{ "name": "Architecture Review", "startDate": "03/15/2026", "status": "Pending" }
],
"updates": {
"thisWeek": { "text": "Completed database schema migration." },
"lastWeek": { "text": "API gateway configuration finalized." }
}
}
]
}
}calendar-scheduleStarterRequired fields: months
{
"templateId": "calendar-schedule",
"data": {
"projectTitle": "Product Launch 2026",
"orientation": "Landscape",
"masthead": ["04.13.26", "PRODUCT LAUNCH", "RELEASE SCHEDULE", "12 WEEKS"],
"palette": { "dev": "#7c3aed", "review": "#ea580c", "milestone": "#b45309" },
"legend": { "dev": "Development Sprint", "review": "Review", "milestone": "Milestone" },
"months": [{ "y": 2026, "m": 3 }, { "y": 2026, "m": 4 }, { "y": 2026, "m": 5 }],
"events": [{ "date": "2026-05-01", "kind": "milestone", "text": "Launch Day" }],
"ranges": [{ "start": "2026-04-01", "end": "2026-04-12", "kind": "review", "label": "QA" }]
}
}kpi-dashboardStarterRequired 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" }
]
}
}