Zapier
Prerequisites
- A PolyDoc account and API key - sign up for free, no credit card required. The free plan includes 150 PDF conversions per month.
- A Zapier account - sign up for free. This guide uses Catch Hook (the inbound webhook trigger) and Code by Zapier, both free. Webhooks by Zapier → POST (the outbound action) is paid and not needed here.
Accept invoice data from any source (a custom form, a third-party app, your own backend) via a Zapier webhook, generate the PDF, and email it.Webhooks by Zapier (Catch Hook) → Code by Zapier (call PolyDoc) → Gmail
1. Add the Catch Hook trigger
Click + Create Zap and set the trigger to Webhooks by Zapier → Catch Hook. Walk through Setup (no fields required) and Configure (leave Pick off a Child Key empty). Zapier generates a unique URL like https://hooks.zapier.com/hooks/catch/<id>/<path>; copy it from the Test step.
2. Send test data to the webhook
Send a sample request to the catch URL so Zapier learns the field shape. From your terminal:
curl -X POST '<your-catch-hook-url>' \
-H 'Content-Type: application/json' \
--data-raw '{
"invoice_number": "INV-2026-001",
"invoice_date": "2026-01-15",
"invoice_due_date": "2026-02-14",
"invoice_subtotal": 1200,
"invoice_tax_rate": 0.1,
"invoice_tax_amount": 120,
"invoice_total": 1320,
"customer_name": "John Doe",
"customer_email": "john.doe@example.com",
"customer_street": "456 Customer Avenue",
"customer_city": "Beautiful City",
"customer_country": "UK",
"items": [
{"quantity":1,"name":"Web Design Services","description":"…","price":800},
{"quantity":1,"name":"Logo Design","description":"…","price":300},
{"quantity":1,"name":"SEO Optimization","description":"…","price":100,"original_price":150}
]
}'
Back in Zapier, click Test trigger. The request is listed as request A with every field ready to bind in downstream steps.
3. Add the PolyDoc HTTP request
Add an action: Code by Zapier → Run JavaScript. This one step reassembles the payload, calls PolyDoc, and returns a file_url for Gmail to attach.
In the Input Data table, map every field from the trigger payload (items comes through as a JSON string, since the Catch Hook doesn't preserve nested arrays). Add three static constants you type directly on this step:
api_key=Bearer YOUR_API_KEY(from the Dashboard; keeping it in Input Data keeps it out of the script body)template_id= your PolyDoc template short ID, e.g.a1b-c2dfrom the Dashboard Templates pagepresigned_url= a PUT-presigned URL on your own bucket (S3, GCS, R2, Azure Blob, …). PolyDoc PUTs the PDF there; Gmail then attaches the resulting object URL. See the Cloud storage guide for how to generate one per provider.
Paste this into the Code editor:
const payload = {
source: `[template:${inputData.template_id}]`,
templateData: {
invoice_number: inputData.invoice_number,
invoice_date: inputData.invoice_date,
invoice_due_date: inputData.invoice_due_date,
invoice_subtotal: Number(inputData.invoice_subtotal),
invoice_tax_rate: Number(inputData.invoice_tax_rate),
invoice_tax_amount: Number(inputData.invoice_tax_amount),
invoice_total: Number(inputData.invoice_total),
customer_name: inputData.customer_name,
customer_email: inputData.customer_email,
customer_street: inputData.customer_street,
customer_city: inputData.customer_city,
customer_country: inputData.customer_country,
items: JSON.parse(inputData.items), // Catch Hook flattens nested JSON to a string in Input Data
},
cloudStorage: { presignedUrl: inputData.presigned_url },
};
const res = await fetch('https://api.polydoc.tech/pdf/convert', {
method: 'POST',
headers: {
'Authorization': inputData.api_key,
'Content-Type': 'application/json',
'X-Sandbox': 'true',
},
body: JSON.stringify(payload),
});
if (!res.ok) {
throw new Error(`PolyDoc ${res.status}: ${await res.text()}`);
}
// PolyDoc PUTs the PDF to your bucket. Strip the presigning query string so
// Gmail attaches the canonical object URL (which must be readable by recipients,
// or you generate a separate GET-presigned URL for sharing).
output = { file_url: inputData.presigned_url.split('?')[0] };
4. Deliver the PDF
Add Gmail → Send Email with these mappings:
To:customer_emailfrom the Catch HookSubject:Invoice <invoice_number from Catch Hook>Attachments: File URL from the Code step
Test the chain end-to-end (resend the curl from Step 2, walk the tester), then click Publish. Any service that POSTs to your catch URL now triggers a PDF email automatically.