Integration and Conversion Tracking Guide

Complete guide for integrating Simple TDS with your traffic sources and affiliate networks, including all conversion tracking methods.

Traffic URL Structure

Base URL Format

All traffic to Simple TDS campaigns follows this URL pattern:

https://yourdomain.com/{campaign_token}/

Example:

https://track.example.com/abc123def456/

Where:

Passing Parameters to Target URL

You can pass any query parameters through the traffic URL, and they will be automatically forwarded to the target URL along with the system-generated click_id.

Example:

https://track.example.com/abc123def456/?utm_source=facebook&utm_campaign=summer2024&sub1=adset123

All parameters (utm_source, utm_campaign, sub1) will be passed to the final destination URL.

Available Macros in Target URLs

When configuring target URLs in Simple TDS, you can use macros that will be dynamically replaced with actual values:

System Macros

Macro Description Example Value
{click_id} Unique click identifier (for conversion tracking) a3f8b2c1d4e5f6g7h8i9j0k1l2m3n4o5
{timestamp} Current Unix timestamp in milliseconds 1704067200000
{random} Random number (0-999999) 742839
{date} Current date (YYYY-MM-DD format) 2025-01-01
{time} Current time (HH:MM:SS format) 14:30:45
{CLICK_ID} Unique click identifier (alias for {click_id}, for advertiser URLs) a3f8b2c1d4e5f6g7h8i9j0k1l2m3n4o5
{SOURCES} Referrer domain β€” traffic source domain (empty if direct) facebook.com
{GEO} Visitor's country code (ISO 3166-1 alpha-2) US
{CAMPAIGN_ID} Current campaign numeric ID 42
{referrer} Full referrer URL (empty string if direct traffic) https://facebook.com/ads/123

Query Parameter Macros

Any parameter passed in the traffic URL can be used as a macro:

Macro Description Example
{utm_source} Traffic source from URL From ?utm_source=facebook β†’ facebook
{utm_campaign} Campaign name from URL From ?utm_campaign=summer β†’ summer
{sub1} - {sub9} Custom sub-IDs From ?sub1=123 β†’ 123

Example Target URL with Macros:

https://offer.example.com/lp?source={utm_source}&campaign={utm_campaign}&clickid={click_id}&ts={timestamp}

Result (when traffic arrives with ?utm_source=google&utm_campaign=promo):

https://offer.example.com/lp?source=google&campaign=promo&clickid=a3f8b2c1d4e5f6g7h8i9j0k1l2m3n4o5&ts=1704067200000

Conversion Tracking Methods

Simple TDS supports three conversion tracking methods. All methods require a click_id which is automatically added to target URLs.

Method 1: Postback URL (Server-to-Server)

Recommended for: Affiliate networks, direct offers with server-side tracking

URL Format

GET https://yourdomain.com/c/postback

Parameters

Parameter Required Type Description
click_id Yes* String Unique click identifier (UUID format)
campaign_id Yes* Integer Campaign ID (if click_id unavailable)
conversion_type No String Type of conversion (default: confirmed)
conversion_value No Number Revenue/payout amount
external_id No String External transaction/conversion ID

*Either click_id or campaign_id is required. Using click_id is strongly recommended for accurate tracking.

Example Postback URLs

Basic conversion:

https://track.example.com/c/postback?click_id={clickid}

Conversion with revenue:

https://track.example.com/c/postback?click_id={clickid}&conversion_value=25.50

Conversion with type and external ID:

https://track.example.com/c/postback?click_id={clickid}&conversion_type=sale&conversion_value=99.99&external_id=ORDER-12345

Common Affiliate Networks Integration

MaxBounty:

https://track.example.com/c/postback?click_id=[SUBID]&conversion_value=[PAYOUT]

CrakRevenue:

https://track.example.com/c/postback?click_id=[s1]&conversion_value=[payout]&external_id=[transaction_id]

ClickDealer:

https://track.example.com/c/postback?click_id={clickid}&conversion_value={payout}

CPALead:

https://track.example.com/c/postback?click_id=[subid]&conversion_value=[payout]

Note: Replace the macro placeholders (e.g., [SUBID], {clickid}) with the actual macros used by your affiliate network.

Response

Success:

{
  "success": true,
  "conversion_id": 12345
}

Updated existing conversion:

{
  "success": true,
  "conversion_id": 12345,
  "updated": true
}

Error:

{
  "success": false,
  "message": "Click not found"
}

Method 2: Pixel Tracking (Image)

Recommended for: Landing pages, thank-you pages, confirmation pages

