Home / Lawn Care / Lawn care invoice reminder ladder: friendly first, then the office decides

Lawn Care problem 3: Invoices go out after the mow, and getting paid takes weeks of awkward reminders

Lawn care invoice reminder ladder

Friendly first, then the office decides

Verified with mocksLast tested 2026-10-31 · pricing checked October 2026
Download the workflowlawn-invoice-reminder-ladder.zip

20/20 test scenarios passed against mock APIs. Includes the n8n workflow, mock data and the test runner.

  • n8n
  • Twilio
  • Resend
  • Jobber
  • Google Sheets

Every hour from 9 a.m. to 6 p.m. the workflow reads unpaid Jobber invoices. Each customer gets at most four reminders: a heads-up 2 days before the due date, then 3, 10 and 21 days past due, each with the Jobber pay link and a friendly 'if it's already paid, ignore this'. A late-fee sentence appears only at day 21, and only if you paste the wording from your service agreement. On day 30 the customer gets nothing more and the office gets an email to decide: call, payment plan or pause service. A reply or STOP ends the customer reminders.

How the workflow runs

Trigger · On a schedule

Every hour 9 am-6 pm

Steps

  1. Build open-invoices query
  2. Jobber: open invoices
  3. Decide reminders (only node that writes ladder state)

Outcome

  • Send texts + emails (Retry-After)

Also runs on: Twilio inbound SMS → STOP / reply logger

Drawn from the node names in the workflow file inside the download (workflow.json).

The problem

A survey of commercial contractors and owner forum threads. Residential numbers may differ.

Background reading: Lawn care invoice reminders: Jobber's two follow-ups vs. a five-step ladder

Who it's for

US lawn care companies on Jobber that bill after each visit or monthly.

Tools and monthly cost

ToolOfficial price
Jobber (you probably already pay for it)Core $29 / month billed annually ($39 with a 1-year monthly commitment, $49 with no commitment); Connect from $99; Grow from $149; Plus from $399 (5 users). Jobber's developer docs say custom API integrations are only for approved customers, and the pricing page doesn't say which plan an API app needs pricing page
Twilio US local phone number$1.15 / month pricing page
Twilio US SMS, sent or received$0.0083 per segment, plus carrier fees on outbound texts of $0.0035-$0.005 per segment (AT&T $0.0035, T-Mobile $0.0045, Verizon $0.005) pricing page
A2P 10DLC registration (required to text US customers from a local number)One-time: $4.50 brand registration (Standard brands add $41.50 secondary vetting) and $15 campaign vetting. Monthly: $1.50-$10 per campaign by use case ($2 for sole proprietors) pricing page
Resend (sends the emails; any email API that accepts an Idempotency-Key works)Free: 3,000 emails / month, 100 / day. Pro: $20 / month for 50,000 emails pricing page
Google Sheets (opt-out list, replies, renewal list)Free with a Google Account; Google Workspace is optional pricing page
n8nCommunity Edition: free if you self-host (you pay for the server). n8n Cloud: Starter EUR 20 / month or Pro EUR 50 / month, billed annually pricing page

Example month: Illustrative arithmetic, not a measured result. One local number sending 150 single-segment texts and receiving 150 a month, at the highest listed carrier fee ($0.005): 150 x ($0.0083 + $0.005) + 150 x $0.0083 + $1.15 number = $4.39 a month in Twilio usage, plus the A2P 10DLC campaign fee ($1.50-$10 a month) and one-time registration ($4.50 brand + $15 campaign vetting). Emails stay inside Resend's free tier at this volume. n8n Cloud Starter (EUR 20 a month) or your own server, and your Jobber plan, come on top. Your volumes will differ.

