Airtable Integration

Generate PDFs from Airtable records using the DataToPDF API.

Prerequisites

  1. A DataToPDF account with a Starter plan or higher (API access required)
  2. An API key generated from Settings > API Key
  3. A PDF template configured with Airtable as the data source
  4. Airtable connected to your DataToPDF account

Setup

Connect your Airtable account in DataToPDF:

  1. Go to Settings > Integrations > Airtable
  2. Enter your Airtable Personal Access Token
  3. Click Connect

Creating an Airtable Personal Access Token

  1. Go to https://airtable.com/create/tokens
  2. Click Create new token
  3. Add the following scopes:
    • data.records:read - Required for reading records
    • schema.bases:read - Required for listing bases and tables
    • data.records:write - Required for attaching PDFs to records
  4. Select the bases you want to access (or all bases)
  5. Click Create token and copy the token

API Usage

Endpoint

POST https://datatopdf.app/api/v1/pdf/generate

Request

{
  "templateId": "your_template_id",
  "recordId": "airtable_record_id",
  "uploadToRecord": false,
  "fileName": "custom-filename.pdf",
  "attachmentFieldName": "PDF"
}
ParameterTypeRequiredDescription
templateIdstringYesID of the PDF template to use
recordIdstringNoAirtable record ID (starts with rec) for the table configured in your template
uploadToRecordbooleanNoIf true, uploads the generated PDF to the Airtable record's attachment field
fileNamestringNoCustom file name for the PDF (defaults to template name)
attachmentFieldNamestringNoName of the Airtable attachment field to upload to (defaults to "PDF")

Airtable Automations

You can automate PDF generation using Airtable Automations with script actions.

Option 1: Script Action

Use a script action to call the DataToPDF API directly from an Airtable automation.

Setup

  1. Go to your Airtable base
  2. Click Automations in the top navigation
  3. Create a new automation or edit an existing one
  4. Add a trigger (e.g., "When record matches conditions")
  5. Add a Run a script action

JavaScript Script

// Configuration
const DATATOPDF_API_KEY = 'pk_your_api_key_here';
const TEMPLATE_ID = 'clx1234567890';

// Get the record ID from the trigger
let inputConfig = input.config();
let recordId = inputConfig.recordId;

// Generate PDF
let response = await fetch('https://datatopdf.app/api/v1/pdf/generate', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json',
        'X-API-Key': DATATOPDF_API_KEY
    },
    body: JSON.stringify({
        templateId: TEMPLATE_ID,
        recordId: recordId
    })
});

let result = await response.json();

if (response.ok) {
    console.log('PDF generated successfully!');
    // The PDF is returned as base64 in result.pdf
    output.set('pdfGenerated', true);
    output.set('pdfBase64', result.pdf);
} else {
    console.log('Error:', result.error);
    output.set('pdfGenerated', false);
    output.set('error', result.error);
}

Script Input Configuration

Configure the input variables in the script settings:

Input VariableValue
recordIdRecord ID from trigger

Option 2: Webhook (via Make/Zapier)

For more complex workflows, use a webhook integration through Make (Integromat) or Zapier.

Make.com Scenario

  1. Create a new scenario in Make
  2. Add Airtable - Watch Records as the trigger
  3. Add HTTP - Make a request module:
SettingValue
URLhttps://datatopdf.app/api/v1/pdf/generate
MethodPOST
HeadersX-API-Key: pk_your_api_key_here<br>Content-Type: application/json
Body typeRaw
Content typeJSON
Request content{"templateId": "clx1234567890", "recordId": "{{1.id}}"}
  1. Optionally add an Airtable - Update Record module to store the PDF URL or status

Zapier Zap

  1. Create a new Zap
  2. Add Airtable - New or Updated Record as the trigger
  3. Add Webhooks by Zapier - Custom Request:
SettingValue
MethodPOST
URLhttps://datatopdf.app/api/v1/pdf/generate
Data Pass-ThroughFalse
DatatemplateId: clx1234567890<br>recordId: Record ID from step 1
HeadersX-API-Key: pk_your_api_key_here<br>Content-Type: application/json

Automation Use Cases

TriggerTemplateDescription
Record createdWelcome letterAuto-generate welcome document for new clients
Status = "Approved"Contract templateGenerate contract when approval is given
Checkbox checkedInvoice templateCreate invoice when "Ready to Bill" is checked
Date field matches todayReport templateGenerate daily/weekly reports
Form submittedQuote templateCreate quote from form responses

Examples

cURL

curl -X POST https://datatopdf.app/api/v1/pdf/generate \
  -H "Content-Type: application/json" \
  -H "X-API-Key: pk_your_api_key_here" \
  -d '{
    "templateId": "clx1234567890",
    "recordId": "recABC123XYZ"
  }'

JavaScript (Node.js)

const fetch = require('node-fetch');

