The quote request from a three-room HDB in Queenstown lands on WhatsApp at 11.20. Your Google Ads dashboard already counted a conversion at 11.19. The van diary still shows a gap at 14.00. That 41-second gap is the whole problem: the click was real, the message was real, and the booked job never became an event the bidding system can learn from.
Singapore carpet and upholstery shops live on mixed demand. Sofa steam for condos in Tanjong Pagar, flood extract after a washing-machine leak in Bedok, mattress sanitise before a tenant handover in Punggol. Search CPC has climbed (global average search CPC was approximately $2.69 in 2024, per industry benchmarks, and has been rising ~10% annually), and a 20-30% slice of SEM budgets still leaks into irrelevant queries and misaligned pages. If you cannot tell a $180 sofa steam from a $1,200 water-damage job, Smart Bidding will cheerfully buy more of whatever looks cheap to convert.
This piece is the plumbing: UTM hygiene, Google Tag Manager, GA4, Enhanced Conversions, call and WhatsApp events, and a booked-job signal that matches how Singapore operators actually close work. You can run most of it yourself. You should also know it is ongoing work, not a one-off tag install.
Why Ads, WhatsApp, and the van diary never agree on the same sofa job
Most shops in Singapore still treat “lead” as a form thank-you page. The customer never used the form. They tapped Call, opened WhatsApp, or messaged the Google Business Profile. Mobile accounts for 63%+ of paid search clicks, and conversion rates on those sessions lag desktop by 30-40%. Your highest-intent traffic is the least likely to complete a desktop-style form.
Privacy and blockers wipe another 20%+ of conversion data. Smart Bidding then trains on a thinner, biased sample: people who allowed cookies and filled a form. Flood-extract pages with long copy convert in GA4. Sofa-steam ads with a sticky WhatsApp button do not. Spend slides toward the jobs that look efficient in last click, not the jobs that fill Saturday vans.
Last-click also double-counts. A Tampines homeowner sees a Performance Max asset, later Googles the brand, then WhatsApps. Google Ads, Meta, and the CRM each claim a win. Operators then say attribution is dead. Tactically, channel scorekeeping still matters. You just need a first-party event that means “we put a crew in the lift lobby,” not “someone typed a block and unit number.”
A Toa Payoh owner ran Search plus Performance Max into the homepage. Forms looked healthy at about 42 a month. The ops WhatsApp group told a different story: 11 booked visits, three of them sofa steam at $90-120, two of them tyre-shop spam. The mechanism was simple. The conversion tag fired on page load of /thank-you/, and the thank-you URL was reachable from the menu. Bidding learned to buy cheap clicks that never became diary slots.
If your paid landing pages still dump people on the homepage, stop. Dedicated offer pages for sofa steam, mattress, and water damage, with message match, beat another channel. If you want a partner on that handoff, HeyLead’s SEM programmes start from the event, not the click.
The four events a Singapore carpet firm should fire (and the ones to kill)
Kill vanity events. Scroll 50%, click-to-call icon without a connected call, and “button click” on WhatsApp that never opens a chat all inflate conversion volume and wreck quality. Keep four events, named so a dispatcher could read them.
Audit scorecard
-
qualified_enquiryFire once when the form includes postal code or HDB/con
qualified_enquiryFire once when the form includes postal code or HDB/condo estate, service type (sofa, carpet, mattress, flood extract), and a real SG mobile (8-digit after +65). Do not fire on empty “contact us.” Value this at your typical sofa-steam ticket if you must send a value, not at $1.
-
whatsapp_startFire when the wa
whatsapp_startFire when the wa.me link opens with a prefilled service string, not when the floating button is merely rendered. Pass the same UTM parameters you put on the ads. If two buttons exist (header and sticky), use one event name with a button_location parameter so you do not double-count.
-
call_connectedUse a call-tracking number on paid landers only
call_connectedUse a call-tracking number on paid landers only. Fire after a minimum talk time (45-60 seconds is enough to screen a tyre kiosk). Missed rings are not conversions. After-hours voicemail can be a separate event you never import to bidding.
-
job_bookedThis is the only event Smart Bidding should optimise toward on
job_bookedThis is the only event Smart Bidding should optimise toward once volume allows. Fire from the booking tool, Airtable, or a dispatcher toggle when a date, crew, and address exist. Include job_type and estimated_value in SGD. Import it to Google Ads as a secondary, then primary, conversion with a 7-day click window that matches how fast Singapore households book emergency extracts versus planned sofa steam.
Enhanced Conversions (the unified toggle) plus hashed email or phone from the form protect against that 20%+ signal loss. Home services accounts on Google Ads typically see 2-4x ROAS before optimising conversion quality, per LocaliQ 2024 benchmarks. You will not see that if the algorithm is training on form_submit from tyre enquiries. Performance Max can still drive bulk volume. It will not stay profitable if job_booked is missing.
Watch Core Web Vitals on the landers. As of December 2024 CrUX data, only about 51% of origins passed all three Core Web Vitals (source: web.dev/reports/cwv). A 4G session in a multi-storey car park will abandon a 4MB before-and-after gallery before WhatsApp ever opens. INP on the sticky chat button matters more than another testimonial slider.
Get a free marketing audit - we review your search, ads, and landing pages and send back what to fix first.
Get a free audit
A GTM and GA4 rebuild you can finish between clusters
You do not need a six-month stack. You need one container, one GA4 property, and discipline about what leaves the browser. Work in this order so you do not reset learning every afternoon.
Action checklist
- Inventory every paid URL for sofa steam, carpet, mattress, and water damage. If two ads share one URL, split them. Name pages in English a dispatcher would use, not “services-3.”
- Rebuild UTMs with a single convention: source, medium, campaign, content = job type, term = match type or asset group. Use the UTM builder so Ops and Ads do not invent parallel codes.
- In GTM, create the four events above. Block the old form_submit import in Google Ads before you add new ones, or you will train on both for weeks.
- Turn on Enhanced Conversions and pass phone. Singapore forms that hide the +65 country code still hash if you normalise to E.164 in GTM.
- Tag WhatsApp links with the same UTMs in the prefill text so a human can still see campaign when the CRM is late.
- Add a booked-job source: a simple “Booked” button in the shared ops sheet that hits a webhook, or a Zap from the calendar. Do not scrape the diary by hand on Fridays.
- In GA4, mark job_booked as a key event. Build an exploration: session campaign, job_type, booked vs enquiry. You will usually find water-damage ads funding sofa-steam bookings, or the reverse.
- Import only job_booked (and maybe call_connected) to bidding. Keep qualified_enquiry as an observation metric for eight weeks while volume builds.
- Check landers with session recordings so you see where HDB residents drop off the form when you ask for unit number before service type. HeyLead Insights is built for that post-click leak, not for guessing from bounce rate.
- Revisit negatives weekly, not daily. Constant structure changes reset learning. Twenty to thirty percent of SEM waste is still junk queries and weak pages, not “the algorithm.”
Free tools - try these yourself
A Bukit Merah shop had a Facebook plugin iframe wrapping the quote form. GTM never saw the submit. Google Ads showed 9 conversions in 11 days. The van did 37 paid jobs. They moved the form into the page, fired job_booked from the calendar, and tCPA stopped chasing ghost forms. One mechanism, not a new channel.
If landers still feel like a brochure, a short landing page pass aligned to ad copy will do more than another audience layer. Creative is your targeting on Meta. On Google, the event is your targeting. Both fail if the page asks for a life story before a 2-seater steam.
![]()
When Smart Bidding starves sofa steam because flood extract looks cheaper
Flood extract converts in fewer clicks when a unit is wet. Cost per enquiry looks beautiful. Margin per hour in a soaked living room is not always better than stacked sofa jobs in the same condo cluster. If you send one conversion value for every form, bidding will buy emergencies and skip planned upholstery.
Send estimated_value in SGD by job_type. A sofa steam at $180-250 and a water job at $800-1,500 should not share a $1 conversion. If volume is too low for value bidding, use two campaigns or two asset groups with separate primary events, not 14 campaigns you poke every morning. Fewer campaigns, broader targeting, clean conversion setup still beats 2024 audience stacking. Automated bidding does inflate spend when the signal is junk. It does not inflate spend when job_booked is the goal and values are honest.
Meta will look cheaper on in-platform CPA and worse in the diary. UGC that “dies after a few days” is real fatigue: CPMs rise before lead volume drops. Do not pause on a Tuesday dip at S$40 a day. Do pause an ad set whose WhatsApp starts never become job_booked after two creative cycles. Event Match Quality is a diagnostic, not a profit forecast.
AI Overviews now sit on a large share of searches and can cut CTR hard even when you still rank. Zero-click does not cancel local jobs. People still tap Call when the sofa smells. Your job is to capture that tap with a tracked number and a page that loads. Schema for LocalBusiness and FAQ helps machines; it does not replace the booked-job event.
Reporting should be weekly and ugly: spend, qualified_enquiry, whatsapp_start, call_connected, job_booked, SGD per booked job, by job_type. Monthly PDFs bury the Tuesday the thank-you tag broke. No one can guarantee a CPL before seeing your account, pages, and unit economics. Three to six months of clean signals is a serious programme. A week of “more leads” is a form tag on a menu link.
What marketing leaders are seeing
Here is how two clients described the shift after fixing their conversion setup:
“We imported every WhatsApp tap as a conversion. tCPA fell, then Saturday vans sat idle because half the chats were ‘how much for a car seat’ from a number we never should have bid on.” - James, founder of a carpet firm in Tampines
“The moment we delayed job_booked until the dispatcher confirmed a date, Performance Max stopped flooding us with $90 steam requests we could not route.” - Founder, carpet and upholstery firm in Singapore (composite, illustrative of several similar accounts)
![]()
FAQs
Should we optimise Google Ads to form fills while WhatsApp volume is still low?
Use qualified_enquiry as a temporary primary only if you cannot fire job_booked yet. Switch the moment you have a steady booked-job count. Training for eight weeks on forms you cannot fulfil is more expensive than a quieter fortnight.
Do we need a separate call-tracking number for organic?
Keep paid landers on a tracked number. Put the main company number on the Google Business Profile if you must, but you will undercount organic calls. Do not mix both numbers on the same paid URL.
What if most bookings happen after a site visit quote?
Fire a quote_scheduled event and a job_booked event. Import job_booked. Use quote_scheduled in GA4 to find campaigns that generate tyre-kickers in landed condos versus HDB owners who book on the first call.
Will Enhanced Conversions fix ad blockers?
They recover hashed first-party details when the user actually submitted them. They will not invent a conversion for a WhatsApp chat that never hit your server. Pair them with a server-side or webhook booked-job ping.
How often should we change conversion actions?
Rarely. Change when the definition of a good job changes, not when a week looks soft. Learning resets are how accounts stay in the expensive middle forever.
Putting it to work
Execution sprint
This week
- Pull 30-90 days of performance for Singapore carpet and upholstery (Search Console, ads, CRM, or call logs - whatever you have).
- Flag the top leak: wrong intent, weak page, slow response, or dirty conversion tracking.
- Ship one fix on the highest-traffic money path (page, campaign split, or response rule).
- Run the free tools below on that same URL or account and log the findings.
Free tools for this sprint
Next 30 days
- Expand the fix to the next one or two money paths only after the first one shows cleaner bookings.
- Align creative, keywords, or content with the same offer the page now states.
- Review booked outcomes weekly; cut anything that still only produces unqualified volume.
This week
-
Export 60 days of Google Ads conversions next to the van diary and tag each booked job as sofa, carpet, mattress, or water damage.
-
Disable any conversion that fires on thank-you page load or WhatsApp button render.
-
Standardise UTMs with the UTM link builder on every live ad.
-
Add job_type and estimated SGD value fields to the form, even if ops hates extra boxes.
-
Run the Core Web Vitals checker on the sofa-steam lander on mobile.
-
Watch five recorded sessions of form abandon on that lander.
Next 30 days
-
Ship job_booked from the calendar or ops sheet into GA4 and Google Ads as an observation conversion.
-
Promote job_booked to primary once you have enough volume to keep bidding stable.
-
Split water-damage and sofa-steam landers if they still share a URL.
-
Rebuild negatives from search terms that never produced a booked van.
-
Review SGD per booked job by campaign, not CPL by form.
Pull the last 60 days of leads by source and mark which ones became a dated crew visit. If the gap is the handoff between ad click, WhatsApp, and a booked-job event the algorithm never sees, HeyLead can own that tracking loop, the lander, and the bidding signal so your team is not reconciling three dashboards at 22:00. Chat with us on WhatsApp
Free marketing audit, or reach Martin directly:
Get a free audit Connect on WhatsApp · [email protected]