Generate PDF Invoices from Google Sheets Automatically (No Code)

A new row lands in your Google Sheets client tracker. Thirty seconds later, a designed, branded invoice PDF is sitting in your Drive folder and on its way to…

A new row lands in your Google Sheets client tracker. Thirty seconds later, a designed, branded invoice PDF is sitting in your Drive folder and on its way to the client's inbox. No script to write, no PDF-generation module to configure, no webhook round-trips.

In this guide you'll build that exact scenario in Make.com. The "generation" step turns out to be a single URL you paste into one HTTP module. By the end you'll have an invoicing pipeline that runs itself every time you add a client.

Three ways people do this today (and why they're more work than they look)

Google offers an official Apps Script sample that creates and emails invoices from spreadsheet data [1]. It works, but it's rated at beginner coding level and takes about 15 minutes of deploying and configuring a script [1]. It also exports the sheet's own template to PDF via the Sheets export endpoint [1], which caps your design at what a spreadsheet can render (the sample only accounts for six rows of line-item data in its template [1], needs a 500 ms latency pause [1], and relies on an 'Email Sent' column to avoid resending invoices [1]).

The no-code route in Make.com also exists. Plumsail Documents, for example, publishes a tutorial using the same chain we'll build (Watch new rows, then HTTP, Google Drive, and Gmail modules) but with a separate PDF-generation module in the middle, its own double-curly-bracket tokens, and a 30-day trial. CustomJS gives 600 free PDFs per month but still adds a third-party module between your sheet and the PDF.

None of these collapse generation into a single GET whose URL already contains the row data. This walkthrough does.

The trick: your invoice template becomes a URL

MarkupGo's Magic Template URL generates images or PDFs from an existing template with zero code: you pass data and options as query parameters [2]. The structure is:

https://render.markupgo.com/template/{templateId}.pdf?{query}

Swap the extension to .png, .jpeg, or .webp for images [2]. Invoices are an explicitly listed use case [2].

Because the URL carries the data, Make.com's plain HTTP module is all you need. No PDF app, no task ID to parse, no polling. Your template uses Handlebars-style {{ variable }} placeholders, including {{#each}} loops for line items [3], so you design it once and reuse it for every client.

Step 1: Design the invoice template once (visually)

Build your invoice in MarkupGo's template editor with real HTML and CSS (your logo, fonts, tax layout, footer terms), exactly as it should print. Where row data should land, drop in placeholders like {{customerName}}, {{invoiceNumber}}, {{dueDate}}, and {{total}}.

For the line-items table, use an {{#each items}} loop so any number of rows renders cleanly. This is the part a spreadsheet template can't do well: a 12-item invoice and a 3-item invoice come out equally polished.

Pitfall: design for print dimensions (A4 or Letter) from the start. Retrofitting a screen-sized layout into a PDF is the most common reason people redo their template. If you want a full design walkthrough with a complete invoice template, our HTML-to-PDF invoice template guide covers it in depth.

Step 2: Turn on Magic URL for the template

In the template settings, enable the Magic URL option. This exposes your template at its render.markupgo.com URL. Copy the template ID, your endpoint becomes:

https://render.markupgo.com/template/{id}.pdf

Pitfall: Magic URL is public, anyone with the URL can render your template and consume your credits [2]. Treat the URL like a password. Don't paste it into public docs, repos, or screenshots with the query string visible.

Step 3: Set up the Make.com scenario: Watch New Rows

Create a new scenario in Make.com and add Google Sheets → Watch New Rows as the trigger. It fires whenever a new row is added to your tracker.

Pitfall: a blank row anywhere in your sheet stops this trigger from processing subsequent rows [4]. Keep your tracker contiguous, with no gaps.

Don't reach for Watch Changes instead. It only detects edits made by users inside the Sheets app, not API or script writes, and it doesn't watch for newly added rows at all [4].

One more setting: choose Unformatted value as the value render option [4]. Formatted values pull in currency symbols and thousands separators that turn into garbage inside a query string. Pass the raw number and let the template format it.

Step 4: Build the query string from the row

Map each sheet column to a query parameter:

?customerName={{name}}&invoiceNumber={{id}}&dueDate={{date}}&items...

Pitfall: customer names and addresses contain spaces, ampersands, and accents. Unencoded, they break the URL or silently truncate parameters. A client named "Barnes & Noble" will chop off everything after the ampersand. Use Google Sheets' ENCODEURL() in a helper column, or Make's URL-encoding functions, on every text field.

Keep parameter names matching your template's placeholder names exactly: {{customerName}} needs customerName=, not Customer Name=. The mapping is case-sensitive.

Test the URL in a browser first. Paste your Magic URL with sample values into Chrome or Firefox, you should see the finished PDF immediately. That proves the template and parameters work before Make ever enters the picture, and it cuts your debugging surface in half.

Step 5: One HTTP module does the rendering

Add HTTP → Make a request to the scenario:

  • Method: GET
  • URL: your Magic URL with the mapped query string

That's the entire generation step. The response is the PDF: no JSON to parse, no task ID, no follow-up fetch.

Pitfall: leave the method as GET and don't add auth headers. The Magic URL is designed to work as a plain GET; switching it to a POST or adding a request body is the most common cause of "why is my PDF blank".

Step 6: Deliver it: Drive and Gmail

Add Google Drive → Upload a File, mapping the HTTP module's response as the file content. Name the file with row data, like Invoice-{{invoiceNumber}}.pdf, so your Drive folder stays searchable.

Then add Gmail → Send an Email with the Drive file attached, sent to the customer email column from the same row.

This is the same delivery chain Plumsail's tutorial uses; the difference is our middle step is one GET instead of a generate-then-fetch dance.

Pitfall: in the HTTP module, set the response to come back as binary/data, not text. A text-mode response turns the PDF into a corrupt file the moment Drive saves it.

Step 7: Test it, then check the gotchas

Add one test row to the sheet, run the scenario manually once, and confirm three things: the PDF appears in Drive, the email arrives, and the template is filled correctly (check the line items and the encoded special characters).

On costs: every unique URL consumes a credit, but reusing the same URL within 15 days serves a cached copy without consuming additional credits [2], so re-running a scenario on unchanged data won't double-bill you. The free trial grants 100 credits per month, indefinitely, with no credit card required [5], which is enough to build and run this scenario for weeks before paying anything. Paid plans start at $29/month for 2,000 credits [5].

If a row's data changes after generation, the URL changes too, which means a new render and a new credit. For corrected invoices, that's usually exactly what you want. The revised version gets a fresh PDF.

Frequently asked questions

How much does it cost to generate invoices this way?

The free trial gives you 100 credits per month, indefinitely, with no credit card required [5]. When you outgrow that, paid plans start at $29/month for 2,000 credits, with Plus at $49 and Pro at $99 [5]. One invoice render costs one credit.

Will I burn credits if Make re-runs the same row?

No. Reusing the same Magic URL within 15 days serves a cached copy of the PDF without consuming additional credits [2]. Only a genuinely new URL (new data or changed parameters) triggers a fresh render.

Is the Magic URL safe to use with client data?

The Magic URL feature is public: anyone who has the URL can render your template and consume your credits [2]. In this workflow the URL lives inside your Make.com scenario and never touches the client side, so exposure risk is minimal. Just don't share the URL or commit it anywhere public.

Can I get a PNG or image instead of a PDF?

Yes. Change the extension in the URL from .pdf to .png, .jpeg, or .webp and the same template renders as an image [2]. That's how the same chain powers OG images and social graphics.

Do I need to know Google Apps Script?

This workflow doesn't need it. The Apps Script route is Google's official alternative, but it's rated at beginner coding level and involves deploying a script [1]. Here you're clicking modules together in Make.com; the only "code" is a URL with query parameters.


Add one more row to your sheet and watch the PDF land in Drive and the email hit your inbox. Then turn the scenario on and let every new client invoice itself. If you want the same trick for OG images and social graphics, our Make.com + Google Sheets image guide shows the image variant of this exact chain.

Sources

  1. Generate & send PDFs from Google Sheets — developers.google.com
  2. markupgo.com
  3. markupgo.com
  4. apps.make.com
  5. markupgo.com