You paid for an X Ads (formerly Twitter Ads) flight in SGD, the creative actually stopped the scroll, and someone from Tampines or the CBD hit your landing page. Then finance asks which line item paid for the WhatsApp enquiry and the demo. If GA4 still shows that session as Direct or Unassigned, you do not have a tracking problem in theory. You have a broken handoff between twclid, Google Tag Manager, and the event you treat as a conversion.
This how-to finishes one job: a Singapore marketing lead can send X traffic to a dedicated page, persist the click ID, fire a GA4 conversion that matches the offer (form submit, calendar book, PayNow checkout start), and still send a conversion back to X Ads without inventing a second source of truth. Done looks like this: a test click from your own X campaign lands in GA4 with source / medium you defined, the conversion event has a value in SGD, and X Ads Manager shows the same event within a day, not a week later after someone reverse-engineered a spreadsheet.
X is not Meta. Spend is usually smaller, CPMs move with news cycles, and the Singapore audience you care about often hops WhatsApp after the click. In most SG demand-gen accounts we see, Google Ads leads on ROAS, Meta trails it, and X has to prove pipeline to earn budget. X only earns a demand-gen slice when you can prove booked work, not impressions. The rest of this piece is the setup, not a channel strategy lecture.
Accounts, consent, and the Singapore offer you lock before GTM
Skip this and the steps fail in boring ways: duplicate pixels, GST-inclusive values that never match finance, or a conversion that fires on page view because nobody named the real action. You need Admin on the X Ads account, Editor on the GA4 property that actually reports to leadership (not a sandbox), and Publish rights in the GTM web container on the live domain. If legal owns the consent banner, get them in the room before you fire marketing tags in Singapore. PDPA is not a footnote when you persist click IDs.
Decide the conversion before you open GTM. For most B2B teams here that is a qualified form, a Calendly or HubSpot meeting, or a WhatsApp click that you only count if it happens after 8 seconds on a campaign landing page. Do not count homepage views. Do not count Instant Form-style completions if you are not using X lead forms; most SG demand-gen accounts send people to a page. If you also run Meta, keep the event names parallel so a CMO can read one glossary, but do not reuse Meta’s pixel as a proxy for X. They are different IDs.
Have the landing URL, UTM convention, and currency locked. Use SGD everywhere. If the form posts a deal size, pass a numeric value without the dollar sign. GST at 9% belongs in finance reports, not in the GA4 event value unless your CRM already stores GST-inclusive totals and you document that. You also need a staging or preview path that does not pollute production conversions. Preview in GTM is not optional when you are wiring twclid.
If the page is slow, stop. May 2026 CrUX still shows only 55.9% of origins passing all three Core Web Vitals. A heavy chat widget plus three pixels will bury Interaction to Next Paint on mobile, and mobile already converts worse than desktop even when it takes most of the clicks. Check the URL with a Core Web Vitals checker before you add another script. If the page is the leak, HeyLead Insights will show scroll drop and form abandon after the X click; fix that before you celebrate a clean tag.
When paid social and measurement sit in different vendors, ask who owns GTM Publish. If they say they just send X traffic to the homepage, you already know the conversion rate will lie. Dedicated pages aligned to the ad copy are the prerequisite, not a CRO nicety. If you need a partner on the measurement side rather than another creative round, the closest working hub is HeyLead’s paid ads conversion tracking work in Singapore.
Get a free marketing audit - we review your search, ads, and landing pages and send back what to fix first.
Get a free audit
Build the X click path into GA4 with GTM, then close the loop to X
The numbered procedure is the article. Do it in this order. Do not fire the X base pixel from the HTML head and again from GTM. Pick GTM as the only injector unless your CMS already injects the pixel and you are only adding events.
How-to
-
In X Ads Manager, open Events Manager (or Conversion tracking) and create a web conversion with a clear name: generate_lead, schedule, or purchase. Set the counting window you actually believe (7-day click is enough for most SG B2B; 30-day only if sales cycle is documented). Copy the pixel ID and the event ID. Do not enable automatic page-view conversions.
-
Standardise UTMs for every X ad. Campaign = the X campaign name, source = x, medium = paid_social, content = creative ID. Build them with a UTM link builder so nobody types twitter versus x versus TwitterAds. Append the destination URL in Ads Manager. Confirm the live ad URL still includes twclid when you click it from a logged-out phone on mobile data, not only from office wifi.
-
In GTM, create a 1st Party Cookie variable (or a Custom JavaScript variable that reads the URL then the cookie) for twclid. Capture it on landing and write it to a first-party cookie named x_twclid. Set Max-Age to match your X attribution window in seconds (604800 for 7-day). Never overwrite a later organic visit’s cookie with a blank value; if the parameter is missing, leave the existing cookie alone. If the landing page is on a different subdomain from the form, set SameSite=None; Secure so the cookie survives the cross-site redirect.
-
Install the X base pixel once via a Custom HTML or community template tag, Consent Initialization respecting your CMP, All Pages. Fire only after analytics_storage and ad_storage (or your CMP’s equivalent) are granted. Singapore visitors who decline ads should still get a cookieless GA4 page_view if that is your policy, but they should not get the X pixel.
-
Create a GA4 Configuration tag if you do not already have one, then a GA4 Event tag for the same business action you defined in step 1. Event name must match GA4 exactly (snake_case). Parameters: value (SGD number), currency = SGD, and a custom param campaign_id if you have it. Trigger on the actual success state: thank-you URL, dataLayer push form_submit, or button ID. Never trigger on the form page itself.
-
Mark that GA4 event as a Key event. In Admin, toggle it as a conversion. If you use Google Ads as well, do not import this X event into Google Ads as a conversion or you will double-count pipeline when both channels touched the same person. Keep X’s conversion in X, GA4 as the cross-channel ledger.
-
Add a second GTM tag that fires the matching X conversion event on the same trigger as the GA4 event. Pass value and currency. Pass email or phone only if the user typed them on your form and your privacy policy allows hashed matching. Empty PII is better than fake PII.
-
Push a dataLayer event from the site when the CRM or form tool confirms success. GTM listening to a CSS click will fire on validation errors. If HubSpot, Webflow, or your custom form cannot push dataLayer, use the thank-you path as a fallback and block it from firing on refresh with a session cookie.
-
Preview in GTM. Click your X ad (or a QA URL that includes a dummy twclid). Confirm: X base pixel once, GA4 config once, conversion event once, cookie set. Then publish to the live container, not a copy someone forgot on a subdomain.
-
In GA4 DebugView, watch the test user. In X Events Manager, confirm the test conversion. Wait for the 24-hour reporting lag before you judge volume. Compare 7 days of X reported conversions to GA4 key events filtered to session source x / paid_social. They will not match 1:1 (view-through, ad blockers, iOS). You want them in the same order of magnitude, not identical.
-
Create an exploration in GA4: session source/medium, landing page, key event, event value. Exclude internal IPs. If Unassigned still eats X sessions, your UTMs were stripped by a redirect. Fix the redirect before you change bidding.
-
Document the event dictionary in one page your CMO can read: event name, trigger, SGD value rule, consent behaviour, and who can publish GTM. That document is the conversion setup. The tags are just the implementation.
Free tools - try these yourself
Schema on the thank-you page will not fix twclid, but a validator pass keeps FAQ and breadcrumb markup from throwing console noise that junior analysts blame on GTM. Same for a clean H1 and meta description on the landing URL the ad promised. Creative is targeting on X the same way it is on Meta; the page has to finish the sentence the tweet started.
If Meta still takes most of the social budget, that is fine. Keep X’s events named like Meta’s so weekly reporting does not invent a third glossary. For the paid social operating model around creative fatigue and landing handoff, use the Meta Ads playbook as the sibling, not a substitute pixel.

