Drive2pdf API

Generate high-quality PDF documents from Google Docs and Sheets templates with advanced data insertion, conditional sections, repeating tables, and dynamic images.

Key Features

  • Document Templates — Use Google Docs with placeholders for text, images, conditional sections, and repeating tables.
  • Sheet Templates — Use Google Sheets with dynamic cell data, row/column visibility control, and multi-tab export.
  • Rich Content — Support for styled text, hyperlinks, and dynamic images.
  • PDF Customization — Add watermarks, metadata, and control page size/orientation.
  • Secure Storage — Generated PDFs are stored securely and accessible via unique URLs for 24 hours (1-day TTL).

Authentication

All API requests require authentication using your API key. Include the key in the request header:

Header Value Required
api_key Your API key Required
Content-Type application/json Required

Getting Your API Key

Your API key is available in your Drive2pdf dashboard. Keep it secure and never expose it in client-side code.

Base URL

All API requests should be made to:

https://api.drive2pdf.com

Deploying Templates

Before using a template with the API, it must be deployed. Deployment creates a cached mirror of your Google Drive file tailored for high-performance API generation.

Important

Anytime you modify the structure, named ranges, or layout of your source Google Doc or Sheet, you must redeploy the template to update the cache.

How to Deploy

  1. Go to the Drive2pdf Admin Dashboard.
  2. Select an existing template, or;
  3. Click "New Template" to create a template, a Google File Picker will open where you can select your file from your Google Drive.
  4. On the templates list, click the Deploy button.
Template Deployment UI

The deployment interface allows you to sync your Drive files with the API.

Document Template Language

Drive2pdf uses a powerful template language for Google Docs that allows you to define dynamic content using placeholders, conditional sections, and repeating tables.

Page Setup

Page orientation, size, and margins are configured directly in your Google Doc template via File → Page setup. The PDF will use these settings automatically.

Text Placeholders

Text placeholders are defined using double curly braces: {{placeholder_name}}. These are replaced with the corresponding values from your API request.

Template Example

Dear {{customer_name}},

Thank you for your purchase on {{date}}. Your order #{{order_id}} has been confirmed.

API Data

{
  "data": [
    { "key": "customer_name", "value": "John Doe", "type": "text" },
    { "key": "date", "value": "January 22, 2026", "type": "text" },
    { "key": "order_id", "value": "ORD-12345", "type": "text" }
  ]
}

Key Matching

Keys are case-insensitive. {{Customer_Name}} and {{customer_name}} will both match the key "customer_name".

Multiple Data Types Example

You can mix text and number types in the same request:

{
  "data": [
    { "key": "customer_name", "value": "John Doe", "type": "text" },
    { "key": "order_total", "value": 299.99, "type": "number" },
    { "key": "order_date", "value": "January 22, 2026", "type": "text" },
    { "key": "order_id", "value": "ORD-2026-0001", "type": "text" },
    { "key": "quantity", "value": 5, "type": "number" }
  ]
}

Multi-line Text

Use \n for line breaks within a placeholder:

{
  "key": "address",
  "value": "123 Main Street\nSuite 456\nSan Francisco, CA 94105",
  "type": "text"
}

Conditional Sections

Conditional sections allow you to show or hide entire blocks of content based on a boolean value. Define sections with opening and closing tags:

Template Syntax

{{disclaimer}}
This section will only appear if the "disclaimer" key has show: true.
{{/disclaimer}}

API Data (Hide Section)

{
  "data": [
    { "key": "disclaimer", "show": false, "type": "section" }
  ]
}

If the section key is not provided in the data, the section content will be kept (shown) by default.

Multiple Conditional Sections Example

You can control multiple sections in a single request:

Template
Invoice #{{invoice_number}}

{{has_discount}}
DISCOUNT APPLIED: {{discount_amount}} off your order!
{{/has_discount}}

Total: {{total}}

{{show_bank_details}}
Bank Details:
Account: 1234567890
Routing: 987654321
{{/show_bank_details}}