Setup

  1. Jobber: create a Jobber developer app, add an n8n OAuth2 credential (authorization URL https://api.getjobber.com/api/oauth/authorize, token URL https://api.getjobber.com/api/oauth/token). n8n refreshes the token and stores the rotated refresh token. Set MSS_JOBBER_URL=https://api.getjobber.com/api/graphql. The X-JOBBER-GRAPHQL-VERSION header is pinned in the workflow.
  2. Texts need a Twilio number on an approved A2P 10DLC campaign. Set TWILIO_ACCOUNT_SID, TWILIO_BASIC_AUTH (base64 of SID:auth token) and LAWN_TWILIO_FROM. Texts only go out 8 a.m.-9 p.m. in the customer's time zone and only with recorded consent.
  3. Email: MSS_EMAIL_API (e.g. https://api.resend.com), EMAIL_API_KEY, LAWN_EMAIL_FROM, LAWN_OFFICE_EMAIL. Every send carries an Idempotency-Key, so a retried run never emails twice.
  4. Company details: LAWN_COMPANY_NAME, LAWN_COMPANY_PHONE, COMPANY_TZ. Every message names your company.
  5. Google Sheet stand-in: MSS_SHEET_URL points at the shared sheets (sms_optouts, inbound_texts and the recipe's own sheets). In production, swap these HTTP calls for n8n's Google Sheets node.
  6. Remove the test-only mss-lc*-tick webhook (or put it behind n8n header auth) and make sure MSS_TEST_CLOCK is NOT set in production.
  7. Point your Twilio inbound webhook at /webhook/mss-lc3-sms (or the rain-day recipe's mss-lc2-sms; both record STOP/START and replies).
  8. LAWN_LATE_FEE_NOTE: leave it empty unless your signed service agreement has a late fee, then copy that wording exactly. Late-fee rules vary by state; we're not lawyers.
  9. LAWN_INVOICE_OFFICE_DAY (default 30) sets when the office takes over. Turn off Jobber's own invoice follow-ups so customers don't get two sets.

Download

Downloadlawn-invoice-reminder-ladder.zip

Contains the n8n workflow, the mock data, the test runner with its last results, and the mock server we tested against. All keys in .env.example are fake.

Test result

Every workflow was imported into n8n 2.45.4 on an isolated test instance and run end to end. Jobber (GraphQL, OAuth2 with refresh-token rotation and signed webhooks), Twilio, the National Weather Service API, the email API (Resend-style) and Google Sheets were replaced by a local mock server built from the vendors' public docs: same request shapes and auth headers, HMAC-signed webhooks, HTTP 429 with Retry-After and Jobber THROTTLED errors. A frozen test clock checks the 8 a.m.-9 p.m. texting window. These recipes use no AI model; every decision is a written rule. Customers, yards, invoices and addresses are invented. Verified with mocks; nothing was sent to a real person or account. How we test.

20/20 scenarios passed (run 2026-10-31)

PASSL3-012 days before due: friendly heads-up with the pay link (text, else email); client with invoice follow-ups off gets nothing; paid invoices never queried
PASSL3-02Next hourly run the same day: nothing repeats
PASSL3-033 days past due: second step ('if it's already paid, ignore this'), still no late-fee wording
PASSL3-0410 days past due: offers to fix a problem or split the payment, no threats
PASSL3-0521 days past due: last customer reminder; the late-fee line appears only here and only because LATE_FEE_NOTE is set
PASSL3-0630 days past due: the office (not the customer) decides: call, payment plan or pause service; includes the client with follow-ups off
PASSL3-06bAfter day 30: silence (no more customer or office messages)
PASSL3-07Late start (first run 11 days past due): only the latest step goes out, not the whole backlog
PASSL3-07bNext day: nothing (the next step is day +21)
PASSL3-08Balance is $0 in Jobber (paid but status not yet flipped): no reminder
PASSL3-09Customer texts back: logged, no automatic reply
PASSL3-09bNext run: no more reminders to that customer; office told once to answer them
PASSL3-09cLater steps: still nothing to that customer, no repeated office email
PASSL3-10Customer texted STOP: reminders go by email instead
PASSL3-11Before 8 am in the customer's time zone: emails go, the text waits
PASSL3-11b9 am run: the held text goes out, email not repeated
PASSL3-12Jobber THROTTLED twice in one day: one office email, no customer messages, no crash
PASSL3-12bJobber back: the reminders that were due go out
PASSL3-13Forged Twilio signature: not recorded
PASSL3-14Twilio answers 429 once: waits per Retry-After, the text goes out exactly once

Actual output from the test run

Scenario L3-01: the friendly heads-up two days before the due date (invented customer; the pay link is a mock). Names and numbers are invented.

Hi Dana, a heads-up from Prairie Edge Lawn Co.: invoice #5101 for $220 is due Sat May 15. Pay online: https://clienthub.getjobber.com/client_hubs/mock/invoices/5101 Reply STOP to opt out. - Prairie Edge Lawn Co.

Verified with mocks

  • 2 days before due: friendly heads-up with the pay link (text, else email); client with invoice follow-ups off gets nothing; paid invoices never queried
  • Next hourly run the same day: nothing repeats
  • 3 days past due: second step ('if it's already paid, ignore this'), still no late-fee wording
  • 10 days past due: offers to fix a problem or split the payment, no threats
  • 21 days past due: last customer reminder; the late-fee line appears only here and only because LATE_FEE_NOTE is set
  • 30 days past due: the office (not the customer) decides: call, payment plan or pause service; includes the client with follow-ups off
  • After day 30: silence (no more customer or office messages)
  • Late start (first run 11 days past due): only the latest step goes out, not the whole backlog
  • Next day: nothing (the next step is day +21)
  • Balance is $0 in Jobber (paid but status not yet flipped): no reminder
  • Customer texts back: logged, no automatic reply
  • Next run: no more reminders to that customer; office told once to answer them
  • Later steps: still nothing to that customer, no repeated office email
  • Customer texted STOP: reminders go by email instead
  • Before 8 am in the customer's time zone: emails go, the text waits
  • 9 am run: the held text goes out, email not repeated
  • Jobber THROTTLED twice in one day: one office email, no customer messages, no crash
  • Jobber back: the reminders that were due go out
  • Forged Twilio signature: not recorded
  • Twilio answers 429 once: waits per Retry-After, the text goes out exactly once
  • Verified with mocks; invented customers, yards, invoices and addresses only.

Documented from official API docs only

Built to the vendor's documentation but not run against a live account. Check these on yours.

  • Jobber GraphQL field and mutation names, webhook signing (X-Jobber-Hmac-SHA256) and OAuth refresh-token rotation (from Jobber's developer docs; not run against a live account).
  • Twilio request signing, Messages API, 429 behavior and built-in STOP handling (from Twilio's docs). The email API follows Resend's documented request shape.

Limitations

  • The ladder never threatens collections, liens or court; what happens after day 30 is a person's decision.
  • If Jobber is rate-limited, the run sends nothing and the office gets one email that day; the next run catches up.
  • Every message is checked against a word list first: safety claims like 'pet safe' or 'non-toxic' (the kind 40 CFR 156.10 treats as misbranding on a pesticide label), 'guaranteed' results and collection threats are blocked, and the office is told instead.
  • Written and tested for Jobber's API only. LMN, Aspire, Service Autopilot and other software are not built for this recipe, and we make no claim that it works with them. Jobber's developer docs say custom integrations are only possible for approved Jobber customers, so check with Jobber first.
  • Not legal advice and not a compliance guarantee. Texts go only to customers with recorded consent, only between 8 a.m. and 9 p.m. in the customer's time zone, and plain-English opt-outs are honored (47 CFR 64.1200 is the federal rule we design around). Some states are stricter than federal law; have your attorney review texting consent before going live.