URL Format

<img src="https://yourdomain.com/c/pixel.gif?click_id={clickid}" width="1" height="1" />

Parameters

Same as postback method, but supports legacy parameter names:

Parameter Alias Type Description
click_id - String Unique click identifier
conversion_value amount Number Revenue amount
conversion_type status String Conversion status
external_id transaction_id String External ID

Implementation Example

Basic pixel (1x1 transparent image):

<!DOCTYPE html>
<html>
<head>
    <title>Thank You!</title>
</head>
<body>
    <h1>Thank you for your purchase!</h1>
    <p>Your order has been confirmed.</p>

    <!-- Conversion tracking pixel -->
    <img src="https://track.example.com/c/pixel.gif?click_id=a3f8b2c1d4e5f6g7h8i9j0k1l2m3n4o5"
         width="1" height="1" style="display:none;" />
</body>
</html>

Pixel with revenue tracking:

<img src="https://track.example.com/c/pixel.gif?click_id=a3f8b2c1d4e5f6g7h8i9j0k1l2m3n4o5&conversion_value=49.99&conversion_type=sale"
     width="1" height="1" style="display:none;" />

When to Use Pixel Tracking

Advantages:

Limitations:

Method 3: JavaScript Tracker

Recommended for: Advanced tracking, dynamic conversion values, client-side applications

URL Format

<script src="https://yourdomain.com/c/js?click_id={clickid}"></script>

Basic Implementation

<!DOCTYPE html>
<html>
<head>
    <title>Confirmation</title>
</head>
<body>
    <h1>Thank you!</h1>

    <!-- JavaScript conversion tracker -->
    <script>
        var clickId = 'a3f8b2c1d4e5f6g7h8i9j0k1l2m3n4o5'; // Retrieved from URL or cookie
        var conversionValue = 29.99;
        var conversionType = 'sale';

        var script = document.createElement('script');
        script.src = 'https://track.example.com/c/js?click_id=' + clickId +
                     '&conversion_value=' + conversionValue +
                     '&conversion_type=' + conversionType;
        document.head.appendChild(script);
    </script>
</body>
</html>

Advanced Usage: Dynamic Conversion Tracking

<script>
// Get click_id from URL parameter
function getClickId() {
    const urlParams = new URLSearchParams(window.location.search);
    return urlParams.get('click_id');
}

// Track conversion with dynamic value
function trackConversion(value, type, externalId) {
    const clickId = getClickId();
    if (!clickId) {
        console.error('Click ID not found');
        return;
    }

    const params = new URLSearchParams({
        click_id: clickId,
        conversion_value: value,
        conversion_type: type || 'confirmed',
        external_id: externalId || ''
    });

    const script = document.createElement('script');
    script.src = 'https://track.example.com/c/js?' + params.toString();
    document.head.appendChild(script);
}

// Example: Track on form submission
document.getElementById('purchaseForm').addEventListener('submit', function(e) {
    e.preventDefault();

    const amount = document.getElementById('amount').value;
    const orderId = document.getElementById('orderId').value;

    trackConversion(amount, 'sale', orderId);

    // Continue with form submission
    this.submit();
});
</script>

When to Use JavaScript Tracker

Click ID Handling

What is Click ID?

The click_id is a unique identifier (UUID v4 format) automatically generated by Simple TDS for each click. It's essential for conversion tracking.

Example click_id:

a3f8b2c1d4e5f6g7h8i9j0k1l2m3n4o5

Why Click ID is Important

  1. Unique identification: Links conversions to specific clicks
  2. Accurate attribution: Tracks which campaign/flow/target generated the conversion
  3. Prevents duplicates: Ensures conversions aren't counted multiple times
  4. Statistics: Enables detailed conversion reporting

Passing Click ID to Landing Pages

Simple TDS automatically adds click_id to target URLs. You don't need to do anything if you're using the default behavior.

Traffic flow:

User clicks β†’ https://track.example.com/abc123def456/?utm_source=facebook
              ↓
Simple TDS processes filters and selects target
              ↓
Redirect to β†’ https://landing.example.com/?click_id=a3f8b2c1d4&utm_source=facebook

If you use macros in target URL configuration:

Target URL: https://landing.example.com/?id={click_id}&source={utm_source}
Result:     https://landing.example.com/?id=a3f8b2c1d4&source=facebook

Storing Click ID for Conversion Tracking

Method 1: URL Parameter (Recommended)

Store the click_id from the URL and use it later for conversion tracking.

JavaScript example:

// Get click_id from URL
function getClickId() {
    const urlParams = new URLSearchParams(window.location.search);
    return urlParams.get('click_id');
}

// Store in sessionStorage
const clickId = getClickId();
if (clickId) {
    sessionStorage.setItem('tds_click_id', clickId);
}

// Later: Retrieve for conversion tracking
const storedClickId = sessionStorage.getItem('tds_click_id');

Method 2: Cookie Storage

Store in a cookie for multi-page tracking.

JavaScript example:

// Set cookie with click_id
function setClickIdCookie(clickId) {
    const expiryDays = 30;
    const date = new Date();
    date.setTime(date.getTime() + (expiryDays * 24 * 60 * 60 * 1000));
    const expires = "expires=" + date.toUTCString();
    document.cookie = "tds_click_id=" + clickId + ";" + expires + ";path=/";
}

// Get click_id from URL and store in cookie
const urlParams = new URLSearchParams(window.location.search);
const clickId = urlParams.get('click_id');
if (clickId) {
    setClickIdCookie(clickId);
}

// Retrieve from cookie
function getClickIdFromCookie() {
    const name = "tds_click_id=";
    const decodedCookie = decodeURIComponent(document.cookie);
    const ca = decodedCookie.split(';');
    for (let i = 0; i < ca.length; i++) {
        let c = ca[i];
        while (c.charAt(0) == ' ') {
            c = c.substring(1);
        }
        if (c.indexOf(name) == 0) {
            return c.substring(name.length, c.length);
        }
    }
    return null;
}

Method 3: Hidden Form Field

Pass click_id through forms.

HTML example:

<form id="signupForm" action="/process" method="POST">
    <input type="text" name="email" placeholder="Email" required>
    <input type="password" name="password" placeholder="Password" required>

    <!-- Hidden field with click_id -->
    <input type="hidden" name="click_id" id="clickIdField" value="">

    <button type="submit">Sign Up</button>
</form>

<script>
// Populate hidden field with click_id from URL
const urlParams = new URLSearchParams(window.location.search);
const clickId = urlParams.get('click_id');
if (clickId) {
    document.getElementById('clickIdField').value = clickId;
}
</script>

Common Integration Scenarios

Scenario 1: Direct Linking (No Landing Page)

Setup:

Traffic source β†’ Simple TDS β†’ Affiliate offer

Configuration:

  1. Create campaign in Simple TDS
  2. Add flow with appropriate filters
  3. Add target with affiliate offer URL

Target URL example:

https://affiliate-network.com/offer?affid=12345&clickid={click_id}

Postback URL (configure in affiliate network):

https://track.example.com/c/postback?click_id=[SUBID]&conversion_value=[PAYOUT]

Replace [SUBID] and [PAYOUT] with the network's macros.

Scenario 2: Landing Page Setup

Setup:

Traffic source β†’ Simple TDS β†’ Your landing page β†’ Offer

Configuration:

Create campaign and flow in Simple TDS

Configure target URL to your landing page:

https://yourlanding.com/?offer_id=123&click_id={click_id}&source={utm_source}

On your landing page, store the click_id:

<script>
// Store click_id from URL
const urlParams = new URLSearchParams(window.location.search);
const clickId = urlParams.get('click_id');
if (clickId) {
    sessionStorage.setItem('tds_click_id', clickId);
}
</script>

When user submits form, track conversion:

<script>
document.getElementById('leadForm').addEventListener('submit', function(e) {
    e.preventDefault();

    const clickId = sessionStorage.getItem('tds_click_id');
    if (clickId) {
        // Track conversion with pixel
        const pixel = new Image();
        pixel.src = 'https://track.example.com/c/pixel.gif?click_id=' + clickId +
                    '&conversion_type=lead';
        pixel.onload = function() {
            // Redirect to offer after tracking
            window.location.href = 'https://offer.example.com/?subid=' + clickId;
        };
    }
});
</script>

Scenario 3: Multi-Step Funnel

Setup:

Traffic β†’ Simple TDS β†’ Landing page β†’ Pre-lander β†’ Offer

Implementation:

Landing page (step 1):
<!-- Store click_id in sessionStorage -->
<script>
const urlParams = new URLSearchParams(window.location.search);
const clickId = urlParams.get('click_id');
if (clickId) {
    sessionStorage.setItem('tds_click_id', clickId);
}

