X (Twitter) Pixel Setup, Conversion API, and Ads API | OpsBlu Docs

X (Twitter) Pixel Setup, Conversion API, and Ads API

Technical guide to X Pixel (twq) installation, conversion tracking, Conversion API, custom audiences, click ID tracking, and X Ads API integration.

How X Ad Tracking Works

X (formerly Twitter) uses a JavaScript pixel (twq) called the Website Tag to track user behavior on advertiser websites and attribute conversions back to ad interactions on the X platform. The tracking architecture operates as follows:

  1. A user sees or clicks an ad on X (promoted post, video ad, carousel, or conversation ad)
  2. On click, X's redirect server appends a twclid (Twitter Click ID) parameter to the destination URL
  3. The X Website Tag JavaScript loads on the advertiser's site, reads the twclid parameter, and stores it in a first-party cookie (_twclid)
  4. The tag fires a PageView event on each page load
  5. When the user completes a conversion action, the tag fires the corresponding event to analytics.twitter.com
  6. X matches the conversion to the original ad interaction via click ID (click-through) or cookie-based matching (view-through)

X also supports a server-side Conversion API (CAPI) that sends events directly from your server to X's measurement endpoint. CAPI can be used alongside or instead of the client-side pixel.

The twclid parameter is the primary attribution key. It is a long alphanumeric string appended as a query parameter on the landing page URL. For view-through attribution, X relies on a third-party cookie set during ad impression and the first-party _twclid cookie set by the Website Tag.


Installing the X Website Tag (Pixel)

Place the base tag code in the <head> of every page. Get your pixel ID from X Ads Manager under Tools > Events Manager > Add Event Source.

<!-- X (Twitter) Website Tag - Base Code -->
<script>
  !function(e,t,n,s,u,a){e.twq||(s=e.twq=function(){s.exe?s.exe.apply(s,arguments):s.queue.push(arguments);
  },s.version='1.1',s.queue=[],u=t.createElement(n),u.async=!0,u.src='https://static.ads-twitter.com/uwt.js',
  a=t.getElementsByTagName(n)[0],a.parentNode.insertBefore(u,a))}(window,document,'script');

  twq('config', 'YOUR_PIXEL_ID');
</script>

The twq('config', ...) call automatically fires a PageView event. No separate page view call is needed.

Verification

  1. Open DevTools > Network tab and filter for analytics.twitter.com or ads-twitter.com
  2. Confirm requests fire on page load
  3. In X Ads Manager, go to Events Manager and check the pixel status (should show "Active")
  4. Install the X Pixel Helper Chrome extension for real-time event debugging

Conversion Tracking

Fire conversion events by calling twq('event', 'event_id', { parameters }) after the base tag has loaded.

Creating Events in Ads Manager

Before firing events, create them in X Ads Manager:

  1. Navigate to Tools > Events Manager
  2. Click "Add Event"
  3. Choose the event type (Purchase, Lead, Add to Cart, etc.)
  4. X generates a unique event ID (e.g., tw-xxxxx-yyyyy)
  5. Use this event ID in your pixel code

Standard Events

<script>
  // Purchase with revenue
  twq('event', 'tw-xxxxx-purchase', {
    value: 119.99,
    currency: 'USD',
    num_items: 2,
    conversion_id: 'ORD-TW-12345',
    contents: [
      { content_id: 'SKU-001', content_name: 'Product A', content_price: 59.99, num_items: 1 },
      { content_id: 'SKU-002', content_name: 'Product B', content_price: 60.00, num_items: 1 }
    ]
  });

  // Lead form submission
  twq('event', 'tw-xxxxx-lead', {
    conversion_id: 'LEAD-67890'
  });

  // Sign up / Registration
  twq('event', 'tw-xxxxx-signup', {
    conversion_id: 'REG-11111'
  });

  // Add to cart
  twq('event', 'tw-xxxxx-addtocart', {
    value: 49.99,
    currency: 'USD',
    contents: [
      { content_id: 'SKU-003', content_name: 'Product C', content_price: 49.99, num_items: 1 }
    ]
  });

  // Initiate checkout
  twq('event', 'tw-xxxxx-checkout', {
    value: 149.99,
    currency: 'USD'
  });

  // Content view (specific page view)
  twq('event', 'tw-xxxxx-viewcontent', {
    content_id: 'page-pricing'
  });

  // Search
  twq('event', 'tw-xxxxx-search', {
    search_string: 'analytics platform'
  });

  // App install
  twq('event', 'tw-xxxxx-appinstall');

  // Download
  twq('event', 'tw-xxxxx-download');
