Pdf Generation Api
PDF Forms and PDF Pages API - Complete Documentation
Learn how to generate PDFs programmatically using Tadabase PDF Forms (fill existing PDFs) and PDF Pages (generate PDFs from data) via the REST API v1.1.
Two PDF Generation Methods
PDF Forms: Fill existing PDF form templates with data
PDF Pages: Generate custom PDFs from scratch using record data and layouts
API Version and Permissions Required
These endpoints use API v1.1 (not v1). Your API key must have allow_pdf_form or allow_pdf_page permissions enabled, and your plan must allow PDF generation.
Table of Contents
PDF Forms API
PDF Forms allow you to fill existing PDF form templates with data. Upload a PDF form with fillable fields in the Tadabase builder, then use the API to populate those fields.
List All PDF Forms
GET /api/v1.1/{appId}/pdf-forms
Headers:
X-Tadabase-App-id: your_app_id
X-Tadabase-App-Key: your_app_key
X-Tadabase-App-Secret: your_app_secret
Response
{
"status": "success",
"items": [
{
"id": "encoded_id",
"name": "Employment Agreement",
"pdf_id": "external_pdf_id",
"app_id": "encoded_app_id",
"created_at": "2024-01-01 00:00:00",
"placeholders": [
{
"id": "field_id",
"type": "text",
"name": "employee_name"
},
{
"id": "field_id_2",
"type": "checkbox",
"name": "agree_terms"
}
]
}
],
"totalItems": 5
}
Response Fields
| Field | Description |
|---|---|
id |
Encoded PDF form ID |
name |
PDF form name |
pdf_id |
External PDF identifier |
placeholders |
Array of fillable fields in the PDF form |
created_at |
When the form was created |
Note on Response Fields
The API automatically removes sensitive fields from responses: password, path, and folder are excluded for security.
Get Single PDF Form
GET /api/v1.1/{appId}/pdf-forms/{pdfFormId}
Headers:
X-Tadabase-App-id: your_app_id
X-Tadabase-App-Key: your_app_key
X-Tadabase-App-Secret: your_app_secret
Response
{
"status": "success",
"item": {
"id": "encoded_id",
"name": "Employment Agreement",
"pdf_id": "external_pdf_id",
"app_id": "encoded_app_id",
"placeholders": [
{
"id": "placeholder_id",
"type": "text",
"name": "employee_name"
},
{
"id": "placeholder_id_2",
"type": "checkbox",
"name": "agree_terms"
},
{
"id": "placeholder_id_3",
"type": "select",
"name": "department"
}
],
"created_at": "2024-01-01 00:00:00"
}
}
Generate/Fill PDF Form
Fill a PDF form template with provided data and return the completed PDF.
POST /api/v1.1/{appId}/pdf-forms/{pdfFormId}/create?format=file
Headers:
X-Tadabase-App-id: your_app_id
X-Tadabase-App-Key: your_app_key
X-Tadabase-App-Secret: your_app_secret
Content-Type: application/json
Body:
{
"fileName": "completed-agreement",
"mapping": {
"employee_name": "John Doe",
"start_date": "2024-01-15",
"agree_terms": "1",
"department": "Engineering"
}
}
Request Parameters
| Parameter | Location | Type | Description |
|---|---|---|---|
format |
Query | string | Optional. file returns PDF file, omit for base64 JSON response |
fileName |
Body | string | Optional. PDF filename (default: "pdf-form") |
mapping |
Body | object | Field name/value pairs to fill in the PDF form |
Response (format=file)
Returns raw PDF file with headers:
Content-Type: application/pdf
Content-Disposition: attachment; filename="completed-agreement.pdf"
Response (without format parameter)
{
"status": "success",
"name": "completed-agreement",
"fileData": "JVBERi0xLjQKJeLjz9MKMyAwIG9iago8PC9UeXBlL... (base64 encoded PDF)"
}
Field Type Values
| Field Type | Value Format | Example |
|---|---|---|
| text | String | "John Doe" |
| checkbox | "1" for checked, "0" or empty for unchecked | "1" |
| radio | Selected option value | "option_a" |
| select | Selected option value | "Engineering" |
| date | YYYY-MM-DD format | "2024-01-15" |
Error Responses
{
"status": "error",
"msg": "PDF Form not found"
}
{
"status": "error",
"msg": "API key does not have pdf_form permission"
}
{
"status": "error",
"msg": "Plan limit reached for PDF forms"
}
PDF Pages API
PDF Pages generate custom PDFs from scratch using your data and custom layouts. Design the PDF layout in the Tadabase builder, then use the API to generate PDFs with record data.
List All PDF Pages
GET /api/v1.1/{appId}/pdf-pages
Headers:
X-Tadabase-App-id: your_app_id
X-Tadabase-App-Key: your_app_key
X-Tadabase-App-Secret: your_app_secret
Response
{
"status": "success",
"items": [
{
"id": "encoded_id",
"name": "Invoice Template",
"data_table_id": "table_id",
"pdf_layout_id": "layout_id",
"metas": {
"is_file_name": "DetailField",
"file_name": "",
"file_name_detail_field": "invoice_number"
}
},
{
"id": "encoded_id_2",
"name": "Report Template",
"data_table_id": "table_id_2",
"pdf_layout_id": "layout_id_2",
"metas": {
"is_file_name": "Yes",
"file_name": "Monthly-Report"
}
}
],
"totalItems": 3
}
Note on PDF JSON
The pdf_json field (which contains the PDF layout structure) is automatically removed from list responses for performance. It's only included when fetching a single PDF page.
Get Single PDF Page
GET /api/v1.1/{appId}/pdf-pages/{pdfPageId}
Headers:
X-Tadabase-App-id: your_app_id
X-Tadabase-App-Key: your_app_key
X-Tadabase-App-Secret: your_app_secret
Response
{
"status": "success",
"item": {
"id": "encoded_id",
"name": "Invoice Template",
"data_table_id": "table_id",
"pdf_layout_id": "layout_id",
"metas": {
"is_file_name": "DetailField",
"file_name": "",
"file_name_detail_field": "invoice_number",
"css": "body { font-family: Arial; }",
"js": "console.log('PDF generated');",
"hasnewdesign": 1
}
}
}
Generate PDF Page
Generate a PDF from a PDF page template with optional record data and custom design settings.
POST /api/v1.1/{appId}/pdf-pages/{pdfPageId}/create/{recordId}?format=link
Headers:
X-Tadabase-App-id: your_app_id
X-Tadabase-App-Key: your_app_key
X-Tadabase-App-Secret: your_app_secret
Content-Type: application/json
Body:
{
"designMetas": {
"page": {
"size": "A4",
"orientation": "portrait",
"margin_top": 20,
"margin_bottom": 20
},
"is_header": "Yes",
"header": {
"column": 2,
"column1_con": "Image",
"column1_img": "https://example.com/logo.png",
"column2_con": "PageNumber"
}
}
}
Path Parameters
| Parameter | Required | Description |
|---|---|---|
pdfPageId |
Yes | Encoded PDF page template ID |
recordId |
Conditional | Required if PDF page is connected to a data table |
Query Parameters
| Parameter | Options | Description |
|---|---|---|
format |
file, link |
file=download PDF, link=S3 URL, omit for base64 JSON |
Response (format=file)
Returns raw PDF file with headers:
Content-Type: application/pdf
Content-Disposition: attachment; filename="invoice-2024.pdf"
Response (format=link)
{
"status": "success",
"name": "invoice-2024",
"url": "https://s3.amazonaws.com/bucket/pdfs/invoice-2024.pdf",
"expires_at": "2024-01-15T12:00:00Z"
}
Response (without format parameter)
{
"status": "success",
"name": "invoice-2024",
"fileData": "JVBERi0xLjQKJeLjz9MKMyAwIG9iago8PC9UeXBlL... (base64 encoded PDF)"
}
Error Responses
{
"status": "error",
"msg": "PDF Not found"
}
{
"status": "error",
"msg": "Record ID is required for this PDF page"
}
{
"status": "error",
"msg": "API key does not have pdf_page permission"
}
{
"status": "error",
"msg": "Plan limit reached for PDF pages"
}
Common Design Settings (designMetas)
Override the default PDF design settings when generating a PDF page. All settings are optional.
Page Settings
{
"page": {
"size": "A4", // A4, Letter, Legal
"orientation": "portrait", // portrait or landscape
"margin_top": 20, // millimeters
"margin_right": 20,
"margin_bottom": 20,
"margin_left": 20,
"margin_level": "Page",
"font_size": 12, // Default font size
"color": "#000000", // Text color (hex)
"bk_color": "#ffffff", // Background color (hex)
"bg_img": "https://example.com/bg.jpg", // Background image URL
"bg_pos": "center center", // CSS background-position
"bg_repeat": "no-repeat", // CSS background-repeat
"bg_rotate": "0", // Rotation in degrees
"bg_opacity": 5 // 0-10 scale (divided by 10 for actual opacity)
}
}
Page Size Options
| Size | Dimensions |
|---|---|
A4 |
210mm × 297mm |
Letter |
8.5in × 11in |
Legal |
8.5in × 14in |
Header and Footer Settings
Both header and footer share the same structure and support up to 3 columns.
{
"is_header": "Yes", // Enable header
"header": {
"height": 10, // Height in millimeters
"margin_top": 10,
"margin_right": 10,
"margin_bottom": 10,
"margin_left": 10,
"font_size": 12,
"color": "#000000",
"bk_color": "#ffffff",
"column": 2, // Number of columns (1-3)
"column1_con": "Image", // Text, Image, or PageNumber
"column1_img": "https://example.com/logo.png",
"column1_align": "top", // top, middle, or bottom
"column2_con": "PageNumber",
"column2_align": "middle",
"column3_con": "Text",
"column3_text": "Confidential",
"column3_align": "bottom"
},
"is_footer": "Yes",
"footer": {
"height": 10,
"column": 1,
"column1_con": "Text",
"column1_text": "© 2024 Company Name"
}
}
Column Content Types
| Type | Fields Required | Description |
|---|---|---|
Text |
column{N}_text |
Static text content |
Image |
column{N}_img |
Image URL to display |
PageNumber |
None | Automatic page numbering (e.g., "Page 1 of 5") |
Background Image Settings
{
"is_background": "Yes",
"page": {
"bg_img": "https://example.com/watermark.png",
"bg_pos": "center center",
"bg_repeat": "no-repeat",
"bg_rotate": "45",
"bg_opacity": 3
}
}
File Naming Options (PDF Pages Only)
Control how the generated PDF file is named using the metas object in the PDF page configuration.
Option 1: Static Name
{
"is_file_name": "Yes",
"file_name": "Invoice-2024"
}
// Result: Invoice-2024.pdf
Option 2: From Record Field
{
"is_file_name": "DetailField",
"file_name_detail_field": "invoice_number"
}
// Result: INV-00123.pdf (uses value from invoice_number field)
Option 3: Default (Use PDF Page Name)
{
"is_file_name": "No"
}
// Result: Uses the PDF page's name property
Security and Permissions
Required Permissions
To use PDF generation endpoints, you must have:
- Valid API key with
allow_api_accessenabled allow_pdf_formpermission for PDF Forms endpointsallow_pdf_pagepermission for PDF Pages endpoints- Plan must allow PDF generation (not exceeded limits)
- Rate limiting applies via
tb.throttlemiddleware
Usage Tracking and Limits
Both PDF Forms and PDF Pages trigger usage tracking:
- pdf_forms - Tracked when generating PDF forms
- pdf_pages - Tracked when generating PDF pages
Plan limits are checked before generation:
total_pdf_forms- Maximum PDF forms per monthtotal_pdf_pages- Maximum PDF pages per month
Complete Examples
Example 1: Generate PDF Form with File Download
curl -X POST "https://api.tadabase.io/api/v1.1/YOUR_APP_ID/pdf-forms/FORM_ID/create?format=file" \
-H "Content-Type: application/json" \
-H "X-Tadabase-App-id: YOUR_APP_ID" \
-H "X-Tadabase-App-Key: YOUR_API_KEY" \
-H "X-Tadabase-App-Secret: YOUR_API_SECRET" \
-d '{
"fileName": "employment-agreement",
"mapping": {
"employee_name": "John Doe",
"employee_email": "john@example.com",
"start_date": "2024-02-01",
"position": "Software Engineer",
"salary": "100000",
"agree_terms": "1"
}
}' --output employment-agreement.pdf
Example 2: Generate PDF Page with S3 Link
curl -X POST "https://api.tadabase.io/api/v1.1/YOUR_APP_ID/pdf-pages/PAGE_ID/create/RECORD_ID?format=link" \
-H "Content-Type: application/json" \
-H "X-Tadabase-App-id: YOUR_APP_ID" \
-H "X-Tadabase-App-Key: YOUR_API_KEY" \
-H "X-Tadabase-App-Secret: YOUR_API_SECRET" \
-d '{
"designMetas": {
"page": {
"size": "A4",
"orientation": "portrait",
"margin_top": 25,
"margin_right": 20,
"margin_bottom": 25,
"margin_left": 20
},
"is_header": "Yes",
"header": {
"height": 15,
"column": 2,
"column1_con": "Image",
"column1_img": "https://example.com/company-logo.png",
"column1_align": "middle",
"column2_con": "PageNumber",
"column2_align": "middle"
},
"is_footer": "Yes",
"footer": {
"height": 10,
"column": 1,
"column1_con": "Text",
"column1_text": "Company Name - Confidential Document",
"column1_align": "middle"
}
}
}'
Example 3: JavaScript - Generate Invoice PDF
async function generateInvoice(appId, pdfPageId, orderId) {
const response = await fetch(
`https://api.tadabase.io/api/v1.1/${appId}/pdf-pages/${pdfPageId}/create/${orderId}?format=link`,
{
method: 'POST',
headers: {
'X-Tadabase-App-id': appId,
'X-Tadabase-App-Key': 'your_api_key',
'X-Tadabase-App-Secret': 'your_api_secret',
'Content-Type': 'application/json'
},
body: JSON.stringify({
designMetas: {
page: {
size: 'A4',
orientation: 'portrait'
},
is_header: 'Yes',
header: {
column: 1,
column1_con: 'Image',
column1_img: 'https://example.com/logo.png'
}
}
})
}
);
const data = await response.json();
if (data.status === 'success') {
console.log('Invoice PDF generated:', data.url);
return data.url;
} else {
throw new Error(`PDF generation failed: ${data.msg}`);
}
}
// Usage
const pdfUrl = await generateInvoice('74QY8R4ENB', 'pdf_page_id', 'order_123');
console.log('Download invoice at:', pdfUrl);
Example 4: JavaScript - Fill PDF Form and Get Base64
async function fillPDFForm(appId, pdfFormId, formData) {
const response = await fetch(
`https://api.tadabase.io/api/v1.1/${appId}/pdf-forms/${pdfFormId}/create`,
{
method: 'POST',
headers: {
'X-Tadabase-App-id': appId,
'X-Tadabase-App-Key': 'your_api_key',
'X-Tadabase-App-Secret': 'your_api_secret',
'Content-Type': 'application/json'
},
body: JSON.stringify({
fileName: 'completed-form',
mapping: formData
})
}
);
const data = await response.json();
if (data.status === 'success') {
// data.fileData contains base64 encoded PDF
// Convert to blob for download
const binaryData = atob(data.fileData);
const bytes = new Uint8Array(binaryData.length);
for (let i = 0; i
Example 5: Bulk PDF Generation
async function generateBulkInvoices(appId, pdfPageId, orderIds) {
const results = [];
for (const orderId of orderIds) {
try {
const response = await fetch(
`https://api.tadabase.io/api/v1.1/${appId}/pdf-pages/${pdfPageId}/create/${orderId}?format=link`,
{
method: 'POST',
headers: {
'X-Tadabase-App-id': appId,
'X-Tadabase-App-Key': 'your_api_key',
'X-Tadabase-App-Secret': 'your_api_secret',
'Content-Type': 'application/json'
}
}
);
const data = await response.json();
if (data.status === 'success') {
results.push({
orderId,
success: true,
pdfUrl: data.url,
fileName: data.name
});
} else {
results.push({
orderId,
success: false,
error: data.msg
});
}
// Rate limit friendly - wait 1 second between requests
await new Promise(resolve => setTimeout(resolve, 1000));
} catch (error) {
results.push({
orderId,
success: false,
error: error.message
});
}
}
return results;
}
// Usage
const orderIds = ['order_1', 'order_2', 'order_3'];
const results = await generateBulkInvoices('74QY8R4ENB', 'pdf_page_id', orderIds);
const successful = results.filter(r => r.success);
console.log(`Generated ${successful.length}/${results.length} invoices`);
results.forEach(result => {
if (result.success) {
console.log(`✓ ${result.orderId}: ${result.pdfUrl}`);
} else {
console.log(`✗ ${result.orderId}: ${result.error}`);
}
});
Important Notes
- All IDs in the API are encoded using the application's encoding scheme
- Maximum file size and generation time may be limited by the external service
- Custom CSS and JavaScript can be included in PDF pages via the
metasobject - PDF URLs from S3 (
format=link) may have expiration times - Background images support rotation and opacity for watermark effects
Best Practices
- Test Templates First: Verify PDF templates render correctly in the builder before using the API
- Use Appropriate Format: Use
format=linkfor sharing,format=filefor direct downloads, and base64 for embedding - Handle Rate Limits: Add delays between bulk PDF generations (1 second recommended)
- Store PDF References: Save generated PDF URLs in your database for future access
- Validate Data: Ensure all required fields have values before generating PDFs
- Error Handling: Always check the
statusfield in responses and handle errors gracefully - Monitor Usage: Track PDF generation counts to avoid hitting plan limits
- Optimize Images: Use appropriately sized images in headers/footers for faster generation
- Test Different Sizes: Test PDFs with different page sizes and orientations
- Cache When Possible: Avoid regenerating the same PDF multiple times
Troubleshooting
Common Issues
| Error | Cause | Solution |
|---|---|---|
| PDF Form not found | Invalid form ID | Verify form ID using GET /pdf-forms endpoint |
| PDF Not found | Invalid page ID | Verify page ID using GET /pdf-pages endpoint |
| Record ID is required | PDF page needs record data | Provide recordId in URL path |
| Permission denied | Missing API key permission | Enable allow_pdf_form or allow_pdf_page permission |
| Plan limit reached | Monthly PDF limit exceeded | Upgrade plan or wait for limit reset |
| Generation timeout | PDF too complex or large images | Simplify layout or optimize images |
Next Steps
Learn more about automating workflows with PDFs:
→ Tasks API - Schedule automated PDF generation
→ Automations API - Trigger PDF generation from events
→ Working with Records - Manage data for PDF generation
We'd love to hear your feedback.