Documentation
Everything you need to create documents with AI, build smart templates, automate via the REST API, and deliver at scale with SFTP.
Getting Started
EZdoc templates are just regular Word documents with special placeholders where your data goes. When you upload your spreadsheet, EZdoc replaces each placeholder with the real data.
Create your template
Design your document in Word. Add {{ placeholders }} where data should appear.
Prepare your data
Create a spreadsheet with columns matching your placeholder names. Each row becomes one document.
Generate documents
Upload both files to EZdoc. Download your personalized documents as PDFs instantly.
{{ first_name }} not {{ first name }}
Basic Placeholders
Placeholders are wrapped in double curly braces: {{ name }}. When your document is generated, these are replaced with actual values from your spreadsheet.
In your Word template:
Dear {{ first_name }} {{ last_name }},
Thank you for your order #{{ order_number }}.
Your total is {{ total }}.
Best regards,
{{ company_name }}
Your spreadsheet data:
first_name,last_name,order_number,total,company_name
Sarah,Johnson,ORD-001,149.99,Acme Corp
Mike,Chen,ORD-002,89.50,Acme Corp
Emma,Williams,ORD-003,234.00,Acme Corp
customer_name, order2_total, itemPrice
Show/Hide Content
Sometimes you want to show different content based on conditions. Use {% if %} to show content only when a condition is true.
Show content when something is true:
{% if is_premium %}
Thank you for being a Premium member!
Your exclusive discount: {{ discount }}% off
{% endif %}
The discount message only appears if is_premium is "true" or "yes" in your spreadsheet.
Show different content based on values:
{% if total > 100 %}
Congratulations! You qualify for FREE shipping!
{% else %}
Add {{ 100 - total | round(2) }} more for free shipping.
{% endif %}
Shows free shipping message for orders over $100, otherwise shows how much more is needed.
true, yes, 1, or any non-empty text. Empty cells and no are treated as false.
Repeating Sections
Need to list multiple items? Use {% for item in items %} to repeat a section for each item in a list.
Basic repeating section:
Your Order Items:
{% for item in items %}
• {{ item.name }} (Qty: {{ item.quantity }})
{% endfor %}
Nested loops (lists within lists):
{% for department in departments %}
{{ department.name }}:
{% for employee in department.employees %}
- {{ employee.name }} ({{ employee.role }})
{% endfor %}
{% endfor %}
[{"name": "Widget", "quantity": 2}]
Math & Calculations
Do math directly in your templates. Add, subtract, multiply, divide, and more.
Calculate totals:
Subtotal: {{ subtotal }}
Tax (8%): {{ subtotal * 0.08 }}
Shipping: {{ shipping_cost }}
━━━━━━━━━━━━━━━━━━━━
Total: {{ subtotal + (subtotal * 0.08) + shipping_cost }}
Round numbers:
Original: {{ price }}
Rounded: {{ price | round(2) }}
No decimals: {{ price | round(0) }}
Formatting Data
Use filters to format your data. Add a pipe (|) after the value, then the filter name.
Date formatting
Order placed: {{ order_date | date("F j, Y") }}
Short format: {{ order_date | date("m/d/Y") }}
With time: {{ order_date | date("M j, Y at g:i A") }}
Number formatting
Price: {{ price | number_format(2) }}
With commas: {{ large_number | number_format(0, ".", ",") }}
Text formatting
UPPERCASE: {{ name | upper }}
lowercase: {{ name | lower }}
Title Case: {{ name | title }}
First letter: {{ name | first }}
Default Values
What if a spreadsheet cell is empty? Use the default filter to show a fallback value.
Hello {{ name | default("Valued Customer") }},
Your membership level: {{ tier | default("Standard") }}
{% if name %}Hello {{ name }}{% else %}Hello there{% endif %}
Real-World Examples
Here are complete examples you can copy and adapt for your own templates.
Example: Invoice with line items
INVOICE #{{ invoice_number }}
Items:
{% for item in items %}
{{ item.name }} - {{ item.quantity }} x ${{ item.price }}
{% endfor %}
Subtotal: ${{ subtotal }}
Tax: ${{ tax }}
Total: ${{ total }}
Example: Certificate of completion
CERTIFICATE OF COMPLETION
This certifies that
{{ student_name | upper }}
has successfully completed
{{ course_name }}
on {{ completion_date | date("F j, Y") }}
{% if honors %}
WITH HONORS
{% endif %}
Example: Welcome letter with conditional content
Welcome to {{ company_name }}, {{ first_name }}!
{% if is_first_purchase %}
As a thank you for your first order, here's 10% off your next purchase: WELCOME10
{% endif %}
Your order #{{ order_number }} is confirmed.
{% for item in items %}
• {{ item.name }}
{% endfor %}
{% if delivery_notes %}
Special instructions: {{ delivery_notes }}
{% else %}
No special delivery instructions.
{% endif %}
Ready to create your first template?
Start with a simple document and add features as you need them. You can always come back to this guide.
AI Builder
Describe what you need and get a professional document in 30 seconds. No design skills required.
Three creation modes
- Finished Document — A ready-to-download PDF. Invoices, proposals, certificates, flyers, resumes, and 40+ other types.
- Reusable Template — A template with
{{ placeholders }}that you can use for batch generation. Upload a CSV and generate thousands of personalized PDFs. - Webpage — A responsive HTML page (landing page, portfolio, event page). Download and host anywhere.
CSV-to-Template flow
When creating a Reusable Template, you can upload your CSV file directly. EZdoc extracts the column headers and first row of data, then the AI designs a template specifically around your columns. The preview renders with your actual data so you can see exactly what the output will look like.
Logo support
Paste your logo's SVG markup or provide an image URL in the Logo field. The AI will embed it in the document header. SVG is recommended for crisp rendering at any size.
Print-Friendly mode
Select "Print-Friendly (B&W)" from the Style dropdown to generate documents optimized for black-and-white printing — no colors, no decorative elements, proper page breaks, and generous margins.
See examples: Browse 129 AI-generated documents across 43 types to see the quality before you create.
REST API
Automate document generation from any application. Available on all paid plans.
Authentication
Generate an API key in Settings. Include it as a Bearer token in every request:
Authorization: Bearer ezdoc_sk_your_key_here
Key endpoints
| Endpoint | Description |
|---|---|
| GET /api/v1/account | Your plan, usage, and limits |
| GET /api/v1/templates | List templates with placeholder fields |
| POST /api/v1/merge_jobs | Generate documents (JSON data or CSV upload) |
| GET /api/v1/merge_jobs/:id | Poll for status, get download URL when complete |
| POST /api/v1/sftp_connections | Create an SFTP connection for delivery |
Quick example
curl -X POST https://ezdoc.app/api/v1/merge_jobs \
-H "Authorization: Bearer ezdoc_sk_your_key" \
-H "Content-Type: application/json" \
-d '{
"template_id": 42,
"data": [
{"client_name": "Alice", "amount": "$500"},
{"client_name": "Bob", "amount": "$750"}
]
}'
SFTP Delivery
Automatically upload completed batch documents to your SFTP server. Available on Growth ($49/mo) and Scale ($99/mo) plans.
Setup
- 1. Create a connection — Go to Settings → SFTP Connections. Add your server hostname, port, username, and SSH key or password. Set the remote path where files should land.
- 2. Test and verify — Click "Test" to perform an SSH handshake. A green checkmark means the connection is verified and ready. Connections must be verified before use.
- 3. Enable on batch generation — On the Generate page (step 3), toggle "SFTP Delivery" and select your verified connection. The ZIP file uploads automatically when processing completes.
- 4. Check delivery status — The merge job detail page shows delivery status: Pending → Delivering → Delivered (or Failed with error message).
Security
- Credentials encrypted at rest with AES-256-GCM
- Private keys and passwords are never returned in API responses
- Changing host, username, or credentials resets verification
- Files named
ezdoc_{template}_{job_id}.zip
Bulk Generate
Generate hundreds or thousands of personalized documents from a single template and a spreadsheet.
Three data input methods
- CSV/XLSX upload — Upload a spreadsheet where each row becomes one document. Column headers must match template placeholders.
- JSON paste — Paste a JSON array of objects. Each object becomes one document. Useful for API-generated data.
- Manual entry — Fill in fields one at a time for a single document.
Special CSV columns
_email_to— Email each PDF directly to the recipient at this address_email_subject— Custom subject line for the email_email_body— Custom body text for the email_template— In multi-template mode, specifies which template to use per row
Line items (arrays in CSV)
For documents with variable-length tables (like invoice line items), store JSON arrays in a CSV cell:
client_name,line_items,total
"Alice","[{""desc"":""Widget"",""qty"":""2""},{""desc"":""Gadget"",""qty"":""1""}]","$150"
EZdoc automatically parses JSON arrays in CSV cells and expands them in
{% for item in line_items %} loops.