How to Generate Invoices with the ImaginePDF API

Mark your invoice fields as variables, fill them with one API call, and wire it into Zapier, Make, or any webhook so a finished invoice PDF generates itself.

Jagadeesh
Jagadeesh
June 27, 20268 min read

An invoice is tied to something that happens: an order is paid, a project ships, a subscription renews. So the natural moment to make one is the moment that event fires, one at a time, straight from the system that knows about it. You rarely sit down to produce a whole stack of invoices in one go.

ImaginePDF turns an invoice design into an endpoint. You mark the fields that change, send the order data in one API call, and get back a finished PDF. Then you put that call behind an automation, so the invoice generates itself the moment an order comes in.

This guide covers both halves: the single API call, and how to wire it into Zapier, Make, n8n, or any tool that can send a webhook.

A paid order calls the API and returns a finished invoice PDF
An order is paid, one API call fills your invoice design, and a finished PDF comes back ready to deliver.

Start from an invoice design

You need an invoice design first. Pick a free one on the invoice maker, or a format built for your region like the GST invoice, or build your own in the visual editor. Open it in the editor.

Then mark the parts that change from one invoice to the next as variables. Click a field, click the lightning bolt to make it dynamic, and give it a name. For an invoice that is usually the business and client details, the invoice number and date, and the totals. The variables guide walks through that gesture and how to create an API key, so keep it open in a tab.

The line items are the one part that works a little differently. They live in a table, and the number of rows changes with every order. Select that table, make it dynamic with the same lightning bolt, and name it line_items. A whole dynamic table is filled from the data you send, one row per line item, so the same design handles an order with two lines or one with a dozen.

Generate one invoice with a single call

With the fields named, generating an invoice is a single POST. You send the values in a data object, keyed by the names you gave them, and you authenticate with your API key on the X-API-Key header:

curl -X POST 'https://api.imaginepdf.com/api/v1/designs/YOUR_DESIGN_ID/generate' \
  -H 'X-API-Key: YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
  "data": {
    "business_name": "Brightwork Studio LLC",
    "client_name": "Harbor Foods Inc.",
    "invoice_number": "INV-1042",
    "invoice_date": "27 June 2026",
    "line_items": [
      ["Website redesign", "1", "3,500.00", "3,500.00"],
      ["Monthly hosting", "3", "50.00", "150.00"]
    ],
    "subtotal": "3,650.00",
    "tax": "310.25",
    "total": "3,960.25"
  }
}'

The text fields are plain strings. The line_items table is the one to look at: it is a list of rows, and each row is a list of cells in column order. No column names, no objects, just the cell values as they should read across the row. Add or remove inner arrays to match the order you are billing.

The response comes straight back with a link to the finished PDF:

{
  "status": "success",
  "data": {
    "filename": "invoice.pdf",
    "downloadUrl": "https://files.imaginepdf.com/...",
    "expiresIn": 3600
  },
  "error": null
}

Generation is synchronous, so there is nothing to poll. The call returns once the PDF is rendered, and downloadUrl is a ready-to-use link that needs no API key to open. It stays valid for about an hour, which is plenty of time for the next step to grab it. The JavaScript and Python tabs in the editor's API panel make the same call if you would rather not use cURL.

Wire it into an automation

One invoice on demand is handy. The real win is not calling this by hand at all. ImaginePDF does not ship a one-click Zapier app, and it does not need to: the endpoint is a plain REST call, and every automation tool can make a plain REST call. So the shape is the same wherever you build it.

Three steps:

  1. Trigger. An event in your stack: a paid order, a form submission, a closed deal.
  2. Generate. POST that event's data to the generate endpoint.
  3. Deliver. Take downloadUrl from the response and do something with it: email the PDF, save it to Drive, attach it to the customer record.
Trigger, generate, deliver: the three-step automation pattern
Trigger to generate to deliver. The middle step is always the same POST, whichever tool you build it in.

Zapier

Say you want an invoice every time a customer pays. Your trigger is the payment: Stripe, Payment succeeded, or Shopify, Order paid. Then add a Webhooks by Zapier, Custom Request action:

  • Method: POST
  • URL: https://api.imaginepdf.com/api/v1/designs/YOUR_DESIGN_ID/generate
  • Headers: X-API-Key set to your key, and Content-Type set to application/json
  • Data: a JSON body that maps the order fields into data, the same shape as the cURL above.

One honest wrinkle: the line_items table wants a list of rows, and an order's items usually arrive as a list from the trigger. Folding them into that nested array is the spot Zapier's plain field-mapping struggles with, so a small Code by Zapier step that builds the line_items array from the order is the clean way to do it.

Finish with a delivery action: Gmail, Send Email (or Email by Zapier) with the downloadUrl in the body, or Google Drive, Upload File pointed at the same link. Now every paid order produces an invoice with no one touching it.

Make and n8n

The pattern is identical in other tools, and the array-shaping is often easier:

  • Make: an HTTP, Make a request module does the POST. Build the line_items array with an Iterator or a small mapping function, then add a Gmail or Google Drive module that uses downloadUrl.
  • n8n: an HTTP Request node does the POST, an expression or a Function node shapes line_items, and an Email or Drive node delivers the file.

Any webhook or your own backend

Strip the tools away and this is just an HTTPS POST with one header. If you already receive a webhook when an order is paid (a Stripe webhook hitting your server, say), call ImaginePDF straight from that handler:

const res = await fetch(`https://api.imaginepdf.com/api/v1/designs/${DESIGN_ID}/generate`, {
  method: 'POST',
  headers: {
    'X-API-Key': process.env.IMAGINEPDF_API_KEY,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    data: {
      business_name: 'Brightwork Studio LLC',
      client_name: order.customerName,
      invoice_number: order.number,
      line_items: order.items.map((i) => [i.name, String(i.qty), i.unitPrice, i.amount]),
      total: order.total,
    },
  }),
});
 
const { data } = await res.json();
// data.downloadUrl is ready to email, store, or attach to the order

That order.items.map(...) is the whole trick: turn your list of items into a list of rows, and the table fills itself.

One at a time, not in bulk

It is worth saying plainly: invoices are not a batch job. You generate each one when its order happens, not in a nightly run of five hundred. That is why this guide is about a single call behind an event, rather than a spreadsheet of rows.

The batch flow does exist, and it is the right tool for documents that genuinely come in sets: a class of certificates, a month of payslips, a mailing of statements. For those, you upload a CSV and download a zip, which the bulk generation guide covers. Invoices are simply not that shape.

Put it to work

Start from a free design on the invoice maker (or a regional format like the GST invoice), open it in the visual editor to mark your fields, and create an API key from your dashboard. Point your automation at the endpoint, and the next paid order writes its own invoice.

For the field-marking and API-key setup in detail, see the template API guide.

Related guides