// Pass to next step
function goToNextStep() {
    const clickId = sessionStorage.getItem('tds_click_id');
    window.location.href = '/prelander?click_id=' + clickId;
}
</script>
Pre-lander (step 2):
<!-- Retrieve and store click_id -->
<script>
const urlParams = new URLSearchParams(window.location.search);
let clickId = urlParams.get('click_id');

// Fallback to sessionStorage if not in URL
if (!clickId) {
    clickId = sessionStorage.getItem('tds_click_id');
} else {
    sessionStorage.setItem('tds_click_id', clickId);
}

function goToOffer() {
    const clickId = sessionStorage.getItem('tds_click_id');
    window.location.href = 'https://offer.example.com/?subid=' + clickId;
}
</script>
Thank-you page (after conversion):
<!-- Track conversion -->
<script>
const clickId = sessionStorage.getItem('tds_click_id');
if (clickId) {
    const pixel = new Image();
    pixel.src = 'https://track.example.com/c/pixel.gif?click_id=' + clickId +
                '&conversion_value=25.00&conversion_type=sale';
}
</script>

Scenario 4: Affiliate Network Integration

Setup:

Configure postback in affiliate network to track conversions back to Simple TDS

Steps:

Get your click_id to the affiliate network:

In Simple TDS target URL:

https://network.com/click?affid=12345&subid={click_id}

Configure postback in affiliate network:

Most networks have a "Postback URL" or "Conversion Callback" setting. Configure it as:

https://track.example.com/c/postback?click_id=[SUBID]&conversion_value=[PAYOUT]&conversion_type=[STATUS]&external_id=[TRANSACTION_ID]

Replace the placeholders with network-specific macros:

Network SubID Macro Payout Macro Status Macro
MaxBounty [SUBID] [PAYOUT] [STATUS]
CrakRevenue [s1] [payout] [status]
ClickDealer {clickid} {payout} {status}
A4D {s1} {payout} N/A

Test the integration:

Most networks provide a test postback feature. Use it to verify conversions are tracked correctly.

Scenario 5: Traffic Source S2S Postback (RTB Networks)

Use case: You buy traffic from an RTB network (RTB Panda, ClickBaza, PropellerAds, etc.) that requires a conversion postback to their system when an offer conversion fires.

Full Data Flow

RTB Network ──[visitor + ?clickid=XYZ]──→ TDS Campaign URL
                                                  β”‚
                                          TDS stores XYZ in click.query_params
                                                  β”‚
                                          TDS redirects to offer
                                                  β”‚
Offer ──[GET /c/postback?click_id={tds_uuid}]──→ TDS
                                                  β”‚