</script>

Attribution Windows

Configure per-event in Events Manager:

  • Post-engagement (click): 1, 7, 14, or 30 days (default 30)
  • Post-view: 1, 7, 14, or 30 days (default 1)
  • Post-engagement includes clicks, retweets, replies, likes, and follows on promoted content

Audience and Retargeting

Website Activity Custom Audiences

Build audiences from Website Tag data:

  1. In Ads Manager, go to Tools > Audiences > Create Audience
  2. Select "Website Activity"
  3. Define rules:
    • All website visitors
    • Visitors to specific URLs (URL contains, equals)
    • Visitors who fired specific events
    • Visitors with specific event parameters (e.g., purchase value > $100)
  4. Set lookback window (1-90 days)
  5. Minimum audience size: 100 matched users

List-Based Custom Audiences

Upload first-party data for matching:

# Supported identifiers (CSV, one per row):
# - Email addresses (plain text or SHA-256 hashed)
# - X @handles
# - Mobile advertising IDs (IDFA/AAID)
# - X user IDs

# Minimum list size: 100 rows
# Maximum file size: 4GB

Upload in Ads Manager under Audiences > Upload List.

Follower Lookalike Audiences

Target users similar to the followers of specific X accounts:

  1. Create a new audience > Follower Lookalikes
  2. Enter X @handles (your own or competitors)
  3. X builds an audience of users with similar interests and behaviors
  4. No minimum follower count required

Conversation and Keyword Targeting

Target users based on their X activity:

  • Conversation topics: Predefined topic categories (e.g., "Technology > Artificial Intelligence")
  • Keywords: Target users who recently tweeted, searched, or engaged with posts containing specific keywords
  • Event targeting: Target users engaging with specific X events (conferences, sports, cultural moments)

Server-Side / Conversion API (CAPI)

X's Conversion API sends events from your server directly to X, improving attribution accuracy, especially when browsers block third-party cookies or the client-side pixel.

CAPI Setup

# Server-side conversion event via CAPI
curl -X POST 'https://ads-api.x.com/12/measurement/conversions/YOUR_PIXEL_ID' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: OAuth oauth_consumer_key="YOUR_CONSUMER_KEY",oauth_token="YOUR_ACCESS_TOKEN",oauth_signature_method="HMAC-SHA1",oauth_timestamp="...",oauth_nonce="...",oauth_version="1.0",oauth_signature="..."' \
  -d '{
    "conversions": [{
      "conversion_time": "2026-03-01T14:30:00Z",
      "event_id": "tw-xxxxx-purchase",
      "identifiers": [{
        "twclid": "twclid_value_from_url",
        "hashed_email": "a1b2c3d4e5f6..."
      }],
      "conversion_id": "ORD-CAPI-12345",
      "value": 199.99,
      "number_items": 3,
      "price_currency": "USD",
      "contents": [{
        "content_id": "SKU-001",
        "content_name": "Product A",
        "content_price": 66.66,
        "num_items": 1
      }]
    }]
  }'

CAPI Authentication

CAPI uses OAuth 1.0a. You need:

  • Consumer Key and Secret (from your X Developer App)
  • Access Token and Secret (generated for your Ads account)

Generate the OAuth signature per the OAuth 1.0a specification, or use an OAuth library:

# Python example using requests-oauthlib
from requests_oauthlib import OAuth1Session

session = OAuth1Session(
    client_key='YOUR_CONSUMER_KEY',
    client_secret='YOUR_CONSUMER_SECRET',
    resource_owner_key='YOUR_ACCESS_TOKEN',
    resource_owner_secret='YOUR_ACCESS_TOKEN_SECRET'
)

response = session.post(
    f'https://ads-api.x.com/12/measurement/conversions/YOUR_PIXEL_ID',
    json={
        'conversions': [{
            'conversion_time': '2026-03-01T14:30:00Z',
            'event_id': 'tw-xxxxx-purchase',
            'identifiers': [{
                'twclid': 'twclid_value',
                'hashed_email': 'a1b2c3d4...'
            }],
            'conversion_id': 'ORD-99',
            'value': 99.99,
            'price_currency': 'USD'
        }]
    }
)

Deduplication Between Pixel and CAPI

When using both the Website Tag and CAPI, X deduplicates events using conversion_id. Always include the same conversion_id in both the client-side twq('event', ...) call and the server-side CAPI request.


X Ads Management API

The X Ads API enables programmatic campaign management.

Campaign Management

# List campaigns
curl -X GET 'https://ads-api.x.com/12/accounts/YOUR_ACCOUNT_ID/campaigns' \
  -H 'Authorization: OAuth ...'

# Create a campaign
curl -X POST 'https://ads-api.x.com/12/accounts/YOUR_ACCOUNT_ID/campaigns' \
  -H 'Authorization: OAuth ...' \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "Q1 Retargeting",
    "funding_instrument_id": "YOUR_FUNDING_INSTRUMENT_ID",
    "daily_budget_amount_local_micro": 50000000,
    "start_time": "2026-04-01T00:00:00Z",
    "entity_status": "PAUSED"
  }'

Note: Budgets are specified in micros (1 USD = 1,000,000 micros).

Analytics and Reporting

# Get campaign stats
curl -X GET 'https://ads-api.x.com/12/stats/accounts/YOUR_ACCOUNT_ID?entity=CAMPAIGN&entity_ids=CAMPAIGN_ID&start_time=2026-03-01T00:00:00Z&end_time=2026-03-31T23:59:59Z&granularity=DAY&metric_groups=ENGAGEMENT,BILLING,CONVERSION_TAGS' \
  -H 'Authorization: OAuth ...'

API Rate Limits

  • 15 requests per 15-minute window for most endpoints
  • Analytics endpoints: 100 requests per 15 minutes
  • Rate limit headers included in every response: x-rate-limit, x-rate-limit-remaining, x-rate-limit-reset

Common Issues

twclid Not Persisting

  • Some CMS platforms, redirect chains, or URL shorteners strip the twclid parameter
  • SPAs using client-side routing often lose query parameters on navigation:
// Capture twclid before SPA router takes over
const params = new URLSearchParams(window.location.search);
const twclid = params.get('twclid');
if (twclid) {
  document.cookie = `_twclid=${twclid};max-age=${60*60*24*30};path=/;SameSite=Lax`;
}
  • UTM parameters and twclid can conflict with URL length limits on some servers. Ensure your server accepts URLs up to 2,048 characters

Conversion Counts Higher Than Expected

  • X counts post-engagement conversions, which include likes, retweets, replies, and follows. A user who liked your promoted post and later purchased gets attributed even without clicking through
  • Set post-engagement windows to shorter durations (1-7 days) if this inflates numbers
  • Use conversion_id on all events to prevent duplicate counting

CAPI OAuth Signature Errors

  • OAuth 1.0a signature generation is sensitive to parameter ordering and encoding
  • Use a library (requests-oauthlib for Python, oauth-1.0a for Node.js) rather than building signatures manually
  • Ensure your system clock is synchronized (NTP). OAuth signatures include a timestamp; clock skew over 5 minutes will fail

Website Tag Blocked by Browsers

  • Safari ITP limits first-party cookie lifetime to 7 days for cookies set via JavaScript
  • Firefox Enhanced Tracking Protection may block analytics.twitter.com
  • Use CAPI alongside the client-side tag to fill attribution gaps from browser restrictions

Content Security Policy

script-src: static.ads-twitter.com
img-src: analytics.twitter.com t.co
connect-src: analytics.twitter.com

Platform-Specific Considerations

Post-Engagement Attribution: X attributes conversions to engagements beyond clicks, including likes, retweets, replies, quote tweets, follows, and video views (3 seconds or 100%). This is broader than most platforms and can make X appear to drive more conversions than last-click models suggest. Understand this when comparing X performance to other channels.

twclid Length: The twclid parameter can be 100+ characters. Ensure database columns, cookie storage, and URL handling can accommodate the full value without truncation.

Click ID Auto-Append: X automatically appends twclid to all ad click-through URLs. You cannot disable this behavior. If your landing page URL already has parameters, twclid is appended with &. Ensure your server-side URL parsing handles multiple query parameters correctly.

Conversion API vs Pixel Priority: When both fire for the same event, X deduplicates using conversion_id. If no conversion_id is present, both events may be counted. Always include conversion_id in both the pixel and CAPI call.

X API Versioning: The Ads API uses versioned endpoints (e.g., /12/). Check the current version in the X Developer documentation. Deprecated versions are retired with 90-day notice. Pin your integration to a specific version and update proactively.

Promoted Post Engagements Are Free: Organic engagements on promoted posts (retweets of your ad, replies to your ad) are not charged. You pay only for the initial engagement that matched your bid objective. However, all downstream engagements are tracked for attribution.