PDF templates / Invoice

Invoice with Logo

Header references an uploaded company logo via `asset:<id>` from your asset library. Demonstrates the user-asset store — upload a logo at /settings/assets, then replace `logoAssetId` in your data with the returned id.

First page of the Invoice with Logo template, rendered with its sample data
invoice-with-logo.pdfpage 1 of 1

DSL source

The whole template. Learn the language in the template DSL guide.

js
const cols = [
  ["Description", "1fr"],
  ["Qty", "auto", "right"],
  ["Unit Price", "auto", "right"],
  ["Amount", "auto", "right"],
];

const template = doc(
  { size: "A4", title: "Invoice {{invoiceNumber}}", padding: [32, 36, 32, 36] },

  // Header: logo on the left, invoice meta on the right.
  r({ margin: [0, 0, 12, 0] },
    col("40%",
      img({ src: "asset:{{logoAssetId}}", alt: "{{vendor.name}} logo", width: 120, height: 48 }),
      s({ "font-size": 9, color: "#555", margin: [6, 0, 0, 0], "line-height": 1.4 }, "{{vendor.address}}"),
      s({ "font-size": 9, color: "#555" }, "{{vendor.phone}}  •  {{vendor.email}}"),
    ),
    col("60%", { align: "right" },
      s({ "font-size": 26, "font-weight": "bold", color: "#1a1a1a" }, "INVOICE"),
      s({ "font-size": 10, color: "#333", margin: [4, 0, 0, 0] }, "No. {{invoiceNumber}}"),
      s({ "font-size": 10, color: "#555", margin: [2, 0, 0, 0] }, "Issued {{date}}"),
      s({ "font-size": 10, "font-weight": "bold", color: "#c33", margin: [2, 0, 0, 0] }, "Due {{dueDate}}"),
    ),
  ),

  // Bill to.
  r({ margin: [0, 0, 12, 0] },
    col(
      s({ "font-size": 8, "font-weight": "bold", color: "#7a8a95", margin: [0, 0, 3, 0] }, "BILL TO"),
      s({ "font-size": 11, "font-weight": "bold", color: "#1a1a1a" }, "{{customer.name}}"),
      s({ "font-size": 9, color: "#333", margin: [1, 0, 0, 0], "line-height": 1.4 }, "{{customer.address}}"),
      s({ "font-size": 9, color: "#333" }, "{{customer.email}}"),
    ),
  ),

  // Items.
  table(cols, "item in items", [
    ["{{item.description}}", "1fr"],
    ["{{item.qty}}", "auto", "right"],
    ["${{item.unitPrice}}", "auto", "right"],
    ["${{item.total}}", "auto", "right"],
  ]),

  totals([
    ["Subtotal", "${{subtotal}}"],
    ["Tax", "${{taxAmount}}"],
    ["Total", "${{total}} {{currency}}", true],
  ], cols),

  gap(12),

  // Notes block.
  r(
    col(
      s({ "font-size": 8, "font-weight": "bold", color: "#1a1a1a", margin: [0, 0, 3, 0] }, "NOTES"),
      s({ "font-size": 9, color: "#333", "line-height": 1.45 }, "{{notes}}"),
    ),
  ),

  ftrPages("{{vendor.name}} — {{invoiceNumber}}"),
);

const sampleData = {
  invoiceNumber: "INV-2026-00001",
  date: "1 May 2026",
  dueDate: "31 May 2026",
  currency: "USD",
  // Replace this with the id returned by POST /api/v1/assets after uploading
  // your company logo. While this placeholder is in place, the renderer
  // falls back to a labelled "asset unavailable" rectangle.
  logoAssetId: "your-logo-id-here",
  vendor: {
    name: "Acme Industries, Inc.",
    address: "200 Bridge Street, Floor 3\nBoston, MA 02110\nUnited States",
    phone: "(617) 555-0148",
    email: "billing@acme.example.com",
  },
  customer: {
    name: "Northwind Trading Co.",
    address: "742 Evergreen Terrace\nSpringfield, OR 97477",
    email: "ap@northwind.example.com",
  },
  items: [
    { description: "Q2 Strategic Consulting Retainer", qty: 1, unitPrice: "8,500.00", total: "8,500.00" },
    { description: "Workshop facilitation (2 sessions)", qty: 2, unitPrice: "1,200.00", total: "2,400.00" },
    { description: "Documentation deliverables", qty: 1, unitPrice: "950.00", total: "950.00" },
  ],
  subtotal: "11,850.00",
  taxAmount: "1,036.88",
  total: "12,886.88",
  notes: "Wire transfer preferred. Net 30. Reference invoice number on remittance. Replace logoAssetId with an asset uploaded via POST /api/v1/assets to see your logo in the header.",
};

Sample data

json
{
  "invoiceNumber": "INV-2026-00001",
  "date": "1 May 2026",
  "dueDate": "31 May 2026",
  "currency": "USD",
  "logoAssetId": "your-logo-id-here",
  "vendor": {
    "name": "Acme Industries, Inc.",
    "address": "200 Bridge Street, Floor 3\nBoston, MA 02110\nUnited States",
    "phone": "(617) 555-0148",
    "email": "billing@acme.example.com"
  },
  "customer": {
    "name": "Northwind Trading Co.",
    "address": "742 Evergreen Terrace\nSpringfield, OR 97477",
    "email": "ap@northwind.example.com"
  },
  "items": [
    {
      "description": "Q2 Strategic Consulting Retainer",
      "qty": 1,
      "unitPrice": "8,500.00",
      "total": "8,500.00"
    },
    {
      "description": "Workshop facilitation (2 sessions)",
      "qty": 2,
      "unitPrice": "1,200.00",
      "total": "2,400.00"
    },
    {
      "description": "Documentation deliverables",
      "qty": 1,
      "unitPrice": "950.00",
      "total": "950.00"
    }
  ],
  "subtotal": "11,850.00",
  "taxAmount": "1,036.88",
  "total": "12,886.88",
  "notes": "Wire transfer preferred. Net 30. Reference invoice number on remittance. Replace logoAssetId with an asset uploaded via POST /api/v1/assets to see your logo in the header."
}

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.

bash
curl -X POST https://makespdf.com/api/v1/render \
  -H "Authorization: Bearer $MAKESPDF_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"templateId": "invoice-with-logo"}' \
  -o output.pdf