X Ads, twq Universal Tag and Conversions API
Server-side conversion tracking for X Ads (formerly Twitter Ads). Pair the Pixel ID with a Conversions API key. Optional hybrid mode loads the browser twq Universal Website Tag, deduplicated via conversion_id.
What you'll need
- An X Ads Manager account with Account Administrator or Ad Manager role.
- An existing Web Conversion event source (the X equivalent of a Pixel) attached to your domain.
- About 5 minutes.
1. Find the X Pixel ID
- Open X Ads Manager at
ads.x.com. - Tools → Conversion Tracking → Web.
- Pick the event source for this domain. Create one via Add new event source → Web if none exists.
- The Pixel ID (alphanumeric, ~5 to 6 characters, format like
ojxyz) is shown in the event source header. Copy it.
2. Generate a Conversions API key
- On the same event source detail page: Conversion API → Generate API key.
- X issues a long-lived bearer token, scoped to the event source. The token does not expire under normal operation but can be revoked manually.
- The key is shown ONCE. Copy it immediately. There is no retrieve-later mechanism, you would have to revoke and regenerate.
3. Paste credentials into Beaconry
WordPress Admin → Beaconry → Tracking → X Ads. Paste the Pixel ID, then click Connect with X. Beaconry runs an OAuth 1.0a flow against the Beaconry broker and saves the resulting connection, there is no API key to copy and paste.
The connection credentials are encrypted at rest with AES-256-GCM using your WordPress auth salts. Constants alternative, for running without the broker: BCNR_X_ADS_PIXEL_ID, BCNR_X_ADS_CONSUMER_KEY, BCNR_X_ADS_CONSUMER_SECRET, BCNR_X_ADS_ACCESS_TOKEN and BCNR_X_ADS_ACCESS_TOKEN_SECRET in wp-config.php.
4. Send the test event
Click Send X Ads test event. Beaconry fires a synchronous test conversion through the first configured slot (priority order: purchase, lead, signup, addtocart, pageview) and reports the response inline.
HTTP 200 with no error means credentials work. The event appears in Tools → Conversion Tracking → Health within ~30 minutes. X Ads does not have a real-time test view comparable to Meta's Test Events, the Health tab is what you watch.
About the click identifier
X appends ?twclid=... (the X Click ID) to every ad-click landing URL. Beaconry captures it on first page-load and persists it in the nl_ext cookie alongside fbclid, gclid, ttclid, msclkid and ScCid. Server-side events then carry twclid for accurate attribution. Without one, X falls back to hashed-PII matching plus IP and User-Agent.
Hybrid mode, twq Universal Tag
Server-side CAPI alone covers 100 percent of consenting visitors. Hybrid mode loads the browser twq Universal Website Tag (static.ads-twitter.com/uwt.js) in parallel so X sees the visitor's first-party cookies. Beaconry sends the same conversion_id from both sides as the third argument to twq('event', ..., {conversion_id: ...}), X deduplicates against double-counting.
Toggle in Beaconry → Tracking → X Ads → Hybrid mode. Better match-rate, slightly more bytes shipped to the visitor. Off by default.
What ships automatically
X Ads does not use vendor event-names like Meta or TikTok. Every conversion event is tied to a per-event base-36 event_id that you create in X Events Manager. Beaconry maps GA4 canonical events to nine slots, you paste the matching X event_id into each slot under Beaconry → Tracking → X Ads:
| Beaconry event | X Ads slot |
|---|---|
WooCommerce purchase | purchase (with order value + currency) |
WooCommerce add_to_cart | addtocart |
WooCommerce begin_checkout | begincheckout |
WooCommerce view_item | viewitem |
Site search search | search |
Form generate_lead, submit_application | lead |
Form contact | contact |
Account sign_up, subscribe | signup |
page_view | pageview |
Events without a configured slot event_id are silently skipped: only the slots you set in the Tracking tab actually dispatch. All payloads carry hashed PII (em, ph) when available, the captured twclid, plus IP and User-Agent.
Refund handling: refunds are not sent here. They go to GA4 only, since no ad channel has a real refund event.
Troubleshooting
- "401 invalid_credentials": API key revoked or generated under a different event source. Regenerate on the event source detail page and replace in Beaconry.
- "400 invalid_event_name": a custom event name was sent that does not match X's standard vocabulary. Beaconry only emits standard names from the table above. Custom NLData.track() events with non-standard names get dropped on the X channel.
- Health tab shows zero events received: outbound HTTP from your origin to
ads-api.x.commay be blocked. Check WAF or hosting-firewall outbound rules. Beaconry's Logs tab shows the full HTTP error. - Counter spikes after enabling hybrid mode: the third argument to
twq('event', ...)must be{conversion_id: ...}, not{eventID: ...}. X uses a different field name than Meta. Beaconry's hybrid loader sets the correct one automatically, but verify you don't have a parallel custom twq snippet with the wrong field.