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
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
- Build open-invoices query
- Jobber: open invoices
- 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.
- Aspire's 2026 report on 1,015 commercial landscape contractors: 76% bill within four days of finishing a job, only half of them get paid on time, over 60% are usually paid at least a week late and 7% report delays of two to three months. Source: Aspire 2026 Commercial Landscape Industry Report (press release via GlobeNewswire on Nasdaq, Oct 7, 2025) (Industry survey)
- Overdue invoices are a regular LawnSite topic. LawnSite blocks automated readers, so we link the thread and quote nothing from it. Source: LawnSite thread: Overdue invoices (Forum thread)
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
| Tool | Official 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 |
| n8n | Community 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
- 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.
- 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.
- 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.
- Company details: LAWN_COMPANY_NAME, LAWN_COMPANY_PHONE, COMPANY_TZ. Every message names your company.
- 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.
- 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.
- 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).
- 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.
- 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)
| PASS | L3-01 | 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 |
| PASS | L3-02 | Next hourly run the same day: nothing repeats |
| PASS | L3-03 | 3 days past due: second step ('if it's already paid, ignore this'), still no late-fee wording |
| PASS | L3-04 | 10 days past due: offers to fix a problem or split the payment, no threats |
| PASS | L3-05 | 21 days past due: last customer reminder; the late-fee line appears only here and only because LATE_FEE_NOTE is set |
| PASS | L3-06 | 30 days past due: the office (not the customer) decides: call, payment plan or pause service; includes the client with follow-ups off |
| PASS | L3-06b | After day 30: silence (no more customer or office messages) |
| PASS | L3-07 | Late start (first run 11 days past due): only the latest step goes out, not the whole backlog |
| PASS | L3-07b | Next day: nothing (the next step is day +21) |
| PASS | L3-08 | Balance is $0 in Jobber (paid but status not yet flipped): no reminder |
| PASS | L3-09 | Customer texts back: logged, no automatic reply |
| PASS | L3-09b | Next run: no more reminders to that customer; office told once to answer them |
| PASS | L3-09c | Later steps: still nothing to that customer, no repeated office email |
| PASS | L3-10 | Customer texted STOP: reminders go by email instead |
| PASS | L3-11 | Before 8 am in the customer's time zone: emails go, the text waits |
| PASS | L3-11b | 9 am run: the held text goes out, email not repeated |
| PASS | L3-12 | Jobber THROTTLED twice in one day: one office email, no customer messages, no crash |
| PASS | L3-12b | Jobber back: the reminders that were due go out |
| PASS | L3-13 | Forged Twilio signature: not recorded |
| PASS | L3-14 | Twilio 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.