async function generatePdfFromAirtable(recordId, templateId) {
    const apiKey = process.env.DATATOPDF_API_KEY;

    const response = await fetch('https://datatopdf.app/api/v1/pdf/generate', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'X-API-Key': apiKey
        },
        body: JSON.stringify({
            templateId: templateId,
            recordId: recordId
        })
    });

    const data = await response.json();

    if (!response.ok) {
        throw new Error(`${data.code}: ${data.error}`);
    }

    return Buffer.from(data.pdf, 'base64');
}

// Example usage
generatePdfFromAirtable('recABC123XYZ', 'clx1234567890')
    .then(pdfBuffer => {
        console.log('PDF generated, size:', pdfBuffer.length, 'bytes');
    })
    .catch(error => {
        console.error('Error:', error.message);
    });

Python

import requests
import base64
import os

def generate_pdf_from_airtable(record_id: str, template_id: str) -> bytes:
    api_key = os.environ.get('DATATOPDF_API_KEY')

    response = requests.post(
        'https://datatopdf.app/api/v1/pdf/generate',
        headers={
            'Content-Type': 'application/json',
            'X-API-Key': api_key
        },
        json={
            'templateId': template_id,
            'recordId': record_id
        },
        timeout=30
    )

    data = response.json()

    if not response.ok:
        raise Exception(f"{data.get('code')}: {data.get('error')}")

    return base64.b64decode(data['pdf'])

# Example usage
try:
    pdf_bytes = generate_pdf_from_airtable('recABC123XYZ', 'clx1234567890')
    print(f'PDF generated, size: {len(pdf_bytes)} bytes')

    # Save to file
    with open('output.pdf', 'wb') as f:
        f.write(pdf_bytes)
except Exception as e:
    print(f'Error: {e}')

Airtable Scripting Extension

Use this in the Scripting extension to generate PDFs on-demand:

// Get the current record
let table = base.getTable('Your Table Name');
let record = await input.recordAsync('Select a record', table);

if (!record) {
    console.log('No record selected');
    return;
}

// Configuration
const DATATOPDF_API_KEY = 'pk_your_api_key_here';
const TEMPLATE_ID = 'clx1234567890';

// Generate PDF
console.log('Generating PDF...');

let response = await fetch('https://datatopdf.app/api/v1/pdf/generate', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json',
        'X-API-Key': DATATOPDF_API_KEY
    },
    body: JSON.stringify({
        templateId: TEMPLATE_ID,
        recordId: record.id
    })
});

let result = await response.json();

if (response.ok) {
    console.log('PDF generated successfully!');
    console.log('Content type:', result.contentType);

    // You can now use result.pdf (base64) to:
    // - Download the PDF
    // - Send via email
    // - Store in another service
} else {
    console.error('Error generating PDF:', result.error);
}

Working with Airtable Data

Supported Field Types

All Airtable field types are supported for merge fields:

Field TypeMerge Field Output
Single line textText value
Long textFull text with line breaks
NumberNumeric value
CurrencyFormatted currency
PercentPercentage value
DateISO date string
Checkboxtrue or false
Single selectSelected option text
Multiple selectComma-separated options
EmailEmail address
PhonePhone number
URLWeb URL
AttachmentFirst attachment URL
Link to another recordLinked record names
FormulaCalculated result
LookupLooked up values
RollupAggregated value

Linked Records

When your template includes linked record fields, the primary field value(s) of the linked records are returned:

{{Linked Projects}}     → "Project Alpha, Project Beta"
{{Primary Contact}}     → "John Smith"

Attachments

For attachment fields, the first attachment's URL is available:

{{Logo}}                → URL to the attachment file

Response Format

Success (200)

{
  "pdf": "base64-encoded-pdf-data",
  "contentType": "application/pdf"
}

Error Response

{
  "error": "Human-readable error message",
  "code": "ERROR_CODE"
}

Error Codes

CodeDescription
UNAUTHORIZEDMissing API key
INVALID_API_KEYInvalid or revoked API key
RATE_LIMIT_EXCEEDEDToo many requests (30/minute limit)
SUBSCRIPTION_REQUIREDActive subscription required
PLAN_UPGRADE_REQUIREDAPI access requires Starter plan or higher
GENERATION_LIMIT_EXCEEDEDMonthly PDF limit reached
TEMPLATE_NOT_FOUNDTemplate not found
CONNECTION_NOT_FOUNDAirtable connection not configured
DATA_FETCH_ERRORFailed to fetch Airtable data
INVALID_REQUESTInvalid request body or parameters
GENERATION_FAILEDPDF generation failed

Rate Limits

  • DataToPDF API: 30 requests per minute per API key
  • Airtable API: 5 requests per second per base
  • Monthly generation limits based on your subscription plan

Best Practices

  1. Store API keys securely - Use environment variables or Airtable's scripting secrets
  2. Handle rate limits - Implement retry logic with exponential backoff
  3. Validate record IDs - Ensure the record ID exists before making API calls
  4. Use automations wisely - Avoid triggering on every field change to prevent excessive API calls
  5. Test with specific bases - During development, limit token access to test bases only