Where Singapore X-to-GA4 setups break after you hit Publish
Duplicate base pixels are the first stall. A theme injects the X snippet, GTM injects it again, and Events Manager shows two page views per session. X then undercounts conversions relative to GA4 because the event fires on the wrong instance. Remove the theme copy. One injector.
The second stall is counting the wrong thing. Teams mark generate_lead on the landing page view because “GTM Preview showed the pixel.” That inflates X’s CPA in a flattering direction for about 11 days, until sales says the CRM is empty. Tie the event to success. If WhatsApp is the CTA, fire only after a click on the wa.me link plus a minimum time on page, or you will train X to hunt rage-clickers in Woodlands at 1 a.m. In one B2B SaaS account we audited, X reported 41 conversions while GA4 showed 9 because the pixel fired on the LP view; sales had four meetings. Killing the page-view trigger made CPA look worse for a week, which was the first honest week.
Redirects strip query parameters. A www to apex hop, an HTTP to HTTPS hop, or a marketing site that routes /lp/x-q2 to /lp/x-q2/ with a trailing slash can drop twclid and UTMs. Look at the network waterfall on a real click. If the first 302 drops the query, fix the server. GTM cannot recover an ID it never received. In one professional services account, UTMs said twitter / cpc from a freelancer template and everything landed in Unassigned after the site moved to HTTPS; twclid was never on the thank-you URL. One redirect rule fixed more than a month of “X doesn’t work here.”
Consent mode without a real CMP is the fourth break. You fire everything, then legal turns on a banner that blocks tags on first load. First-touch X sessions vanish. Configure tags to wait for consent, and test as a new user in Incognito with ads declined. You should see GA4 (if allowed) and no X pixel.
Value mismatches poison any later bid automation. Someone sends value: “150” in one tag and “S$150.00” in another. GA4 drops the string. X ignores it. Use a number. If the form has no revenue, send 1 as a count, not a fantasy ACV.
Ad blockers and iOS will still hide 20% or more of conversion data. Do not “fix” that by lowering the GA4 threshold until the dashboards match. Report both numbers and the gap. Last-click already double-counts people who saw Search and X. Your job is a clean event, not a fake reconciliation to 100%.
INP from third-party scripts is the quiet conversion killer after Publish. Chat, heatmaps, three pixels, and a tag manager on a condo-developer landing page will feel fine on office fibre and die on a Punggol commute. If the form is abandoned at the same field every time, that is a page problem, not an X bidding problem.

