Skip to content

Add log_event capability for conversion tracking (aligned with IAB ECAPI) #934

@bokelley

Description

@bokelley

Summary

Add a log_event tool to AdCP for sending conversion and marketing events to advertising platforms. This should provide a generalized interface that works across platform-specific Conversion APIs (CAPIs) while aligning with the emerging IAB Tech Lab ECAPI specification.

Motivation

Today, advertisers must implement separate integrations for each platform's conversion API:

  • Snap CAPI - POST https://tr.snapchat.com/v3/{pixel_id}/events
  • Meta Conversions API - POST https://graph.facebook.com/v18.0/{pixel_id}/events
  • TikTok Events API - POST https://business-api.tiktok.com/open_api/v1.3/event/track/
  • Google Ads - Offline Conversion Import API
  • Pinterest - Conversions API
  • LinkedIn - Conversions API

Each has slightly different schemas, authentication, and event types. IAB Tech Lab's ECAPI aims to standardize this, and AdCP should support it.

Why This Matters for Agentic Buying

As noted by IAB Tech Lab:

"ECAPI will also be built directly into the IAB Tech Lab agentic roadmap so that outcomes-based buying and selling with measurable goals using agents can become a reality."

AdCP agents need to:

  1. Report conversions back to platforms for optimization
  2. Configure measurement when creating media buys
  3. Support deduplication between client-side pixels and server-side events

Proposed Interface

log_event Tool

interface LogEventRequest {
  // Event identification
  event_name: EventType
  event_id?: string           // For deduplication
  event_time: string          // ISO 8601 timestamp
  
  // Event source
  event_source: 'web' | 'app' | 'offline' | 'crm'
  event_source_url?: string   // For web events
  
  // User matching (hashed PII for privacy)
  user_data: {
    email_hash?: string       // SHA-256 hashed
    phone_hash?: string       // SHA-256 hashed, E.164 format
    ip_address?: string
    user_agent?: string
    client_id?: string        // First-party cookie/device ID
    external_id?: string      // Advertiser's user ID
    click_id?: string         // Platform click ID (ScCid, fbclid, ttclid, gclid)
  }
  
  // Event data
  custom_data?: {
    currency?: string         // ISO 4217
    value?: number            // Conversion value
    transaction_id?: string   // Order ID for purchase deduplication
    content_ids?: string[]    // Product SKUs
    content_type?: string     // 'product', 'product_group'
    num_items?: number
    search_string?: string
    // Extensible for platform-specific fields
    [key: string]: unknown
  }
  
  // App-specific (for mobile events)
  app_data?: {
    app_id: string
    app_version?: string
    device_model?: string
    os_version?: string
  }
}

// Standard event types (aligned with IAB ECAPI when finalized)
type EventType = 
  | 'page_view'
  | 'view_content'
  | 'search'
  | 'add_to_cart'
  | 'add_to_wishlist'
  | 'initiate_checkout'
  | 'add_payment_info'
  | 'purchase'
  | 'lead'
  | 'complete_registration'
  | 'subscribe'
  | 'start_trial'
  | 'custom'

interface LogEventResponse {
  success: boolean
  events_received: number
  errors?: Array<{
    event_id?: string
    code: string
    message: string
  }>
  // Platform may return attribution data
  attribution?: {
    matched: boolean
    campaign_id?: string
    ad_id?: string
  }
}

get_measurement_config Tool

Publishers should expose their measurement requirements:

interface GetMeasurementConfigResponse {
  // Identifiers needed for this publisher
  tracking_ids: Array<{
    id_type: 'pixel_id' | 'app_id' | 'dataset_id' | 'conversion_id'
    id_value: string
    name?: string
  }>
  
  // Supported event types
  supported_events: EventType[]
  
  // Required user matching fields
  required_user_fields: Array<'email_hash' | 'phone_hash' | 'click_id'>
  
  // Deduplication configuration
  deduplication: {
    supported: boolean
    id_field: 'event_id' | 'transaction_id'
    window_hours: number
  }
  
  // API details
  api_endpoint?: string      // For direct CAPI integration
  api_version?: string
  rate_limits?: {
    requests_per_second: number
    events_per_batch: number
  }
}

Integration with create_media_buy

Add measurement configuration to Package:

interface Package {
  // ... existing fields
  
  measurement_config?: {
    tracking_id: string                    // Pixel ID, App ID, etc.
    optimization_event?: EventType         // Event to optimize toward
    attribution_window?: {
      click_days: 1 | 7 | 28
      view_days: 1 | 7 | 28
    }
  }
}

Platform Mapping

AdCP Event Snap Meta TikTok Google
purchase PURCHASE Purchase CompletePayment purchase
add_to_cart ADD_CART AddToCart AddToCart add_to_cart
lead SIGN_UP Lead SubmitForm submit_lead_form
view_content VIEW_CONTENT ViewContent ViewContent view_item
search SEARCH Search Search search

Privacy Considerations

  1. Hashing Required - All PII (email, phone) must be SHA-256 hashed before transmission
  2. User Consent - Events should only be sent for users who have consented to tracking
  3. Data Minimization - Only send fields necessary for attribution
  4. Click ID Preference - When available, click IDs provide better matching without PII

Related Work

Questions for Discussion

  1. Should log_event be a separate tool or part of a broader signals protocol?
  2. How should we handle real-time vs. batch event submission?
  3. Should AdCP define the hashing algorithm or leave it to platforms?
  4. How do we handle platforms that require different user matching fields?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions