Home / Electricians / On-site change-order sign-off by text link, with a Jobber note and a receipt

Electricians problem 5: Extra work found on site gets a verbal OK that nobody can prove later

On-site change-order sign-off by text link, with a Jobber note and a receipt

Verified with mocksLast tested 2026-10-28 · pricing checked October 2026

The tech sends the extra work, the reason and the price from a phone shortcut or form (one POST with a shared key). The homeowner gets a text (with consent) and an email with a signed link that expires in 48 hours. The page shows the job, the work, the reason and the price; the homeowner types their name and taps Approve or Decline. The decision is recorded once, in a sheet with time, IP and browser and as a Jobber job note. The tech gets a text ('OK to proceed' or 'do not do the extra work') and the homeowner gets an email receipt. If nobody answers in 30 minutes the tech gets one nudge; an expired link emails the office. Tampered or expired links get an error page, and a hidden honeypot stops bots.

The problem

These are a forum post, a city fee page and a utility's timeline, so treat them as indications, not measured rates.

Who it's for

Electrical contractors doing panel swaps, remodel wiring and service work where 'while we're in there' changes are common.

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 (permit log, opt-out list, change orders)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 200 single-segment texts and receiving 200 a month, at the highest listed carrier fee ($0.005): 200 x ($0.0083 + $0.005) + 200 x $0.0083 + $1.15 number = $5.47 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 header X-JOBBER-GRAPHQL-VERSION: 2026-09-25 is pinned.
  2. Texts need a Twilio number on an approved A2P 10DLC campaign. Set TWILIO_ACCOUNT_SID, TWILIO_BASIC_AUTH (base64 of SID:auth token), TWILIO_FROM. Texts only go out 8 a.m.-9 p.m. in the customer's state (ELEC_TEXT_START_HOUR / ELEC_TEXT_END_HOUR) and only with recorded consent.
  3. Email: MSS_EMAIL_API (e.g. https://api.resend.com), EMAIL_API_KEY, ELEC_EMAIL_FROM, ELEC_OFFICE_EMAIL. Every send carries an Idempotency-Key, so a retried run never emails twice.
  4. Google Sheet stand-in: MSS_SHEET_URL points at the shared sheets (sms_optouts, inbound_texts, permits, change_orders). In production, swap these HTTP calls for n8n's Google Sheets node or keep a tiny sheet API.
  5. Company details: COMPANY_NAME, COMPANY_PHONE, COMPANY_ADDRESS, COMPANY_LICENSE, COMPANY_TZ. Every message names your company.
  6. Remove the test-only mss-*-tick webhooks (or put them behind n8n header auth) and make sure MSS_TEST_CLOCK is NOT set in production.
  7. Give techs a phone shortcut that POSTs JSON to /webhook/mss-el5-co with header X-MSS-Key: <TECH_FORM_KEY>. Fields: job_id (Jobber job id), job_number, address, customer_name, customer_phone, customer_email, sms_ok, state, tech_name, tech_phone, description, reason, price.
  8. CO_LINK_SECRET (long random string), CO_LINK_HOURS (48), CO_REMIND_MINUTES (30), PUBLIC_WEBHOOK_BASE (the public URL of your n8n webhooks).

Download

Download change-order-sign-off.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 and webhooks), Twilio, Accela Construct v4, 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, Jobber THROTTLED errors, and expiring OAuth tokens with refresh-token rotation. 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, jobs, permits and addresses are invented. Verified with mocks; nothing was sent to a real person, account or permit portal. How we test.

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

PASSE5-01Tech request without the right X-MSS-Key: 401, nothing sent
PASSE5-02Invalid price: 400 with the reason, nothing sent
PASSE5-03Tech posts extra work + price: homeowner gets a text (consented) and an email, both with the signed link
PASSE5-04Homeowner opens the link: sees job, work, reason, price, a typed-name sign form and a hidden honeypot
PASSE5-05Tampered link (signature changed, or expiry pushed out): 403
PASSE5-06Link opened after 48 h: 410 'expired, call us'
PASSE5-07Decision POST with the honeypot filled: polite page, nothing recorded, still pending
PASSE5-08No typed name: 400 asks for it, nothing recorded
PASSE5-09Homeowner approves with typed name: recorded once in the sheet (with time, IP, user agent), Jobber job note, tech texted 'OK to proceed', homeowner receipt
PASSE5-10Second submit (double tap or a later 'decline'): 'already approved', nothing changes; the link now shows the decision
PASSE5-11Reminder tick after a decision: no nudge to the tech
PASSE5-12Homeowner declines: tech told not to do the extra work, receipt sent, Jobber note says DECLINED
PASSE5-13Unsigned after 30 min: one text to the tech (not the homeowner), not repeated
PASSE5-14Still unsigned when the link expires: office email, change order marked expired
PASSE5-15No text consent on file: link goes by email only
PASSE5-169:15 pm, consent but no email on file: no text in quiet hours, the tech is told to get a paper signature
PASSE5-17Homeowner previously texted STOP (shared opt-out list): email only
PASSE5-18Jobber THROTTLED on the job note: decision still recorded, tech texted, office emailed to add the note by hand
PASSE5-19Jobber token expired: refreshed, note saved
PASSE5-20Twilio and email API 429 once: retried per Retry-After, each sent once

Verified with mocks

  • Tech request without the right X-MSS-Key: 401, nothing sent
  • Invalid price: 400 with the reason, nothing sent
  • Tech posts extra work + price: homeowner gets a text (consented) and an email, both with the signed link
  • Homeowner opens the link: sees job, work, reason, price, a typed-name sign form and a hidden honeypot
  • Tampered link (signature changed, or expiry pushed out): 403
  • Link opened after 48 h: 410 'expired, call us'
  • Decision POST with the honeypot filled: polite page, nothing recorded, still pending
  • No typed name: 400 asks for it, nothing recorded
  • Homeowner approves with typed name: recorded once in the sheet (with time, IP, user agent), Jobber job note, tech texted 'OK to proceed', homeowner receipt
  • Second submit (double tap or a later 'decline'): 'already approved', nothing changes; the link now shows the decision
  • Reminder tick after a decision: no nudge to the tech
  • Homeowner declines: tech told not to do the extra work, receipt sent, Jobber note says DECLINED
  • Unsigned after 30 min: one text to the tech (not the homeowner), not repeated
  • Still unsigned when the link expires: office email, change order marked expired
  • No text consent on file: link goes by email only
  • 9:15 pm, consent but no email on file: no text in quiet hours, the tech is told to get a paper signature
  • Homeowner previously texted STOP (shared opt-out list): email only
  • Jobber THROTTLED on the job note: decision still recorded, tech texted, office emailed to add the note by hand
  • Jobber token expired: refreshed, note saved
  • Twilio and email API 429 once: retried per Retry-After, each sent once
  • Verified with mocks; invented customers, jobs, permits 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 topics and the X-Jobber-Hmac-SHA256 signature; Jobber 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

  • A typed name plus a time, IP and browser record is a simple e-signature trail. Whether a typed-name e-signature is valid and enforceable varies by state (and by contract type), so ask your attorney whether it is enough for your change orders.
  • It doesn't change Jobber line items or the invoice; the note tells the office to update them.
  • Open change orders are kept in n8n's workflow static data for 90 days; the sheet row and the Jobber note are the permanent record.
  • Written and tested for Jobber's API only. Housecall Pro, ServiceTitan and other field-service 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). Have your attorney or insurer review texting consent and safety wording before going live; some states are stricter than federal law.