{{is_overdue}}
⚠️ PAYMENT OVERDUE - Please pay immediately to avoid service interruption.
{{/is_overdue}}
API Data
{
  "data": [
    { "key": "invoice_number", "value": "INV-2026-0042", "type": "text" },
    { "key": "discount_amount", "value": "$50.00", "type": "text" },
    { "key": "total", "value": "$450.00", "type": "text" },
    { "key": "has_discount", "show": true, "type": "section" },
    { "key": "show_bank_details", "show": true, "type": "section" },
    { "key": "is_overdue", "show": false, "type": "section" }
  ]
}

Repeating Tables

Repeating tables allow you to dynamically generate rows based on an array of data. Only the rows containing placeholders with dotted field notation (e.g., {{member.name}}) will be repeated for each item in the array.

Template Structure

Create a normal table in Google Docs. Add a row containing placeholders with dotted notation (e.g., {{member.name}}) to define the repeating fields. The API will automatically detect the repeating rows and the table key (member).

Name Role Age
{{member.name}} {{member.role}} {{member.age}}

API Data

{
  "data": [
    {
      "key": "member",
      "type": "table",
      "value": [
        { "name": "Sarah Mitchell", "role": "CEO", "age": "34" },
        { "name": "James Chen", "role": "CTO", "age": "29" },
        { "name": "Emily Rodriguez", "role": "Designer", "age": "31" }
      ]
    }
  ]
}

Invoice Line Items Example

A common use case is generating invoice line items:

Template Table
Description Qty Rate Amount
{{item.description}} {{item.qty}} {{item.rate}} {{item.amount}}
API Data
{
  "key": "item",
  "type": "table",
  "value": [
    { "description": "Web Development", "qty": "40 hrs", "rate": "$150.00", "amount": "$6,000.00" },
    { "description": "UI/UX Design", "qty": "20 hrs", "rate": "$125.00", "amount": "$2,500.00" },
    { "description": "Project Management", "qty": "10 hrs", "rate": "$100.00", "amount": "$1,000.00" }
  ]
}

Advanced Table Features

  • Multi-row headers/footers: Rows without dotted field placeholders are preserved as static headers or footers.
  • Row styling: Background colors, text styles, and borders from template rows are preserved in generated rows.
  • Independent placeholders: Regular placeholders (not using dotted notation) work normally and are replaced with their values.

Supported Types in Tables

Inside repeating table rows, the following types are supported:

  • Supported: Text, Image, RichText, and Links work fully inside table cells.
  • Supported: You can use newlines (\n) in text fields to create multi-line cell content.
  • Not Supported: Conditional Sections inside table cells will be ignored.
  • Not Supported: Nested tables (tables inside table cells) will not be repeated.

Important: Single Object per Table

Do not mix different objects in the same table row (e.g., {{member.name}} and {{product.price}}). The API uses the first detected object key to identify the table. Mixing keys will cause unexpected behavior.

Note on Custom Borders

Custom table borders and borders in merged cells may not be perfectly replicated in generated rows. This is due to a limitation in the Google Docs API, which doesn't always return border styles exactly as they appear in the editor.

Tip: For best results with repeating tables, use simple border styles (uniform borders on all sides) rather than custom per-cell borders. Standard table formatting will be preserved correctly.

Images

To replace images in your template, insert a placeholder image in Google Docs and set its Alt Text title to the key name. The API will replace it with the image from the provided URL.

Setup Steps

  1. Insert a placeholder image in your Google Doc
  2. Right-click the image → Alt Text
  3. Set the Title to your key (e.g., logo)

Image placeholder example showing Alt Text menu

API Data

{
  "data": [
    {
      "key": "logo",
      "value": "https://example.com/logo.png",
      "type": "image"
    }
  ]
}

Advanced: Image with Link

{
  "key": "logo",
  "value": "https://example.com/logo.png",
  "link": "https://example.com",
  "type": "image"
}

Images in Tables

For images inside repeating tables, use the dotted notation for the Alt Text title:

// Alt Text title: member.photo

"value": [
  { "photo": "https://example.com/sarah.jpg", "name": "Sarah" },
  { "photo": "https://example.com/james.jpg", "name": "James" }
]

Image URL Requirements

