Finance
Quote & estimate PDF generator
A polished price estimate with line items and validity window to win the deal before invoicing.
Send prospects a polished price estimate without building PDFs by hand. Provide the services, quantities, prices and a validity window, and PDFgen renders a clean quote PDF you can email or surface in your CRM.
When the deal closes, reuse the same data to generate the matching invoice — one template pipeline for your whole quote-to-cash flow.
Generate a Quote / Estimate PDF via the API
POST your data to /api/v1/generate and get a PDF back. Copy-paste an example, swap in your API key, and loop over a list to render thousands — one quote / estimate per record.
curl -X POST https://pdfgen.com/api/v1/generate \-H "Authorization: Bearer pdfg_live_xxx" \-H "Content-Type: application/json" \-d '{"html": "<div style=\"max-width:760px;margin:0 auto;padding:48px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica,Arial,sans-serif;color:#111827;\">\n <div style=\"display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:36px;\">\n <h1 style=\"font-size:24px;font-weight:800;margin:0;\">{{company.name}}</h1>\n <div style=\"text-align:right;\">\n <h2 style=\"font-size:28px;letter-spacing:2px;color:#0f766e;margin:0;font-weight:800;\">QUOTE</h2>\n <p style=\"margin:6px 0 0;color:#6b7280;font-size:13px;\">#{{quoteNumber}} · valid until {{formatDate validUntil}}</p>\n </div>\n </div>\n <p style=\"font-size:11px;text-transform:uppercase;letter-spacing:1px;color:#9ca3af;margin:0 0 6px;\">Prepared for</p>\n <p style=\"margin:0 0 28px;font-weight:600;\">{{client.name}}</p>\n <table style=\"width:100%;border-collapse:collapse;font-size:14px;\">\n <thead>\n <tr style=\"background:#f0fdfa;text-align:left;\">\n <th style=\"padding:12px;border-bottom:1px solid #ccfbf1;\">Service</th>\n <th style=\"padding:12px;border-bottom:1px solid #ccfbf1;text-align:center;\">Qty</th>\n <th style=\"padding:12px;border-bottom:1px solid #ccfbf1;text-align:right;\">Price</th>\n </tr>\n </thead>\n <tbody>\n {{#each items}}\n <tr>\n <td style=\"padding:12px;border-bottom:1px solid #f3f4f6;\">{{description}}</td>\n <td style=\"padding:12px;border-bottom:1px solid #f3f4f6;text-align:center;\">{{quantity}}</td>\n <td style=\"padding:12px;border-bottom:1px solid #f3f4f6;text-align:right;\">{{formatCurrency amount ../currency}}</td>\n </tr>\n {{/each}}\n </tbody>\n </table>\n <div style=\"display:flex;justify-content:flex-end;margin-top:20px;\">\n <div style=\"background:#0f766e;color:#fff;padding:14px 24px;border-radius:8px;font-size:16px;font-weight:800;\">\n Estimated total: {{formatCurrency total currency}}\n </div>\n </div>\n <p style=\"margin-top:40px;font-size:12px;color:#9ca3af;\">{{notes}}</p>\n</div>","engine": "handlebars","format": "A4","data": {"company": {"name": "Beacon Consulting"},"client": {"name": "Riverside Retail Group"},"quoteNumber": "Q-3391","validUntil": "2026-07-31","currency": "USD","items": [{"description": "Discovery workshop","quantity": 1,"amount": 2500},{"description": "Implementation (per month)","quantity": 3,"amount": 4000},{"description": "Training & handover","quantity": 1,"amount": 1500}],"total": 16000,"notes": "This estimate is non-binding and excludes applicable taxes."}}' --output quote.pdf
Working in another language? Follow a full guide for your stack:
What you can build
- Generating quotes straight from your CRM or sales tool
- Letting prospects download an estimate from a pricing page
- Producing consistent estimates across a sales team
- Converting an accepted quote into an invoice automatically
Frequently asked questions
- Can I set an expiry / valid-until date on the quote?
- Yes — pass a validUntil date in your data and it renders in the quote header. Update the wording in the template if you need different terms.
- How do I turn an accepted quote into an invoice?
- Reuse the same line-item data against the invoice template. Because both are Handlebars templates, the fields line up and you avoid re-keying anything.
- Can I generate quotes in Node or Python?
- Yes — it’s a single HTTP POST, so any language works. Copy-paste Node and Python examples are on this page.