PDF templates / Quote / Estimate
Classic Quote
Formal B2B quote with letterhead, prepared-for / from blocks, itemised services + materials, labour/materials/subscription subtotals, tax breakdown, deposit schedule and signature block.

DSL source
The whole template. Learn the language in the template DSL guide.
const cols = [
["Category", "auto"],
["Description", "1fr"],
["Qty", "auto", "right"],
["Unit", "auto"],
["Unit Price", "auto", "right"],
["Amount", "auto", "right"],
];
const template = doc(
{ size: "A4", title: "Quote {{quoteNumber}}", padding: [28, 32, 28, 32] },
// ===== Header =====
hdr(
r({ "border": [0, 0, 2, 0], "border-color": "#1a1a1a", "padding": [0, 0, 8, 0] },
col("65%",
s({ "font-family": "NotoSans", "font-size": 22, "font-weight": "bold", "color": "#1a1a1a", "letter-spacing": 2 }, "QUOTATION"),
s({ "font-family": "NotoSans", "font-size": 9, "color": "#555", "margin": [2, 0, 0, 0] }, "{{projectName}}"),
),
col("35%", { align: "right" },
s({ "font-family": "NotoSans", "font-size": 10, "font-weight": "bold", "color": "#1a1a1a" }, "{{vendor.name}}"),
s({ "font-family": "NotoSans", "font-size": 8, "color": "#555" }, "{{vendor.website}}"),
s({ "font-family": "NotoSans", "font-size": 8, "color": "#555" }, "{{vendor.email}}"),
),
),
),
// ===== Meta strip =====
r({ "margin": [8, 0, 0, 0], "background-color": "#f3f1ec", "border": 0.5, "border-color": "#bbb", "padding": 8 },
col("25%",
s({ "font-family": "NotoSans", "font-size": 7, "color": "#666", "letter-spacing": 1 }, "QUOTE NO."),
s({ "font-family": "NotoSans", "font-size": 10, "font-weight": "bold", "color": "#1a1a1a" }, "{{quoteNumber}}"),
),
col("25%",
s({ "font-family": "NotoSans", "font-size": 7, "color": "#666", "letter-spacing": 1 }, "REFERENCE"),
s({ "font-family": "NotoSans", "font-size": 10, "color": "#1a1a1a" }, "{{reference}}"),
),
col("25%",
s({ "font-family": "NotoSans", "font-size": 7, "color": "#666", "letter-spacing": 1 }, "DATE ISSUED"),
s({ "font-family": "NotoSans", "font-size": 10, "color": "#1a1a1a" }, "{{date}}"),
),
col("25%",
s({ "font-family": "NotoSans", "font-size": 7, "color": "#666", "letter-spacing": 1 }, "VALID UNTIL"),
s({ "font-family": "NotoSans", "font-size": 10, "font-weight": "bold", "color": "#1a1a1a" }, "{{validUntil}} ({{validityDays}} days)"),
),
),
gap(8),
// ===== Parties =====
r({},
col("48%", { "border": 0.5, "border-color": "#bbb", "padding": 8 },
s({ "font-family": "NotoSans", "font-size": 7, "color": "#666", "letter-spacing": 1, "margin": [0, 0, 3, 0] }, "FROM"),
s({ "font-family": "NotoSans", "font-size": 10, "font-weight": "bold", "color": "#1a1a1a" }, "{{vendor.name}}"),
s({ "font-family": "NotoSans", "font-size": 9, "color": "#333", "line-height": 1.35 }, "{{vendor.address}}"),
s({ "font-family": "NotoSans", "font-size": 9, "color": "#333", "margin": [3, 0, 0, 0] }, "Tel: {{vendor.phone}}"),
s({ "font-family": "NotoSans", "font-size": 9, "color": "#333" }, "Email: {{vendor.email}}"),
s({ "font-family": "NotoSans", "font-size": 9, "color": "#333" }, "Tax ID: {{vendor.taxId}}"),
s({ "font-family": "NotoSans", "font-size": 9, "color": "#333", "margin": [3, 0, 0, 0] }, "Contact: {{vendor.contactName}}, {{vendor.contactTitle}}"),
),
col("4%", s(" ")),
col("48%", { "border": 0.5, "border-color": "#bbb", "padding": 8 },
s({ "font-family": "NotoSans", "font-size": 7, "color": "#666", "letter-spacing": 1, "margin": [0, 0, 3, 0] }, "PREPARED FOR"),
s({ "font-family": "NotoSans", "font-size": 10, "font-weight": "bold", "color": "#1a1a1a" }, "{{customer.name}}"),
s({ "font-family": "NotoSans", "font-size": 9, "color": "#333", "line-height": 1.35 }, "{{customer.address}}"),
s({ "font-family": "NotoSans", "font-size": 9, "color": "#333", "margin": [3, 0, 0, 0] }, "Attn: {{customer.contactName}}, {{customer.contactTitle}}"),
s({ "font-family": "NotoSans", "font-size": 9, "color": "#333" }, "Email: {{customer.email}}"),
s({ "font-family": "NotoSans", "font-size": 9, "color": "#333" }, "Tel: {{customer.phone}}"),
),
),
gap(10),
// ===== Project =====
r({ "border": 0.5, "border-color": "#bbb", "padding": 8, "background-color": "#fafaf7" },
s({ "font-family": "NotoSans", "font-size": 7, "color": "#666", "letter-spacing": 1 }, "PROJECT"),
s({ "font-family": "NotoSans", "font-size": 11, "font-weight": "bold", "color": "#1a1a1a", "margin": [2, 0, 3, 0] }, "{{projectName}}"),
s({ "font-family": "NotoSans", "font-size": 9, "color": "#333", "line-height": 1.4 }, "{{projectSummary}}"),
),
gap(10),
// ===== Line items =====
s({ "font-family": "NotoSans", "font-size": 10, "font-weight": "bold", "color": "#1a1a1a", "letter-spacing": 1, "margin": [0, 0, 4, 0], "border": [0, 0, 1, 0], "border-color": "#1a1a1a", "padding": [0, 0, 2, 0] }, "SCHEDULE OF CHARGES"),
table(cols, "item in items", [
["{{item.category}}", "auto"],
["{{item.description}}", "1fr"],
["{{item.qty}}", "auto", "right"],
["{{item.unit}}", "auto"],
["${{item.unitPrice}}", "auto", "right"],
["${{item.total}}", "auto", "right"],
]),
// ===== Category subtotals + Totals =====
totals([
["Labour subtotal", "${{labourSubtotal}}"],
["Materials subtotal", "${{materialsSubtotal}}"],
["Subscriptions subtotal", "${{subscriptionsSubtotal}}"],
["Subtotal", "${{subtotal}}", true],
["{{discountLabel}}", "− ${{discountAmount}}"],
["Taxable amount", "${{taxableAmount}}"],
["{{taxLabel}}", "${{taxAmount}}"],
["TOTAL ({{currency}})", "${{total}}", true],
], cols),
gap(8),
// ===== Payment schedule =====
r({ "border": 1, "border-color": "#1a1a1a", "padding": 8 },
col("50%",
s({ "font-family": "NotoSans", "font-size": 7, "color": "#666", "letter-spacing": 1 }, "PAYMENT SCHEDULE"),
s({ "font-family": "NotoSans", "font-size": 9, "color": "#1a1a1a", "margin": [3, 0, 0, 0] }, "{{depositLabel}}"),
s({ "font-family": "NotoSans", "font-size": 9, "color": "#1a1a1a" }, "Balance on completion (Net 30)"),
),
col("50%", { align: "right" },
s({ "font-family": "NotoSans", "font-size": 7, "color": "#666", "letter-spacing": 1 }, "AMOUNT"),
s({ "font-family": "NotoSans", "font-size": 10, "font-weight": "bold", "color": "#1a1a1a", "margin": [3, 0, 0, 0] }, "${{depositAmount}}"),
s({ "font-family": "NotoSans", "font-size": 10, "font-weight": "bold", "color": "#1a1a1a" }, "${{balanceOnCompletion}}"),
),
),
gap(10),
// ===== Scope / Terms / Notes =====
s({ "font-family": "NotoSans", "font-size": 9, "font-weight": "bold", "color": "#1a1a1a", "letter-spacing": 1, "margin": [0, 0, 2, 0] }, "SCOPE OF WORK"),
s({ "font-family": "NotoSans", "font-size": 8.5, "color": "#333", "line-height": 1.4 }, "{{scope}}"),
gap(6),
s({ "font-family": "NotoSans", "font-size": 9, "font-weight": "bold", "color": "#1a1a1a", "letter-spacing": 1, "margin": [0, 0, 2, 0] }, "TERMS & CONDITIONS"),
s({ "font-family": "NotoSans", "font-size": 8.5, "color": "#333", "line-height": 1.4 }, "{{terms}}"),
gap(6),
s({ "font-family": "NotoSans", "font-size": 9, "font-weight": "bold", "color": "#1a1a1a", "letter-spacing": 1, "margin": [0, 0, 2, 0] }, "ASSUMPTIONS & NOTES"),
s({ "font-family": "NotoSans", "font-size": 8.5, "color": "#333", "line-height": 1.4 }, "{{notes}}"),
gap(10),
// ===== Acceptance =====
r({ "border": 1, "border-color": "#1a1a1a", "padding": 10 },
s({ "font-family": "NotoSans", "font-size": 10, "font-weight": "bold", "color": "#1a1a1a", "letter-spacing": 1, "margin": [0, 0, 3, 0] }, "ACCEPTANCE"),
s({ "font-family": "NotoSans", "font-size": 8.5, "color": "#333", "line-height": 1.4, "margin": [0, 0, 8, 0] }, "{{acceptance.instruction}}"),
r({ "margin": [6, 0, 0, 0] },
col("55%",
s({ "font-family": "NotoSans", "font-size": 9, "color": "#1a1a1a", "border": [0, 0, 0.5, 0], "border-color": "#1a1a1a", "padding": [10, 0, 2, 0] }, " "),
s({ "font-family": "NotoSans", "font-size": 7, "color": "#666", "letter-spacing": 1, "margin": [2, 0, 0, 0] }, "{{acceptance.signatureLabel}}"),
),
col("5%", s(" ")),
col("40%",
s({ "font-family": "NotoSans", "font-size": 9, "color": "#1a1a1a", "border": [0, 0, 0.5, 0], "border-color": "#1a1a1a", "padding": [10, 0, 2, 0] }, " "),
s({ "font-family": "NotoSans", "font-size": 7, "color": "#666", "letter-spacing": 1, "margin": [2, 0, 0, 0] }, "{{acceptance.dateLabel}}"),
),
),
gap(4),
r({},
col("55%",
s({ "font-family": "NotoSans", "font-size": 9, "color": "#1a1a1a", "border": [0, 0, 0.5, 0], "border-color": "#1a1a1a", "padding": [10, 0, 2, 0] }, " "),
s({ "font-family": "NotoSans", "font-size": 7, "color": "#666", "letter-spacing": 1, "margin": [2, 0, 0, 0] }, "{{acceptance.nameLabel}}"),
),
col("5%", s(" ")),
col("40%",
s({ "font-family": "NotoSans", "font-size": 9, "color": "#1a1a1a", "border": [0, 0, 0.5, 0], "border-color": "#1a1a1a", "padding": [10, 0, 2, 0] }, " "),
s({ "font-family": "NotoSans", "font-size": 7, "color": "#666", "letter-spacing": 1, "margin": [2, 0, 0, 0] }, "{{acceptance.titleLabel}}"),
),
),
),
gap(8),
// ===== Prepared by =====
r({ "border": [1, 0, 0, 0], "border-color": "#1a1a1a", "padding": [6, 0, 0, 0] },
col("60%",
s({ "font-family": "NotoSans", "font-size": 7, "color": "#666", "letter-spacing": 1 }, "PREPARED BY"),
s({ "font-family": "NotoSans", "font-size": 10, "font-weight": "bold", "color": "#1a1a1a", "margin": [2, 0, 0, 0] }, "{{preparedBy.name}}"),
s({ "font-family": "NotoSans", "font-size": 9, "color": "#333" }, "{{preparedBy.title}}"),
),
col("40%", { align: "right" },
s({ "font-family": "NotoSans", "font-size": 9, "color": "#333", "margin": [10, 0, 0, 0] }, "{{preparedBy.email}}"),
s({ "font-family": "NotoSans", "font-size": 9, "color": "#333" }, "{{preparedBy.phone}}"),
),
),
ftrPages("{{vendor.name}} · Quote {{quoteNumber}}"),
);
const sampleData = {
quoteNumber: "QT-2026-00318",
reference: "RFQ-RIV-2026-017",
date: "18 April 2026",
validUntil: "18 May 2026",
validityDays: 30,
currency: "USD",
projectName: "Warehouse Management System — Phase 2",
projectSummary: "Design and implementation of a bar-code-driven inventory workflow across three distribution centres, including integration with the existing ERP and driver-tablet app.",
vendor: {
name: "Northline Integration Co.",
address: "88 Mercer Street, 4th Floor\nNew York, NY 10012\nUnited States",
phone: "(212) 555-0177",
email: "sales@northline.example.com",
website: "northline.example.com",
taxId: "EIN 32-7781942",
contactName: "Priya Shah",
contactTitle: "Solutions Architect",
},
customer: {
name: "Riverside Manufacturing Holdings, LLC",
address: "1200 Industrial Boulevard, Building C\nPortland, OR 97201\nUnited States",
contactName: "Sarah Chen",
contactTitle: "Director of Operations",
email: "sarah.chen@riverside.example.com",
phone: "(503) 555-0233",
},
items: [
{ category: "Labour", description: "Discovery & process mapping — on-site workshops across the three distribution centres, stakeholder interviews, current-state documentation.", qty: 48, unit: "hours", unitPrice: "195.00", total: "9,360.00" },
{ category: "Labour", description: "Solution design & ERP integration blueprint — API contracts, data-mapping, acceptance criteria.", qty: 72, unit: "hours", unitPrice: "210.00", total: "15,120.00" },
{ category: "Labour", description: "Implementation & configuration — barcode workflow build, ERP adapter, driver-tablet app integration.", qty: 160, unit: "hours", unitPrice: "185.00", total: "29,600.00" },
{ category: "Labour", description: "User training (three two-day on-site sessions, up to 15 attendees per cohort).", qty: 6, unit: "days", unitPrice: "1,800.00", total: "10,800.00" },
{ category: "Materials", description: "Rugged handheld barcode scanners — Zebra TC22, includes charging cradle and 3-year warranty.", qty: 18, unit: "units", unitPrice: "845.00", total: "15,210.00" },
{ category: "Materials", description: "Wi-Fi access-point upgrade kit for cold-storage bays (ruggedised enclosure, PoE).", qty: 6, unit: "units", unitPrice: "620.00", total: "3,720.00" },
{ category: "Subscription", description: "Northline Connect — annual platform subscription, unlimited users, 99.9% SLA.", qty: 1, unit: "year", unitPrice: "9,600.00", total: "9,600.00" },
],
labourSubtotal: "64,880.00",
materialsSubtotal: "18,930.00",
subscriptionsSubtotal: "9,600.00",
subtotal: "93,410.00",
discountLabel: "Multi-site commitment discount (4%)",
discountAmount: "3,736.40",
taxableAmount: "89,673.60",
taxRate: 0.08,
taxLabel: "Sales Tax (NY 8%)",
taxAmount: "7,173.89",
total: "96,847.49",
depositLabel: "30% deposit on acceptance",
depositAmount: "29,054.25",
balanceOnCompletion: "67,793.24",
terms: "This quote is valid for 30 days from the date of issue. Prices are held in USD and exclude shipping and on-site travel expenses, which will be billed at cost with receipts. A 30% deposit is required on acceptance; the balance is invoiced on project completion and payable Net 30. Work commences within ten business days of deposit receipt and signed statement of work. Either party may terminate with fourteen days' written notice; billed work to date is payable on termination.",
scope: "Included: requirements discovery, solution design, barcode workflow implementation, ERP adapter, driver-app integration, user training, one year of platform subscription and standard support. Not included: hardware beyond the items listed, ongoing managed services past the first year, changes to the existing ERP outside the documented integration points.",
notes: "Pricing assumes access to non-production ERP and VPN credentials within five business days of kick-off. Delays to access will shift delivery dates by the equivalent duration.",
preparedBy: {
name: "Priya Shah",
title: "Solutions Architect",
email: "priya.shah@northline.example.com",
phone: "(212) 555-0179",
},
acceptance: {
instruction: "To accept this quote, please sign below and return by email to sales@northline.example.com, or reply with written confirmation referencing the quote number.",
signatureLabel: "Authorised signature",
nameLabel: "Printed name",
titleLabel: "Title",
dateLabel: "Date",
},
};Sample data
{
"quoteNumber": "QT-2026-00318",
"reference": "RFQ-RIV-2026-017",
"date": "18 April 2026",
"validUntil": "18 May 2026",
"validityDays": 30,
"currency": "USD",
"projectName": "Warehouse Management System — Phase 2",
"projectSummary": "Design and implementation of a bar-code-driven inventory workflow across three distribution centres, including integration with the existing ERP and driver-tablet app.",
"vendor": {
"name": "Northline Integration Co.",
"address": "88 Mercer Street, 4th Floor\nNew York, NY 10012\nUnited States",
"phone": "(212) 555-0177",
"email": "sales@northline.example.com",
"website": "northline.example.com",
"taxId": "EIN 32-7781942",
"contactName": "Priya Shah",
"contactTitle": "Solutions Architect"
},
"customer": {
"name": "Riverside Manufacturing Holdings, LLC",
"address": "1200 Industrial Boulevard, Building C\nPortland, OR 97201\nUnited States",
"contactName": "Sarah Chen",
"contactTitle": "Director of Operations",
"email": "sarah.chen@riverside.example.com",
"phone": "(503) 555-0233"
},
"items": [
{
"category": "Labour",
"description": "Discovery & process mapping — on-site workshops across the three distribution centres, stakeholder interviews, current-state documentation.",
"qty": 48,
"unit": "hours",
"unitPrice": "195.00",
"total": "9,360.00"
},
{
"category": "Labour",
"description": "Solution design & ERP integration blueprint — API contracts, data-mapping, acceptance criteria.",
"qty": 72,
"unit": "hours",
"unitPrice": "210.00",
"total": "15,120.00"
},
{
"category": "Labour",
"description": "Implementation & configuration — barcode workflow build, ERP adapter, driver-tablet app integration.",
"qty": 160,
"unit": "hours",
"unitPrice": "185.00",
"total": "29,600.00"
},
{
"category": "Labour",
"description": "User training (three two-day on-site sessions, up to 15 attendees per cohort).",
"qty": 6,
"unit": "days",
"unitPrice": "1,800.00",
"total": "10,800.00"
},
{
"category": "Materials",
"description": "Rugged handheld barcode scanners — Zebra TC22, includes charging cradle and 3-year warranty.",
"qty": 18,
"unit": "units",
"unitPrice": "845.00",
"total": "15,210.00"
},
{
"category": "Materials",
"description": "Wi-Fi access-point upgrade kit for cold-storage bays (ruggedised enclosure, PoE).",
"qty": 6,
"unit": "units",
"unitPrice": "620.00",
"total": "3,720.00"
},
{
"category": "Subscription",
"description": "Northline Connect — annual platform subscription, unlimited users, 99.9% SLA.",
"qty": 1,
"unit": "year",
"unitPrice": "9,600.00",
"total": "9,600.00"
}
],
"labourSubtotal": "64,880.00",
"materialsSubtotal": "18,930.00",
"subscriptionsSubtotal": "9,600.00",
"subtotal": "93,410.00",
"discountLabel": "Multi-site commitment discount (4%)",
"discountAmount": "3,736.40",
"taxableAmount": "89,673.60",
"taxRate": 0.08,
"taxLabel": "Sales Tax (NY 8%)",
"taxAmount": "7,173.89",
"total": "96,847.49",
"depositLabel": "30% deposit on acceptance",
"depositAmount": "29,054.25",
"balanceOnCompletion": "67,793.24",
"terms": "This quote is valid for 30 days from the date of issue. Prices are held in USD and exclude shipping and on-site travel expenses, which will be billed at cost with receipts. A 30% deposit is required on acceptance; the balance is invoiced on project completion and payable Net 30. Work commences within ten business days of deposit receipt and signed statement of work. Either party may terminate with fourteen days' written notice; billed work to date is payable on termination.",
"scope": "Included: requirements discovery, solution design, barcode workflow implementation, ERP adapter, driver-app integration, user training, one year of platform subscription and standard support. Not included: hardware beyond the items listed, ongoing managed services past the first year, changes to the existing ERP outside the documented integration points.",
"notes": "Pricing assumes access to non-production ERP and VPN credentials within five business days of kick-off. Delays to access will shift delivery dates by the equivalent duration.",
"preparedBy": {
"name": "Priya Shah",
"title": "Solutions Architect",
"email": "priya.shah@northline.example.com",
"phone": "(212) 555-0179"
},
"acceptance": {
"instruction": "To accept this quote, please sign below and return by email to sales@northline.example.com, or reply with written confirmation referencing the quote number.",
"signatureLabel": "Authorised signature",
"nameLabel": "Printed name",
"titleLabel": "Title",
"dateLabel": "Date"
}
}Render it with your data
Any API key can render this template by its ID. This call uses the sample data; add a data object to use your own. See the API reference.
curl -X POST https://makespdf.com/api/v1/render \
-H "Authorization: Bearer $MAKESPDF_API_KEY" \
-H "Content-Type: application/json" \
-d '{"templateId": "quote-classic"}' \
-o output.pdf