Image URLs must be publicly accessible without authentication. The API fetches images directly from these URLs during PDF generation. Private URLs, URLs requiring login, or URLs with short expiration times will fail.

Tip: Images as Buttons

Images with links can be used as clickable buttons in your PDF! Add the link property to make the image clickable.

Multiple Images Example

{
  "data": [
    { "key": "company_logo", "value": "https://example.com/logo.png", "type": "image" },
    { "key": "product_photo", "value": "https://example.com/product.jpg", "type": "image" },
    {
      "key": "cta_button",
      "value": "https://example.com/button.png",
      "link": "https://example.com/signup",
      "type": "image"
    }
  ]
}

Rich Text

Rich text allows you to insert styled text with bold, italic, colors, and more. Use the richtext type with an array of text segments.

Basic Example

{
  "key": "features",
  "type": "richtext",
  "value": [
    { "text": "Doc to PDF", "bold": true },
    { "text": ": Generate PDFs from Google Docs\n" },
    { "text": "Sheet to PDF", "bold": true, "color": "#6366f1" },
    { "text": ": Generate PDFs from Google Sheets" }
  ]
}

Multi-line Styled Text Example

{
  "key": "product_description",
  "type": "richtext",
  "value": [
    { "text": "Premium Quality\n", "bold": true, "size": 14, "color": "#1a1a1a" },
    { "text": "Our flagship product features:\n", "italic": true },
    { "text": "• ", "bold": true },
    { "text": "Advanced technology\n" },
    { "text": "• ", "bold": true },
    { "text": "Eco-friendly materials\n" },
    { "text": "• ", "bold": true },
    { "text": "5-year warranty" }
  ]
}

Status with Highlights Example

{
  "key": "status_message",
  "type": "richtext",
  "value": [
    { "text": "Status: " },
    { "text": "APPROVED", "bold": true, "color": "#22c55e", "highlight": "#dcfce7" },
    { "text": " - Your application has been ", "color": "#64748b" },
    { "text": "successfully processed", "underline": true }
  ]
}

Richtext with Clickable Links

Use the url property to make text segments clickable:

{
  "key": "contact_info",
  "type": "richtext",
  "value": [
    { "text": "Questions? Contact us at " },
    { "text": "[email protected]", "url": "mailto:[email protected]", "color": "#2563eb", "underline": true },
    { "text": " or visit our " },
    { "text": "Help Center", "url": "https://help.example.com", "color": "#2563eb", "underline": true },
    { "text": "." }
  ]
}

Available Style Properties