TDS records conversion AND fires upstream S2S:
TDS ──[GET https://postback.rtbpanda.com/postback?clickid=XYZ&payout=25.00&status=confirmed]──→ RTB Network

Step 1: Get the traffic source's postback URL template

In the RTB Panda / ClickBaza dashboard, find the "S2S Postback" section. The template looks like:

https://postback.rtbpanda.com/postback?clickid={CLICK_ID}&payout={PAYOUT}&status={STATUS}

Step 2: Translate macro names to TDS macros

Replace their placeholders with the exact query parameter name the source uses when sending traffic:

Traffic SourceTheir click ID paramTDS macro to use
RTB Pandaclickid{clickid}
ClickBazaclickid{clickid}
PropellerAdsclick_id{click_id}
TrafficStarsts_click_id{ts_click_id}

For payout and status, use TDS system macros: {payout}, {status}.

Result for RTB Panda:

https://postback.rtbpanda.com/postback?clickid={clickid}&payout={payout}&status={status}

Step 3: Paste the URL into Campaign Settings β†’ S2S Postback URL

Step 4: Set up your campaign URL in the RTB network

In the network's creative settings, set the destination URL to your TDS campaign URL with the source's click ID macro:

https://yourdomain.com/{campaign_token}/?clickid={CLICK_ID}

Replace {CLICK_ID} with the network's actual macro (RTB Panda uses {CLICK_ID}).

Step 5: Test the full chain

  1. Open a test traffic URL: https://yourdomain.com/{campaign_token}/?clickid=test123
  2. Note the TDS click_id (UUID) from click logs
  3. Fire a test conversion: GET /c/postback?click_id={tds_uuid}&conversion_value=10&conversion_type=lead
  4. Check server logs for [S2S] Postback fired line
  5. Verify the conversion appeared in the RTB network's stats

Troubleshooting

Conversion Not Tracking

Problem: Postback sent but no conversion recorded

Possible causes:

1. Incorrect click_id format
  • Verify the click_id is a valid UUID
  • Check for extra characters or truncation

Solution: Test with a known click_id from your click reports

2. Click_id not found in database
  • The click may be too old (database retention policy)
  • Click was never recorded (bot traffic filtered)

Solution: Check click reports to verify the click_id exists

3. Postback URL misconfigured
  • Wrong domain
  • Missing required parameters

Solution: Test postback manually:

curl "https://track.example.com/c/postback?click_id=YOUR_CLICK_ID&conversion_value=10"

Expected response:

{"success": true, "conversion_id": 12345}
4. Network firewall blocking postback
  • Some servers block outbound connections

Solution: Check server logs, whitelist Simple TDS IP if needed

Problem: Pixel not loading

Possible causes:

1. Ad blocker

Many ad blockers block tracking pixels

Solution: Use server-to-server postback for reliable tracking

2. HTTPS/HTTP mixed content

Loading HTTP pixel on HTTPS page

Solution: Always use HTTPS for pixel URLs

3. JavaScript error preventing pixel load

Solution: Check browser console for errors

Click ID Missing

Problem: click_id not present in target URL

Possible causes:

1. Macro not configured correctly

Using wrong macro syntax

Solution: Use {click_id} macro in target URL or rely on automatic parameter passing

2. Target URL already has click_id parameter

Simple TDS won't add duplicate parameters

Solution: Remove click_id from target URL template, let Simple TDS add it

3. Parameter being stripped by redirect

Intermediate redirects may remove parameters

Solution: Test the full redirect chain, ensure all redirects preserve query parameters

Problem: click_id lost during multi-page flow

Solution:

Use sessionStorage or cookies to persist click_id across pages:

// Store on first page
const urlParams = new URLSearchParams(window.location.search);
const clickId = urlParams.get('click_id');
if (clickId) {
    sessionStorage.setItem('tds_click_id', clickId);
}

// Retrieve on any page
const storedClickId = sessionStorage.getItem('tds_click_id');

Common Errors

Error: "Either click_id or campaign_id is required"

Cause: Postback sent without required parameters

Solution: Include click_id parameter:

https://track.example.com/c/postback?click_id=YOUR_CLICK_ID

Error: "Click not found"

Cause: The click_id doesn't exist in the database

Possible reasons:

  • Click_id is incorrect or corrupted
  • Click is older than retention period
  • Click was from bot traffic (not recorded)

Solution:

  • Verify click_id format and value
  • Check click exists in statistics
  • Use recent click_id for testing

Error: "Invalid conversion"

Cause: Conversion validation failed

Possible reasons:

  • conversion_value is not a number
  • conversion_type is not a string
  • Request from suspicious IP

Solution:

  • Verify parameter types
  • Test with valid values
  • Check conversion validator settings

Error: "Campaign not found"

Cause: Using campaign_id parameter, but campaign doesn't exist or is inactive

Solution:

  • Verify campaign ID is correct
  • Check campaign is active
  • Use click_id instead for better accuracy

Testing Conversions

Manual Testing

Generate a test click:

  • Visit your campaign URL: https://track.example.com/YOUR_CAMPAIGN_TOKEN/
  • Note the click_id from the redirected URL

Test postback:

curl "https://track.example.com/c/postback?click_id=YOUR_CLICK_ID&conversion_value=10"

Verify in Simple TDS:

  • Go to Conversions page
  • Check if conversion was recorded
  • Verify conversion value and click_id

Automated Testing

Create a test script to verify conversion tracking:

// test-conversion.js
const fetch = require('node-fetch');

async function testConversion(clickId) {
    const url = `https://track.example.com/c/postback?click_id=${clickId}&conversion_value=25.50&conversion_type=test`;

    const response = await fetch(url);
    const data = await response.json();

    if (data.success) {
        console.log('βœ“ Conversion tracked successfully');
        console.log('  Conversion ID:', data.conversion_id);
    } else {
        console.error('βœ— Conversion tracking failed');
        console.error('  Error:', data.message);
    }
}

// Test with your click_id
testConversion('a3f8b2c1d4e5f6g7h8i9j0k1l2m3n4o5');

Best Practices

  1. Always use HTTPS for all tracking URLs
  2. Prefer server-to-server postbacks over pixel tracking when possible
  3. Store click_id persistently in sessionStorage or cookies for multi-page flows
  4. Test thoroughly before sending live traffic
  5. Monitor conversion rates to detect tracking issues early
  6. Use external_id to cross-reference with your own transaction IDs
  7. Implement fallback tracking (e.g., both postback and pixel)
  8. Document your integration for future reference

Support

For issues or questions: