Prooflytics + The Trade Desk: B2B Conversion Attribution in an Independent DSP

Prooflytics + The Trade Desk: B2B Conversion Attribution in an Independent DSP

The Trade Desk (TTD) is the largest independent DSP with an 11% share of the programmatic market. For B2B companies buying programmatic inventory through TTD, attribution is the core challenge: a banner click and a signed contract can be separated by 30 to 180 days. TTD has no way of knowing that a given user eventually became a customer.

Prooflytics closes this gap by tracking the full attribution chain: ad click (TDID from the URL) -> lead -> CRM contact -> closed deal. The TTD Offline Conversions API accepts this data back - and TTD’s algorithms begin optimizing campaigns toward real B2B conversions rather than clicks or form submissions.

The Trade Desk (TTD) is an independent demand-side platform founded in 2009 and publicly traded on NASDAQ (TTD). It positions itself as an alternative to Google DV360 without the conflict of interest: TTD does not sell its own ad inventory - it only buys inventory from others. The platform is popular with enterprise advertisers and agencies.

Why B2B Attribution in Programmatic Is Difficult

Google Analytics and standard pixels track conversions within a single session or within a 30-to-90-day attribution window. B2B deal cycles run 3 to 12 months. By the time a contract is signed, the user’s cookie is long gone, they have likely switched devices, and they have no memory of the banner.

The common outcome: a TTD campaign reports zero conversions while the business is generating real revenue from programmatic-sourced clients. The TTD budget gets cut - even though the channel is producing leads. The problem is that the journey is invisible.

Prooflytics + TTD Architecture

Landing page: prospect clicks a TTD banner
  -> URL: https://your-site.com/demo?tdid={TDID}&utm_source=ttd
  -> Prooflytics captures TDID, stores it in cookie + CRM

CRM (Kommo / HubSpot): lead -> qualification -> contract
  -> Deal closed (Closed Won)

Prooflytics:
  -> Look up TDID by contactId
  -> POST TTD Offline Conversions API
     {tdid, unifiedId2, conversionTime, value, currency}

TTD:
  -> Update attribution for this user
  -> Optimize campaigns toward closed deals

Capturing TDID and UID2

import hashlib, re

def normalize_email(email: str) -> str:
    # UID2 requires normalization: lowercase, trim, strip Gmail aliases
    email = email.strip().lower()
    local, domain = email.split("@", 1)
    if domain in ("gmail.com", "googlemail.com"):
        local = local.split("+")[0].replace(".", "")
    return f"{local}@{domain}"

def email_to_uid2(email: str) -> str:
    normalized = normalize_email(email)
    return hashlib.sha256(normalized.encode()).hexdigest()

# Capture TDID from URL on first visit
def extract_tdid(request_args: dict) -> str | None:
    return request_args.get("tdid") or request_args.get("ttdid")

# Flask example: save to cookie and Kommo custom field
from flask import request as flask_request, make_response

@app.route("/landing")
def landing():
    tdid = extract_tdid(flask_request.args)
    resp = make_response("Landing page")
    if tdid:
        resp.set_cookie("ttd_tdid", tdid,
                        max_age=365*24*3600, samesite="Lax")
    return resp

Sending Conversions to TTD

import requests, os
from datetime import datetime, timezone

TTD_API_KEY     = os.environ["TTD_API_KEY"]
TTD_ADVERTISER  = os.environ["TTD_ADVERTISER_ID"]
TTD_TRACKING_TAG = os.environ["TTD_TRACKING_TAG_ID"]
TTD_BASE        = "https://api.thetradedesk.com"
TTD_HDR         = {"TTD-Auth": TTD_API_KEY,
                   "Content-Type": "application/json"}

def send_ttd_conversion(tdid: str | None,
                         uid2: str | None,
                         deal_value: float,
                         deal_id: str,
                         currency: str = "USD"):
    if not tdid and not uid2:
        return None  # nothing to send

    conversion = {
        "trackingTagId": TTD_TRACKING_TAG,
        "conversionTime": datetime.now(timezone.utc).strftime(
            "%Y-%m-%dT%H:%M:%SZ"
        ),
        "orderid":  f"deal_{deal_id}",
        "value":    deal_value,
        "currency": currency,
        "type":     "purchase",
    }
    if tdid:
        conversion["tdid"] = tdid
    if uid2:
        conversion["unifiedId2"] = uid2

    r = requests.post(
        f"{TTD_BASE}/v3/thirdpartydata/postconversion"
        f"/advertiser/{TTD_ADVERTISER}",
        headers=TTD_HDR,
        json=[conversion],
    )
    r.raise_for_status()
    return r.json()