Property Type Description
text string The text content
bold boolean Bold text
italic boolean Italic text
underline boolean Underlined text
strikethrough boolean Strikethrough text
color string Text color (hex, e.g., #FF0000)
highlight string Background color (hex)
size number Font size in points
url string Make text a hyperlink

Rich Text in Tables

You can use rich text inside repeating tables for dynamic styled content. Instead of a plain string value, provide an array of styled text segments for the field.

Template Setup

Create a table with placeholders like {{project.status}} and {{project.notes}}:

Project Status Notes
{{project.name}} {{project.status}} {{project.notes}}

API Data with Rich Text in Table

{
  "key": "project",
  "type": "table",
  "value": [
    {
      "name": "Project Alpha",
      "status": [
        { "text": "On Track", "bold": true, "color": "#22c55e" }
      ],
      "notes": [
        { "text": "Milestone 1: ", "bold": true },
        { "text": "Completed\n", "color": "#22c55e" },
        { "text": "Milestone 2: ", "bold": true },
        { "text": "In Progress", "color": "#f59e0b" }
      ]
    },
    {
      "name": "Project Beta",
      "status": [
        { "text": "Delayed", "bold": true, "color": "#ef4444" }
      ],
      "notes": [
        { "text": "Blocked by: ", "bold": true },
        { "text": "Resource constraints\n", "color": "#ef4444" },
        { "text": "ETA: ", "bold": true },
        { "text": "Feb 15, 2026" }
      ]
    }
  ]
}

Mixing Plain Text and Rich Text

In the same table row, you can mix plain string values (like "name") with rich text arrays (like "status" and "notes"). The API detects the type automatically.

Google Sheets Templates

Different from Docs

Unlike Google Docs templates (which use placeholders like {{name}}), Sheets templates use Cell Coordinates, Named Ranges, and Structural Commands (Insert/Remove/Hide) to modify the spreadsheet before exporting.

Key Concepts

  • Targeting: Insert data into specific cells or Named Ranges.
  • Structure: Dynamically insert, remove, or hide rows/columns.
  • GID (Sheet ID): Every tab has a unique ID found in the URL (#gid=123). You must specify which GID you are modifying or exporting.

Order of Operations & Index Management

Operations are processed in the exact order you provide them in the operations array. This gives you complete flexibility to interleave data insertion, visibility changes, row/column insertions, and removals.

Important: You are responsible for managing row/column index shifts when inserting or removing rows/columns. The API executes operations sequentially without adjusting subsequent indices. This design allows you to create complex, precisely-ordered operations tailored to your needs.

Recommendation: When performing multiple insert or remove operations, work from bottom to top (highest row/column numbers first). This prevents earlier operations from shifting the indices of later operations, making your code more predictable and easier to maintain.

Example: If you insert 5 rows at row 10, any subsequent operations targeting rows after row 10 must account for the shift (e.g., what was row 15 is now row 20).

1. Data Insertion

Use data operations in the operations array to insert values into the sheet. You can target specific cells or Named Ranges.

Basic Example

JSON Payload
{
  "operations": [
    {
      "type": "data",
      "target": "invoice_items",
      "repeat": true,
      "content": [
        ["Item A", 150.00],
        ["Item B", 299.99]
      ]
    },
    {
      "type": "data",
      "target": "B2",
      "content": [["2025-10-10"]]
    }
  ]
}

Comprehensive Invoice Example

{
  "operations": [
    { "type": "data", "target": "B2", "content": [["Invoice #INV-2026-001"]] },
    { "type": "data", "target": "B3", "content": [["January 22, 2026"]] },
    { "type": "data", "target": "E2", "content": [["$9,500.00"]] },
    {
      "type": "data",
      "target": "invoice_items",
      "repeat": true,
      "content": [
        ["Web Development Services", 40, 150.00, 6000.00],
        ["UI/UX Design", 20, 125.00, 2500.00],
        ["Hosting (Annual)", 1, 1000.00, 1000.00]
      ]
    }
  ]
}
Field Type Description
type string Must be "data"
target string Named Range (Recommended): e.g., "my_range"
A1 Notation: e.g., "B2" or "C10" (use gid to specify the sheet)
content array 2D array of values to insert.
repeat boolean (Requires Named Range). If true, the rows spanned by the Named Range will be duplicated for each additional item in content, pushing existing content down. Ideal for dynamic lists.
gid number Sheet tab ID (optional if using Named Range).

Important: Row Styles & Heights

To preserve custom row heights (e.g., small spacer rows) or alternating styles in a list, you MUST use Named Ranges with repeat: true. Inserting data into plain cells will not replicate the row's height metadata.

2. Row/Column Visibility

Control the visibility of rows and columns dynamically. This is useful for hiding empty rows or conditional content.

{
  "operations": [
    {
      "type": "visibility",
      "dimension": "row",
      "start": 10,
      "quantity": 5,
      "hide": true,
      "gid": 0
    },
    {
      "type": "visibility",
      "dimension": "column",
      "start": 4,
      "end": 6,
      "hide": true
    }
  ]
}
Field Type Description
type string Must be "visibility"
dimension string "row", "rows", "column", or "columns"
start number Starting index (1-based)
end number Ending index (1-based, alternative to quantity)
quantity number Number of rows/columns (alternative to end)
hide boolean true to hide, false to show
gid number Sheet tab ID (default: 0)

Multiple Visibility Operations Example

{
  "operations": [
    { "type": "visibility", "dimension": "row", "start": 50, "end": 100, "hide": true, "gid": 0 },
    { "type": "visibility", "dimension": "column", "start": 8, "quantity": 3, "hide": true, "gid": 0 },
    { "type": "visibility", "dimension": "row", "start": 5, "quantity": 1, "hide": false, "gid": 123456 }
  ]
}

Use Cases

Common visibility use cases include: hiding unused template rows, removing draft columns before export, and conditionally showing/hiding sections based on data availability.

3. Insert & Remove

Dynamically insert or remove rows and columns using operations.

{
  "operations": [
    {
      "type": "insert",
      "dimension": "row",
      "start": 20,
      "quantity": 2,
      "inherit_from": "after"
    },
    {
      "type": "remove",
      "dimension": "col",
      "start": 5
    }
  ]
}

Insert Operation Fields

Field Type Description
type string Must be "insert"
dimension string "row", "rows", "column", or "columns"
start number Starting index (1-based)
quantity number Count (default: 1)
inherit_from string "before" (default), "after", or "none". Controls which row to copy from. Use "none" to insert blank rows.
gid number Sheet tab ID (default: 0)

Remove Operation Fields

Field Type Description
type string Must be "remove"
dimension string "row", "rows", "column", or "columns"
start number Starting index (1-based)
quantity number Count (default: 1)
gid number Sheet tab ID (default: 0)

Full Row Inheritance

When inherit_from is set to "before" or "after", the new rows inherit everything from the source row: values, formulas, formatting, cell merges, and text wrap settings. Cell references in formulas are automatically adjusted (e.g., =B10*2 becomes =B11*2, =B12*2, etc.).

4. Export Options

Control how the sheet is exported to PDF, including page size, orientation, margins, and which tabs to include.

Field Type Default Description
gid number | array 0 Tab(s) to export
name string | array Auto Output filename(s)
size string "A4" Page size. Options: A3, A4, A5, B4, B5, Letter, Legal, Tabloid
portrait boolean true Portrait orientation
margins string "0" Margins in inches. Single value for all sides (e.g., "0.5") or four values for top,right,bottom,left (e.g., "0.5,0.25,0.5,0.25")
merge boolean true Merge multiple tabs into one PDF

API Reference

/v1/pdf Endpoint

POST /v1/pdf

Generate a PDF from a template. The template type (Doc or Sheet) is determined automatically based on the template configuration.

Common Parameters

These parameters apply to both Document and Sheet templates:

Field Type Required Description
template_id string Required Your template ID (from your Drive2pdf dashboard, not the Google Drive file ID)
watermark_image_url string Optional Watermark image URL
watermark_opacity number Optional Watermark opacity (0.0 to 1.0)
metadata object Optional PDF metadata object (see fields below)
base64 boolean Optional Include base64-encoded PDF in response

Metadata Object Fields

Field Type Description
title string PDF title
author string PDF author
subject string PDF subject
keywords string | array Keywords (comma-separated string or array)
producer string PDF producer (default: "drive2pdf.com")
creator string PDF creator (default: "drive2pdf.com")
creation_date string Creation date (ISO 8601 format)
modification_date string Modification date (ISO 8601 format)

Document Parameters

Additional parameters for Document (Google Docs) templates:

Field Type Description
data array Array of replacement objects (see Template Language)
name string Output filename (default: "document.pdf")

Data Object Types

Type Required Fields Optional Fields
text key, value
number key, value
image key, value (URL) link
richtext key, value (array)
link key, value (URL) caption, color, underline
section key show (boolean)
table key, value (array of objects)

Sheet Parameters

Additional parameters for Sheet (Google Sheets) templates:

Field Type Description
operations array Array of operation objects with type field: "data", "visibility", "insert", or "remove" (see sections below)
gid number | array Sheet tab ID(s) to export (default: 0)
name string | array Output filename(s)
size string Page size. Options: A3, A4, A5, B4, B5, Letter, Legal, Tabloid (default: "A4")
portrait boolean Portrait orientation (default: true)
margins string Margins in inches. Single value (e.g., "0.5") or top,right,bottom,left (e.g., "0.5,0.25,0.5,0.25"). Default: "0"
merge boolean Merge tabs into one PDF (default: true)

Response

Success Response (200)

{
  "urls": ["https://pdf.drive2pdf.com/pdfs/.../document.pdf"]
}

With base64: true

{
  "urls": ["https://pdf.drive2pdf.com/pdfs/.../document.pdf"],
  "base64": ["JVBERi0xLjQKJ..."]
}

Response Headers

Header Description
X-Request-Id Unique request identifier. Include this ID when contacting support to help diagnose issues.
X-Documents-Limit Your remaining document quota
X-RateLimit-Quota Max requests per minute allowed
X-RateLimit-Remaining Requests remaining in current window
X-RateLimit-Reset Timestamp (ms) when rate limit resets

Limits

Drive2pdf enforces timeout and rate limits to ensure reliable service. Limits vary by plan—check the pricing page for your plan's specific limits.

Request Timeout

API requests have a maximum timeout of 60 seconds. If PDF generation exceeds your plan's timeout limit, the API returns a 408 REQUEST_TIMEOUT error.

Plan-Based Timeout Limits

The 60-second timeout is the maximum available on higher-tier plans. Your plan may have a shorter timeout limit. Check the pricing page to see the timeout limit included in your plan.

Handling Timeouts

Complex templates with many images or large tables may take longer to process. If you frequently encounter timeouts, consider simplifying your template or reducing the amount of dynamic data.

Rate Limits

The API enforces two types of rate limits to ensure fair usage and system stability:

Limit Type Description Error Code
Concurrent Requests Maximum number of requests that can be processed simultaneously. Additional requests will be rejected until an in-progress request completes. RATE_LIMIT_CONCURRENT_EXCEEDED
Requests Per Minute Maximum number of requests allowed within a 60-second rolling window. The window resets continuously, not at fixed intervals. RATE_LIMIT_PER_MINUTE_EXCEEDED

Plan-Based Rate Limits

Rate limits vary by plan. Check the pricing page for the specific limits included in your plan.

Monitoring Your Limits

Use the response headers X-RateLimit-Quota, X-RateLimit-Remaining, and X-RateLimit-Reset to monitor your current rate limit status and avoid hitting limits.

Exponential Backoff

We recommend that you use exponential backoff when you receive a 429 rate limit error: wait 1 second before retrying, then double the wait time (2s, 4s, 8s...) for each subsequent failure. This prevents excessive retry attempts and allows your quota to recover.

Error Responses

All errors return a JSON object with code and message:

{
  "code": "ERROR_CODE",
  "message": "Human-readable description"
}
Status Code Description
400 INVALID_REQUEST_PAYLOAD Invalid or malformed request data
400 TEMPLATE_NOT_DEPLOYED Template has not been deployed
401 API_KEY_INVALID Invalid or missing API key
401 NO_REFRESH_TOKEN Google account not connected. Connect your account in the dashboard.
401 TOKEN_REFRESH_FAILED OAuth token refresh failed. Re-authenticate in the dashboard.
402 QUOTA_EXCEEDED Document quota exhausted
402 SUBSCRIPTION_EXPIRED Subscription cycle has ended. Please renew to continue.
408 REQUEST_TIMEOUT Processing exceeded time limit
429 RATE_LIMIT_CONCURRENT_EXCEEDED Too many concurrent requests
429 RATE_LIMIT_PER_MINUTE_EXCEEDED Too many requests per minute
500 INTERNAL_SERVER_ERROR Unexpected server error
503 SERVICE_CAPACITY_EXCEEDED Service at capacity, retry later

Examples

Document with Text and Image

cURL
curl -X POST https://api.drive2pdf.com/v1/pdf \
  -H "api_key: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "template_id": "tpl-123",
    "data": [
      { "key": "name", "value": "John Doe", "type": "text" },
      { "key": "date", "value": "January 22, 2026", "type": "text" },
      { "key": "signature", "value": "https://example.com/sig.png", "type": "image" }
    ],
    "name": "certificate",
    "watermark": true,
    "metadata": {
      "title": "Certificate of Completion",
      "author": "Acme University"
    }
  }'

Sheet with Multiple Tabs

cURL
curl -X POST https://api.drive2pdf.com/v1/pdf \
  -H "api_key: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "template_id": "tpl-456",
    "operations": [
      { "type": "data", "target": "B2", "content": [["Monthly Report"]] },
      { "type": "insert", "dimension": "row", "start": 10, "quantity": 2, "gid": 0 },
      { "type": "data", "target": "invoice_items", "repeat": true, "content": [["Item A", 100], ["Item B", 200]] },
      { "type": "visibility", "dimension": "row", "start": 15, "quantity": 5, "hide": true, "gid": 0 }
    ],
    "gid": [0, 58736200],
    "name": ["summary", "details"],
    "merge": true
  }'

Document with Repeating Table

cURL
curl -X POST https://api.drive2pdf.com/v1/pdf \
  -H "api_key: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "template_id": "tpl-789",
    "data": [
      { "key": "company_name", "value": "Acme Corp", "type": "text" },
      { "key": "report_date", "value": "Q4 2025", "type": "text" },
      {
        "key": "employee",
        "type": "table",
        "value": [
          { "name": "Alice Johnson", "department": "Engineering", "salary": "$95,000" },
          { "name": "Bob Smith", "department": "Marketing", "salary": "$78,000" },
          { "name": "Carol White", "department": "Sales", "salary": "$82,000" }
        ]
      },
      { "key": "total_employees", "value": "3", "type": "text" }
    ],
    "name": "employee_report"
  }'

Document with Rich Text

Generate a document with styled text, highlights, and clickable links:

cURL
curl -X POST https://api.drive2pdf.com/v1/pdf \
  -H "api_key: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "template_id": "tpl-offer-letter",
    "data": [
      { "key": "recipient_name", "value": "Sarah Johnson", "type": "text" },
      { "key": "date", "value": "January 22, 2026", "type": "text" },
      {
        "key": "message_body",
        "type": "richtext",
        "value": [
          { "text": "Dear Sarah,\n\n", "bold": true },
          { "text": "We are pleased to inform you that your application for the " },
          { "text": "Senior Developer", "bold": true, "color": "#2563eb" },
          { "text": " position has been " },
          { "text": "approved", "bold": true, "color": "#22c55e", "highlight": "#dcfce7" },
          { "text": ".\n\nPlease visit our " },
          { "text": "onboarding portal", "url": "https://example.com/onboard", "color": "#2563eb", "underline": true },
          { "text": " to complete the next steps.\n\nBest regards,\nHR Team" }
        ]
      }
    ],
    "name": "offer_letter"
  }'

Document with Conditional Sections

Dynamically show or hide sections based on your data:

cURL
curl -X POST https://api.drive2pdf.com/v1/pdf \
  -H "api_key: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "template_id": "tpl-invoice-conditional",
    "data": [
      { "key": "customer_name", "value": "Acme Corporation", "type": "text" },
      { "key": "invoice_number", "value": "INV-2026-0042", "type": "text" },
      { "key": "subtotal", "value": "$8,500.00", "type": "text" },
      { "key": "discount_amount", "value": "$850.00", "type": "text" },
      { "key": "total", "value": "$7,650.00", "type": "text" },
      { "key": "has_discount", "show": true, "type": "section" },
      { "key": "is_overdue", "show": false, "type": "section" },
      { "key": "show_bank_details", "show": true, "type": "section" }
    ],
    "name": "invoice_acme"
  }'

Product Catalog with Images and Rich Text

Generate a product catalog with images and styled descriptions in a repeating table:

cURL
curl -X POST https://api.drive2pdf.com/v1/pdf \
  -H "api_key: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "template_id": "tpl-product-catalog",
    "data": [
      { "key": "catalog_title", "value": "Spring 2026 Collection", "type": "text" },
      {
        "key": "product",
        "type": "table",
        "value": [
          {
            "photo": "https://example.com/products/widget-pro.jpg",
            "name": "Widget Pro",
            "price": "$299.99",
            "description": [
              { "text": "Professional Grade\n", "bold": true, "color": "#1a1a1a" },
              { "text": "• Advanced features\n• 2-year warranty\n• Free shipping", "color": "#64748b" }
            ]
          },
          {
            "photo": "https://example.com/products/widget-lite.jpg",
            "name": "Widget Lite",
            "price": "$149.99",
            "description": [
              { "text": "Best Seller\n", "bold": true, "color": "#f59e0b" },
              { "text": "• Essential features\n• 1-year warranty", "color": "#64748b" }
            ]
          }
        ]
      }
    ],
    "name": "product_catalog"
  }'

