After ClickHouse persistence, the API triggers asynchronous forwards.
GA4 (Measurement Protocol)
- Always attempted when
GA4_MEASUREMENT_IDandGA4_SECRETare set. - Maps common names (e.g.
LeadFormSubmitted→generate_leadwhere configured). - For
LeadFormSubmitted,transaction_idis set to a stable per-lead token when identity can be derived (aligns with duplicate handling).
Meta Conversions API
- Runs for eligible event types when Meta credentials exist and entry conditions match (e.g.
fbclid, Facebook UTMs, or certain events such asPageViewper deployment logic). - Uses Pixel ID + access token; optional test event code in non-prod.
- For
LeadFormSubmitted→Lead, the server setsevent_id(stable per lead) and skips a second Meta send when that lead was already counted — see Lead form deduplication.
Google Ads (click conversions upload)
- Uses
ConversionUploadService.uploadClickConversions(REST). Runs whengclid,wbraid, orgbraidis present on the attribution payload (not Metafbclid; not Bingmsclkid— that would be a separate Microsoft Ads path). gclid/wbraid/gbraidare also written onto storedevent_dataJSON so follow-up dedupe queries can match across events.- Conversion actions must be configured as resource names in
G_ADS_CONVERSION_ACTIONS_JSON(per brand and event:PhoneClick,LeadFormSubmitted,EmailClick). Without this map, status ismissing_gads_conversion_map. - For
LeadFormSubmitted, uploads includeorderId(stable per lead) and skip when a prior row for the same lead already reachedsent_gads— see Lead form deduplication. - OAuth refresh failures surface as
error_gads_auth; API rejections aserror_gads.
Status columns on uts_events
meta_capi_status— Meta delivery (sent_meta,error_meta,skipped_meta_duplicate_lead, …).google_capi_status— Google Ads uploads (sent_gads,error_gads,skipped_gads_duplicate_lead, …). Column name is historical (“CAPI”); it refers to Google Ads REST uploads, not GA4.
Why this matters
- Facebook conversions (CAPI / Pixel) do not populate Google Ads offline conversion uploads unless you also have Google click identifiers—those pipelines are separate code paths.