Jobber integration
Jobber is the field service management platform we built our revenue tracking around first. Connecting it closes the loop between ad spend and paid invoices, so Google Ads' Smart Bidding can optimize for revenue instead of just leads.
What it does
Three things:
- Lead sync. Every lead captured in VibeAds (form submission or qualified call) auto-creates a Client + Request in your Jobber account. You see new leads in Jobber's Requests pipeline.
- Job completion sync. When you mark a Job complete in Jobber, the corresponding VibeAds lead status flips to
completed. - Paid invoice upload (Max). When an invoice is marked paid in Jobber, VibeAds uploads the revenue to Google Ads as an offline conversion (UPLOAD_CLICKS_REVENUE). Smart Bidding learns which keywords drive paid customers.
Tier gating
| Feature | Free | Pro | Max |
|---|---|---|---|
| Connect Jobber | No | Yes | Yes |
| Lead → Jobber Client + Request | No | Yes | Yes |
| Job completion → lead status sync | No | Yes | Yes |
| Paid invoice → Google Ads revenue upload | No | No | Yes |
| Predictive LTV for recurring categories | No | No | Yes |
| Bidding ladder auto-promotion based on revenue | No | Suggestion | Auto-execute |
End-to-end flow
- Ad click captures gclid + UTM params at funnel page load
- Visitor submits lead form OR calls tracking number
- VibeAds creates lead record with gclid + UTM + funnel data
- VibeAds calls Jobber GraphQL API to find or create Client by email/phone
- VibeAds creates Jobber Request linked to the Client
- Stores
jobber_client_id+jobber_request_idon the lead - You see the lead in Jobber Requests, schedule + dispatch the job
- Tech completes the work, you mark the Job complete in Jobber
- Jobber fires
JOB_CLOSEDwebhook → VibeAds updates lead status - You invoice the customer in Jobber, they pay
- Jobber fires
INVOICE_UPDATEwebhook with paidStatus=PAID → VibeAds upsertsjobber_paid_invoicesrow upload-jobber-conversionsruns every 15 min, uploads the row to Google Ads as offline conversion to UPLOAD_CLICKS_REVENUE (Max only)- Smart Bidding learns which keywords drive paid customers
Predictive LTV for recurring categories
Google Ads offline conversion uploads must be within 90 days of the click (the GCLID window). Recurring-service businesses often see the first invoice 30 to 60 days after the click and subsequent invoices well past 90 days.
Predictive LTV solves this by uploading revenue × multiplier on the FIRST invoice when:
- Category is recurring (cleaning, pool, pest, landscaper)
- This is the first paid invoice for this lead
- GCLID is still within the 85-day buffer window
Multipliers per category:
| Category | Multiplier | Rationale |
|---|---|---|
| cleaner | 10x | Avg 10 invoices over 2 years |
| pool_services | 12x | Monthly + chemical upsells |
| pest_control | 8x | Quarterly + seasonal |
| landscaper | 6x | 4 to 6 visits/yr |
| hvac | 3x | Install + maintenance + repeat |
| christmas_lighting | 2x | Seasonal repeat |
| Others | 1x | One-time or emergency |
For nth-invoice-of-same-lead recurring invoices, the upload is skipped (the LTV was already uploaded on invoice 1). Per-invoice attribution is tracked in jobber_paid_invoices.conversion_value_type with values: actual, predicted_ltv, skipped_recurring, skipped_gclid_expired.
Webhook events
VibeAds subscribes to these Jobber webhook topics:
REQUEST_CREATE: confirms VibeAds' Request creation succeededJOB_CREATE: when you create a Job from a RequestJOB_UPDATE: status changes (scheduled, in progress)JOB_CLOSED: tech marked complete, triggers lead status updateINVOICE_CREATE: when an invoice is generatedINVOICE_UPDATE: status changes, including paidStatus=PAID
Signature verified via HMAC-SHA256 with X-Jobber-Hmac-SHA256 header using JOBBER_CLIENT_SECRET.
Double-counting protection
When a call comes in and gets qualified (score over 30), the upload-call-conversions cron normally uploads it to Google Ads as a UPLOAD_CLICKS_LEAD conversion. With Jobber connected, the call upload is SKIPPED if the lead also has jobber_job_id set. The eventual paid invoice will upload to UPLOAD_CLICKS_REVENUE, and we do not want Google to credit two conversions on the same gclid.
Net result: one gclid = one conversion. The conversion is either the call (if no Jobber Job) or the paid revenue (if the Job ran).