Complete Invoice with All Features

A comprehensive example combining text, images, tables, sections, rich text, and links:

cURL
curl -X POST https://api.drive2pdf.com/v1/pdf \
  -H "api_key: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "template_id": "tpl-full-invoice",
    "data": [
      { "key": "company_logo", "value": "https://example.com/logo.png", "type": "image" },
      { "key": "invoice_number", "value": "INV-2026-0099", "type": "text" },
      { "key": "invoice_date", "value": "January 22, 2026", "type": "text" },
      { "key": "due_date", "value": "February 21, 2026", "type": "text" },
      { "key": "client_name", "value": "TechStart Inc.", "type": "text" },
      { "key": "client_address", "value": "123 Innovation Drive\nSan Francisco, CA 94105", "type": "text" },
      {
        "key": "line_item",
        "type": "table",
        "value": [
          { "description": "API Integration Services", "hours": "32", "rate": "$175.00", "total": "$5,600.00" },
          { "description": "Custom Dashboard Development", "hours": "48", "rate": "$175.00", "total": "$8,400.00" },
          { "description": "Training & Documentation", "hours": "8", "rate": "$150.00", "total": "$1,200.00" }
        ]
      },
      { "key": "subtotal", "value": "$15,200.00", "type": "text" },
      { "key": "tax_rate", "value": "8.5%", "type": "text" },
      { "key": "tax_amount", "value": "$1,292.00", "type": "text" },
      { "key": "total_due", "value": "$16,492.00", "type": "text" },
      { "key": "has_notes", "show": true, "type": "section" },
      {
        "key": "notes",
        "type": "richtext",
        "value": [
          { "text": "Payment Terms: ", "bold": true },
          { "text": "Net 30\n" },
          { "text": "Thank you for your business! ", "italic": true, "color": "#64748b" },
          { "text": "Pay online", "url": "https://pay.example.com/inv-0099", "color": "#2563eb", "underline": true }
        ]
      },
      {
        "key": "payment_link",
        "type": "link",
        "value": "https://pay.example.com/inv-0099",
        "caption": "Pay Now - Secure Payment",
        "color": "#22c55e"
      }
    ],
    "name": "invoice_techstart",
    "watermark": false,
    "metadata": {
      "title": "Invoice INV-2026-0099",
      "author": "Your Company Name",
      "subject": "Invoice for TechStart Inc."
    }
  }'