FAQs
Should we use X’s conversion API instead of only the browser pixel?
If you have server-side GTM or a CRM webhook and a real volume of form fills, yes, as a complement. Start with a clean browser event. A broken CAPI on top of a duplicate pixel makes the gap worse. Server-side is how you claw back some of the blocked traffic, not how you skip step 1.
Why don’t X Ads conversions match GA4 in Singapore?
Different windows, view-through in X, consent, ad blockers, and iOS. You want similar rank order by campaign, not identical counts. If they diverge by 5x, you have a tag or redirect bug, not a philosophical attribution debate.
Can we import X conversions into Google Ads?
Don’t, if the same user also clicked Search. You’ll double-count. Keep GA4 as the cross-channel view and each ad platform on its own optimisation event.
Do we need a separate GA4 property for X?
No. One property, one GTM container, named events, UTMs that don’t collide with Meta. Extra properties just hide the journey from X to Search to close.
Is X worth tracking if spend is small versus Meta?
Only if you will act on the number. A S$2,000 test with no event is theatre. A S$2,000 test with a key event and a landing page is a decision. If you will not pause or scale on that signal, don’t buy the clicks.
Putting it to work
Execution sprint
This week
- Pull 30-90 days of performance for how to track x ads conversions in ga4 and gtm (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 last 14 days of X spend in SGD next to GA4 key events for source x / paid_social. Note the gap.
-
Confirm a single X base pixel in GTM Preview on your live landing URL.
-
Capture twclid in a first-party cookie and stop redirects from stripping query strings.
-
Move the conversion trigger from page view to thank-you or dataLayer success.
-
Rebuild UTMs with the UTM link builder so source and medium never vary by freelancer.
-
Run the landing URL through the Core Web Vitals checker on mobile.
Next 30 days
-
Align event names with Meta so weekly reporting uses one glossary.
-
Add event value in SGD only where CRM has a real number.
-
Compare X Manager to GA4 weekly; investigate 5x gaps, ignore 20% gaps.
-
Kill homepage destinations for X; keep one offer page per campaign.
-
Write the one-page event dictionary and restrict GTM Publish.
Pull your last 14 days of X clicks against GA4 key events before you touch bidding. If the click ID dies on the first redirect, no amount of creative testing will save the CPA. HeyLead can own the GTM and GA4 wiring for X Ads conversions in Singapore, including twclid persistence, consent-aware tags, and the event that finance will actually trust. Chat with us on WhatsApp
Free marketing audit, or reach Martin directly:
Get a free audit Connect on WhatsApp · [email protected]