# Integration with Kommo webhook (Closed Won):
@app.route("/webhooks/kommo", methods=["POST"])
def kommo_webhook():
    data = request.json or {}
    for lead_data in data.get("leads", {}).get("status", []):
        lead_id    = lead_data.get("id")
        new_status = lead_data.get("status_id")
        if new_status != int(os.environ["KOMMO_CLOSED_WON_ID"]):
            continue

        # Fetch deal + contact data
        lead, contact = get_lead_contact(lead_id)
        amount = float(lead.get("price") or 0)
        email  = get_email(contact)

        # Retrieve TDID from Kommo custom field
        tdid   = get_cf(lead, int(os.environ.get("CF_TTD_TDID", "0")))

        uid2   = email_to_uid2(email) if email else None

        if not tdid and not uid2:
            add_note(lead_id, "TTD: no TDID or email - conversion not sent.")
            continue

        result = send_ttd_conversion(
            tdid     = tdid or None,
            uid2     = uid2,
            deal_value = amount,
            deal_id    = str(lead_id),
        )
        add_note(
            lead_id,
            f"TTD offline conversion sent: {amount} USD. "
            f"TDID: {tdid or 'none'}, UID2: {'email hash' if uid2 else 'none'}"
        )

    return jsonify({"status": "ok"}), 200

UID2 in B2B Without Opt-In

UID2 (Unified ID 2.0) is an identity ecosystem built on email and phone hashes. A full UID2 integration requires user opt-in via a UID2 Operator. In B2B with a long sales cycle, this is practically unrealistic.

The pragmatic B2B approach: send unifiedId2 as a SHA256 hash of the normalized email. TTD accepts this as a “first-party UID2” and uses it for attribution in environments that support UID2. It is less precise than a full UID2 integration, but substantially better than sending nothing.

TDID (The Trade Desk ID) is a stronger signal: it is the cookie or device ID set by TTD itself when a user views an ad. If you capture the TDID from the click URL, you have a direct link between that user and the TTD campaign.

Lookback Window and Conversion Delay

TTD accepts conversions with a conversionTime in the past - the default lookback window is 90 days. For B2B with a 6-to-12-month sales cycle: ask your TTD account manager to extend the attribution window to 365 days via advertiser settings. This is a standard option for enterprise B2B advertisers.

Verifying That Conversions Are Being Received

After sending conversions:

  1. TTD Advertiser Portal -> Reports -> Conversion Report
  2. Confirm that conversions with type purchase are appearing
  3. Compare against the number of Closed Won deals you sent
  4. A discrepancy greater than 10% - check TDID (the user may not have clicked from a TTD campaign)

Who This Is For

B2B companies with a programmatic budget of $50k+ per month in TTD, a long sales cycle (30+ days), and a need to optimize campaigns toward actual revenue. Especially relevant for enterprise SaaS, financial services, and professional services firms. Without offline conversions, TTD optimizes toward micro-conversions - form fills, page views - rather than revenue.

Other attribution integrations: Prooflytics + DV360 (Google programmatic), Prooflytics + Quora Ads (B2B intent).

Frequently Asked Questions

How do I get a TTD API Key?

The TTD-Auth API Key is issued through the TTD Advertiser Portal -> Settings -> API Access. Obtaining it may require a request to your TTD account manager. The TTD API is not fully self-serve - initial access typically requires interaction with the TTD team.

What if TDID was not captured (direct traffic, email click)?

The fallback is UID2 via email hash. If you have the contact’s email in the CRM, always send unifiedId2. TDID + UID2 gives maximum accuracy. UID2 alone is acceptable for B2B. Neither TDID nor UID2 means the conversion cannot be attributed - TTD will never know the deal closed.

Does TTD work in the EU under GDPR?

TTD supports GDPR compliance through TCF 2.0 (Transparency and Consent Framework). UID2 in the EU operates under TCF consent. For B2B companies without a public site displaying a cookie banner - consult legal counsel before using UID2. TDID from click URLs technically does not require separate consent if it is passed within the ad link itself.

Can I send conversions for past periods?

Yes, within the advertiser’s lookback window. If you have historical deal data that includes TDIDs, you can batch-send them through the same API using historical conversionTime values. TTD will recalculate attribution retrospectively. This is especially valuable when setting up the integration for the first time.

Summary

Prooflytics + The Trade Desk - B2B offline attribution in programmatic:

  • TTD API: TTD-Auth header with API Key
  • TDID: capture from ?tdid= URL on click, store in CRM
  • UID2: SHA256(normalize_email(email)) as fallback without full opt-in
  • POST /v3/thirdpartydata/postconversion/advertiser/{id} on Closed Won
  • Lookback window up to 365 days for B2B via advertiser settings
  • Result: TTD campaigns optimize toward real B2B revenue

If your team uses The Trade Desk for B2B programmatic and wants to connect closed deals to campaigns - reach out to the Exceltic.dev team.

More articles

All →