Sheet with All Operations

A comprehensive Sheet example with interleaved operations: data insertion, visibility control, row insertion, and multi-tab export. Notice how operations are ordered to handle index shifts correctly:

cURL
curl -X POST https://api.drive2pdf.com/v1/pdf \
  -H "api_key: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "template_id": "tpl-financial-report",
    "operations": [
      { "type": "data", "target": "report_title", "content": [["Q4 2025 Financial Summary"]] },
      { "type": "data", "target": "report_date", "content": [["Generated: January 22, 2026"]] },
      { "type": "insert", "dimension": "row", "start": 15, "quantity": 10, "inherit_from": "before", "gid": 0 },
      {
        "type": "data",
        "target": "monthly_data",
        "repeat": true,
        "content": [
          ["October 2025", 125000, 98000, 27000],
          ["November 2025", 142000, 105000, 37000],
          ["December 2025", 168000, 112000, 56000]
        ]
      },
      { "type": "visibility", "dimension": "row", "start": 60, "end": 85, "hide": true, "gid": 0 },
      { "type": "visibility", "dimension": "column", "start": 10, "quantity": 5, "hide": true, "gid": 0 }
    ],
    "gid": [0, 987654321],
    "name": ["summary", "detailed_breakdown"],
    "size": "Letter",
    "portrait": false,
    "margins": "0.5,0.75,0.5,0.75",
    "merge": true
  }'