Home / Lawn Care / Lawn care estimate follow-up for Jobber: three useful touches, then a hand-off

Lawn Care problem 1: Lawn care estimates go out and nobody follows up, because the crew lead is mowing all day

Lawn care estimate follow-up for Jobber

Three useful touches, then a hand-off

Verified with mocksLast tested 2026-10-31 · pricing checked October 2026
Download the workflowlawn-estimate-follow-up.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 8 a.m. to 8 p.m. the workflow reads open Jobber quotes. On days 2, 5 and 9 after an estimate was sent, the customer gets one short message: a text if Jobber says the client accepts texts, otherwise an email. Each touch says something useful instead of 'just checking in': yard details (gate code, dog, areas to skip), an offer to change frequency or scope, then an offer to stop. It stops when the customer replies, opts out, or the quote is approved or archived. On day 14 the estimator gets a 'call them once yourself' email instead of a fourth message. When Jobber sends a signed QUOTE_APPROVED webhook, the customer gets a 'what to expect' email (gates, pets, rain days, billing), the quote gets a note and the office is told.

How the workflow runs

Trigger · When an event arrives

Jobber webhook (quote approved)

Steps

  1. Verify X-Jobber-Hmac-SHA256 + dedupe
  2. Jobber: get quote
  3. Approved? Welcome email + office + note
  4. Quote note items
  5. Jobber: quoteCreateNote
  6. Note saved? Else email the office

Outcome

  • Send approval emails
  • Send fallback emails

Also runs on: Every hour 8 am-8 pm → Build open-quotes query → Jobber: open quotes → Decide touches (only node that writes follow-up state) → Send texts + emails (Retry-After)

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

The problem

One survey (commercial contractors) and owner forum threads, so treat them as indications. We found no reliable public close-rate figure for lawn estimates, so we cite none.

Background reading: Lawn care estimate follow-up: a free template and three texts that stop when they should

Who it's for

US lawn care and landscape maintenance companies on Jobber that send estimates for weekly mowing, cleanups, mulch and aeration.

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. In your Jobber app, subscribe to the quote-approved webhook and point it at /webhook/mss-lc1-jobber. Set JOBBER_WEBHOOK_SECRET to the app's client secret (base64 HMAC-SHA256 of the raw body). Confirm the topic name in the app settings.
  8. LAWN_ESTIMATE_TOUCH_DAYS (default 2,5,9), LAWN_ESTIMATE_HANDOFF_DAY (14), optional LAWN_RAIN_POLICY, LAWN_BILLING_NOTE and LAWN_ROUTE_NOTE for the 'what to expect' email.
  9. The rain-day recipe's inbound text webhook (mss-lc2-sms) fills the inbound_texts and sms_optouts sheets this recipe reads. Without it, point your Twilio inbound webhook at something that fills them, or replies won't stop the sequence.

Download

Downloadlawn-estimate-follow-up.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)

PASSL1-01Day 1 after the estimate was sent: nothing yet
PASSL1-02Day 2: touch #1 asks about questions and yard details (text if the client allows texts, else email); the client who turned off quote follow-ups in Jobber and the approved quote are skipped
PASSL1-03Same day, next hourly run: no duplicate
PASSL1-04Day 5: touch #2 offers to change frequency or scope instead of pushing
PASSL1-05Day 9: last check-in that offers to stop
PASSL1-06Day 14: follow-ups end and the estimator gets a 'call them once yourself' email; customers get nothing
PASSL1-079:30 pm run: no text to the Kansas customer (8 am-9 pm), the email-only client still gets email
PASSL1-07bNext morning 8 am Central (7 am in western Kansas): still held because Kansas spans two time zones
PASSL1-07c9 am: the deferred text goes out once
PASSL1-08Workflow switched on late (day 7): only the touch that is due now (#2), not a burst
PASSL1-09Customer texted back after the estimate: no automatic touch, the office is told to answer
PASSL1-10Customer is on the shared STOP list: no text, follow-ups stop, office informed
PASSL1-11Signed QUOTE_APPROVED webhook: re-queries the quote, sends a 'what to expect' email (gates, pets, rain, billing), notes the quote in Jobber, tells the office
PASSL1-12Same webhook delivered twice (at-least-once): nothing happens the second time
PASSL1-13After approval the follow-ups stop for that estimate; others continue
PASSL1-14Forged X-Jobber-Hmac-SHA256: rejected before any Jobber call
PASSL1-15QUOTE_APPROVED for a quote that is still awaiting response in Jobber (stale event): nothing sent
PASSL1-16Jobber token expired during the webhook: refreshed, quote read and note saved
PASSL1-17Jobber THROTTLED on the hourly read: one office notice, no messages; the next hour works normally
PASSL1-18Twilio and email API both answer 429 once: each send waits per Retry-After and goes out exactly once

Actual output from the test run

Scenario L1-02: the day-2 follow-up text on a mowing estimate (invented customer and company). Names and numbers are invented.

Hi Dana, it's Kyle at Prairie Edge Lawn Co. Any questions on the estimate for weekly mowing, trimming and edging (April-October)? If something about the yard changed (gate code, dog, areas to skip), reply and we'll adjust it. Estimate: https://clienthub.getjobber.com/client_hubs/mock/quotes/1101 Reply STOP to opt out. - Prairie Edge Lawn Co.

Verified with mocks

  • Day 1 after the estimate was sent: nothing yet
  • Day 2: touch #1 asks about questions and yard details (text if the client allows texts, else email); the client who turned off quote follow-ups in Jobber and the approved quote are skipped
  • Same day, next hourly run: no duplicate
  • Day 5: touch #2 offers to change frequency or scope instead of pushing
  • Day 9: last check-in that offers to stop
  • Day 14: follow-ups end and the estimator gets a 'call them once yourself' email; customers get nothing
  • 9:30 pm run: no text to the Kansas customer (8 am-9 pm), the email-only client still gets email
  • Next morning 8 am Central (7 am in western Kansas): still held because Kansas spans two time zones
  • 9 am: the deferred text goes out once
  • Workflow switched on late (day 7): only the touch that is due now (#2), not a burst
  • Customer texted back after the estimate: no automatic touch, the office is told to answer
  • Customer is on the shared STOP list: no text, follow-ups stop, office informed
  • Signed QUOTE_APPROVED webhook: re-queries the quote, sends a 'what to expect' email (gates, pets, rain, billing), notes the quote in Jobber, tells the office
  • Same webhook delivered twice (at-least-once): nothing happens the second time
  • After approval the follow-ups stop for that estimate; others continue
  • Forged X-Jobber-Hmac-SHA256: rejected before any Jobber call
  • QUOTE_APPROVED for a quote that is still awaiting response in Jobber (stale event): nothing sent
  • Jobber token expired during the webhook: refreshed, quote read and note saved
  • Jobber THROTTLED on the hourly read: one office notice, no messages; the next hour works normally
  • Twilio and email API both answer 429 once: each send waits per Retry-After and 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

  • Jobber's own automatic quote follow-ups may already be on; use one or the other (the recipe skips clients with receivesQuoteFollowUps=false).
  • 'Days since sent' counts calendar days in your time zone.
  • 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.