Skip to content

On a schedule

Turn rows in a billing sheet into QuickBooks invoices

Each new row in your billing sheet becomes a QuickBooks invoice, and the invoice number is written back into the row.

Runs
On a schedule
Apps
Google Sheets, QuickBooks
AI
Not needed
Access
accounting write; sheet editor

Send this to your assistant

Create a ClickRuntime automation: every hour, create a QuickBooks invoice for each row in my Billing sheet that has no invoice number yet, and write the invoice number back to the row.

Paste it into your assistant. It tells you what it will send or change before it runs live.

First time? Adding ClickRuntime to your assistant takes about two minutes.

Why use it

Why teams use this automation

A consultancy logs billable work in a shared sheet: client, description, hours, rate. At month end the bookkeeper re-types every line into QuickBooks, which takes an afternoon and occasionally bills the wrong client.

Creating the invoice straight from the row removes the re-typing. The sheet stays the simple place the team records work, and QuickBooks gets accurate invoices without delay.

What you get out of it

  • No re-typing

    Rows become invoices exactly as entered, which removes a whole class of copying mistakes.

  • Invoice sooner

    Work is billed within the hour it's logged, not at month end, which brings payments forward.

  • A clear trail

    The invoice number written back to each row shows what's been billed and what hasn't.

  • Keep the sheet your team knows

    Nobody needs to learn QuickBooks to record billable work.

How it works

What happens, step by step

  1. Every hour, ClickRuntime reads your Billing sheet.

  2. It picks out rows that don't have an invoice number yet.

  3. For each row, it finds the customer in QuickBooks, or creates them, and creates the invoice.

  4. It writes the new invoice number back into the row, so the row is never billed twice.

Before it runs live

  • Connect your Google Sheets account and pick the spreadsheets it may use
  • Connect QuickBooks

What you get

RunsOn a schedule
Turn rows in a billing sheet into QuickBooks invoicestoday, 9:00Succeeded
Google Sheets · BillingAcme Corp · October design retainer · 3,500 · Invoice 1052

Build your own

Need it to work differently?

This template is a starting point. Copy the prompt and change it, or describe a different automation from scratch, with your own conditions, more apps or an AI step. Your assistant writes it, tests it and runs it on ClickRuntime.
  • Your own rules

    Conditions, thresholds, filters and exceptions, written the way you'd explain them to a colleague.

  • Any number of apps

    One automation can read from one app and update several others. Over 248 apps are ready, and anything with an API works too.

  • AI where it helps

    Summaries, classification, extraction and drafts use ClickRuntime's built-in AI, with no extra key.

  • On a schedule or on each event

    Runs as often as every 5 minutes, or the moment an app sends an event, and keeps track of what it already handled.

Changes you can ask for

  • Act only on the items that match your own rules, and skip the rest
  • Add an AI step, for example to summarize, sort or draft a reply
  • Add another app, for example also send it to Slack
  • Combine it with other Google Sheets and QuickBooks steps into one automation

Under the hood

The code that runs this automation

This is the Python script that runs each time the automation starts. Your AI assistant writes it for you when you send the prompt, and you allow each step in your assistant. To change how the automation works, describe the change to your assistant and it updates the script for you. For every function it can use, see the script reference.
create_quickbooks_invoices_from_sheet_rows.pyexample
from google.oauth2.credentials import Credentials
from googleapiclient.discovery import build
from clickruntime import on_trigger, credentials, http, report_fetched

SHEET_ID = "your-spreadsheet-id"
API = "https://quickbooks.api.intuit.com/v3/company/1234567890"  # your QuickBooks company id

def qb(method, path, **kw):
    r = http.request(method, API + path, params={"minorversion": 73, **kw.pop("params", {})}, **kw, headers={"Accept": "application/json", "Authorization": "Bearer " + credentials.connection("quickbooks", "company")})
    return r.raise_for_status() or r.json()

@on_trigger
def run(event):
    sheets = build("sheets", "v4", credentials=Credentials(credentials.connection("google", "work")), cache_discovery=False).spreadsheets()
    rows = sheets.values().get(spreadsheetId=SHEET_ID, range="Billing!A2:D").execute().get("values", [])
    todo = [(i, r) for i, r in enumerate(rows, start=2) if len(r) >= 3 and (len(r) < 4 or not r[3])]
    report_fetched(len(todo))
    if not todo:
        return {"summary": "Nothing new"}
    for i, (customer, desc, amount, *_) in todo:
        name = customer.replace("'", "\\'")
        found = qb("GET", "/query", params={"query": f"select * from Customer where DisplayName = '{name}'"})["QueryResponse"].get("Customer")
        cust = found[0] if found else qb("POST", "/customer", json={"DisplayName": customer})["Customer"]
        inv = qb("POST", "/invoice", json={"CustomerRef": {"value": cust["Id"]}, "Line": [{
            "Amount": float(amount), "Description": desc, "DetailType": "SalesItemLineDetail",
            "SalesItemLineDetail": {"ItemRef": {"value": "1"}}}]})["Invoice"]
        sheets.values().update(spreadsheetId=SHEET_ID, range=f"Billing!D{i}", valueInputOption="RAW", body={"values": [[inv["DocNumber"]]]}).execute()
    return {"invoiced": len(todo)}

FAQ

Common questions

What columns does the sheet need?
Customer name, description and amount at minimum, plus an empty column for the invoice number. Dates and quantities are optional.
What if the customer isn't in QuickBooks yet?
It's created from the name in the row, so the invoice can still be made. Check new customers' details in QuickBooks afterwards.
Can it email the invoice to the customer?
Yes. Add an email column and ask for invoices to be sent through QuickBooks once created.
What permissions does it need?
accounting write; sheet editor. Nothing else in your accounts is used.
Does it need AI?
No. It runs without AI, so it doesn't use your plan's AI allowance.
How many runs does it use?
One run each time it checks. Checks that find nothing new and stop right away aren't counted.
Can I change how it works?
Yes. Describe the change to your AI assistant, for example a different schedule, channel or filter. It updates the automation, tests it and tells you what changed.

Set up “Turn rows in a billing sheet into QuickBooks invoices” from your assistant

Copy the prompt above, or connect your assistant first. Free plan, no credit card.