Google Data Manager - Events

What Is Google Data Manager - Events?

Google Data Manager is Google's unified data ingestion service for advertising and measurement. Its Events service (events:ingest) accepts server-side conversion and engagement events and fans them out to multiple Google products — Google Ads, Google Analytics 4 (GA4), and Google Marketing Platform Floodlight configurations (Campaign Manager 360 / Display & Video 360) — from a single API call. This MetaRouter Starter Kit, "Google Data Manager - Events," sends full-funnel web and app events to the events:ingest endpoint with SHA-256 hashed user identifiers, Google ad identifiers, cart data, and per-destination routing.


Product Type: Advertising
Integration Type: Starter Kit & ID Sync
Event Source Type: Web and/or Mobile Browser and/or Mobile App
Event Scope: Full-Funnel Events


Capabilities

  • Sends full-funnel events (page views, product and cart activity, checkout, purchases, refunds, promotions) to the Google Data Manager events:ingest endpoint using an HTTP POST with an OAuth2 JWT bearer token.
  • Fans out one event stream to multiple Google destinations — GA4, Google Ads, and Floodlight — in a single request via the destinations[] array and per-event destinationReferences.
  • Attaches SHA-256 hashed user identifiers (email, phone, and address components) plus Google ad identifiers (gclid, wbraid, dclid, matchId, mobileDeviceId) to improve conversion matching.
  • Carries conversion value and count, currency, cart items, and additional GA4 event parameters per event.
  • Derives event source (WEB or APP) from the incoming context and maps the mobile advertising ID for app events.
  • Ships with global consent signals set to granted and HEX encoding for hashed identifiers.

Considerations

  • The integration only forwards events that carry at least one usable identifier. Support for PII-only conversions (hashed user data with no click or device ID) varies by destination:
    • Google Ads: accepts gclid, gbraid, wbraid, or userData — PII-only conversions are always supported.
    • GA4: PII-only is supported only in multi-source mode (events sent with a transactionId as an additional data source to an allowlisted property), where clientId, userId, or userData alone is sufficient. Outside multi-source mode, GA4 requires clientId (or appInstanceId) as its primary identifier.
    • Floodlight: PII-only is never sufficient, in either mode — it always requires at least one of gclid, dclid, matchId, impressionId, mobileDeviceId, or encryptedUserIds, and rejects conversions without one.
  • validateOnly is set to false in the global enrichments, so the kit ships ready to send live events. Set it to true to validate requests without executing them — the API checks each request and returns only errors, not results. Useful for schema and configuration testing.
  • The kit sends a single event stream to several Google platforms at once. The vendor configures one entry per target platform in the destinations array in the global Lua, and each destination is addressed by its operatingAccount.accountType, accountId, and productDestinationId. If the you do not use a given platform, that entry must be removed from the destinations Lua, the matching reference must be removed from event.destinationReferences in each event, and any event left with no remaining destination should be deleted entirely. Any now-unneeded conditions should also be removed from the filters section.
  • Destination-to-event relationship: one GA4 destination covers all events, while Google Ads and Floodlight require one destination per event because each event maps to a distinct conversion action (Google Ads) or activity (Floodlight).
  • GA4 destinations are addressed by eventName, which is required for GA4 events; Google Ads, Display & Video 360, and Floodlight destinations are addressed by the conversion action ID (Google Ads) or Floodlight activity ID set as productDestinationId.
  • To add a new destination, choose the platform, add a destination(...) line with a unique reference (the reference provides uniqueness when credentials are shared), then add that reference to the event's destinationReferences array. To remove one, delete the destination(...) line and remove its value from destinationReferences — note that leaving the array empty sends the event to all remaining destinations, so decide whether that is the intended behavior; if not, delete the event itself. If the removed destination was the last one for its platform, also remove any now-unneeded conditions from the filters section.
  • The page event's name is taken from MetaRouter's Analytics.js event due to GA4 naming rules, and the page event is treated as a custom event for GA4.
  • Use GA4's official parameter names for parameterName in additionalEventParameters where possible, as recommended by Google.
  • gclid, wbraid, dclid, and clientId are web-only and are sourced from browser-side providers (gtag.js, Google Ads, CM360, GA4). Mobile (iOS/Android) events still deliver to the Data Manager API using mobileDeviceId with hashed user identifiers (email, phone, address) or matchId; these identifiers can also be passed directly on the event payload without relying on the sync.
  • encoding is required only when the request includes UserData uploads; this kit sets it to HEX. Email, phone, and name fields are SHA-256 hashed before sending.
  • Within a single UserData identifier, only one of emailAddress, phoneNumber, or address can be set.
  • unitPrice must exclude tax, shipping, and order-wide discounts, but include item-level discounts.
  • cartData requires the merchantProductId field for Floodlight and for Google Ads conversions that are not store sales; without it, the API returns an error.
    • In this starter kit, merchantProductId is mapped only on Order Completed: it is the sole cart event routed to Floodlight and Google Ads (via its destinationReferences). The other cart events go to GA4 only, which does not require it. If you route another cart event to Floodlight or Google Ads, add merchantProductId to its items as well.
    • Using cartData requires a Google Merchant Center account with a product feed. The merchantProductId values must match the item IDs in that feed exactly, or the match fails even when the field is populated.
  • The kit sets event.consent.adUserData and event.consent.adPersonalization to CONSENT_GRANTED statically; confirm this matches the pipeline's consent enforcement.
  • There is no processing delay recommended for Google Ads conversions. For Floodlight conversions, it is recommended to allow approximately two hours for a newly created ad identifier to process before it is used to match a conversion. Please reach out to your MetaRouter representative to set up a delay.
  • This kit uses a batch size of 500.

Limitations

  • A single request can contain at most 10 Destination resources in the destinations list and at most 10 user identifiers in the UserData for each event.
  • Diagnostics cannot be retrieved for requests that have validateOnly set to true; the kit must be switched out of validate-only mode before request status can be polled.
  • GA4 events must have an eventTimestamp within the last 72 hours, and an event can reference only one GA4 destination — if destinationReferences is unset or has multiple entries referring to Google Analytics destinations, the event is rejected with MULTIPLE_DESTINATIONS_FOR_GOOGLE_ANALYTICS_EVENT.
  • GA4 rejects reserved event names with INVALID_EVENT_NAME, so custom names must follow GA4 naming rules.
  • Each Google Cloud project is limited to 100,000 IngestionService requests per day and 300 requests per minute; exceeding the limits returns RESOURCE_EXHAUSTED with HTTP status 429 Too Many Requests.

MSC Support (Multi-Source Conversions)

Multi-Source Conversions is a Google Ads configuration, currently in beta, that lets one conversion action accept data from both the Google tag and a server-side feed. Google matches the two on transaction ID, deduplicates them, and fills in conversions the tag missed. Google's Help Center calls this "conversions with multiple data sources".

MSC is not a MetaRouter integration — it is configuration in your Google Ads account. The server-side feed it consumes is delivered through the Google Data Manager — Events integration. MSC is independent of Google Tag Gateway and works with or without it.

Requirements

No MSC-specific field or flag is required in the payload. A matching transaction ID plus conversion date and time is sufficient for automatic deduplication. An MSC-ready configuration requires:

  • A Google Data Manager — Events integration configured against your Google Ads destination, targeting the specific conversion action that has the additional data source connected.
  • A transaction ID on the event. This originates from your own conversion event — your order ID — rather than from the sync injector, which carries and maps it. The same ID must also be present on your client-side Google tag conversion, or there is nothing to match against.
  • Conversion date and time on each delivered conversion.
  • Conversion value and currency. Required for Google to reconcile value, and required to see any reported uplift.

Prerequisites

  • MSC enablement on your Google Ads account, requested through your Google representative. It is a beta and not self-serve.
  • Allowlisting to connect an additional data source via the Data Manager API.
  • A website conversion action created manually via the Google tag or Google Tag Manager. Imported Google Analytics conversions and URL-based conversion actions are not eligible.
  • A conversion event that reliably generates and sends a consistent transaction ID.

How It Behaves

  • The server-side feed becomes the source of truth for conversion value. When a transaction ID matches an existing tag event, the uploaded value overwrites the value the tag recorded.
  • Deduplication is scoped to a single conversion action. It does not deduplicate across other conversion actions in the account. If a new conversion action is created for this purpose, it must not sit alongside the original in the same campaign goal set, or conversions will be double-counted.
  • A newly connected data source enters a 14-day trial period during which its data is used for reporting and diagnostics but does not affect bidding. After the trial it becomes biddable automatically, regardless of outstanding diagnostic alerts.
  • Google raises an urgent diagnostic if transaction ID overlap between the two sources falls below 10%.
  • Conversions still require a click identifier to be counted. Deduplication does not depend on GCLID, but a conversion with no associated click will not increment the reported conversion count. This is expected behaviour, not a delivery failure.

Identity Sync

  • Sync Available: Yes
  • Required for Starter Kit: Yes — the Google Tag (decoupled) sync populates the clientId, gclid, wbraid, and dclid values that the integration reads from context.providers. The matchId (MetaRouter anonymousId) is available without the sync, but GA4 web-stream matching and Google Ads/Floodlight click attribution depend on the sync-captured values.
  • Prerequisites: Parent Google Tag Settings configured and deployed before any child sync; relevant account identifiers (GA4 Measurement ID, Google Ads ID with conversion labels, and/or CM360 Floodlight IDs); consent categories configured in the MetaRouter UI.
  • Documentation: See Additional Google Tag (Decoupled) Documentation

Sync Details

  • In the decoupled model, Google Tag Settings acts as a parent that loads the gtag.js library, and each Google product (GA4, Google Ads, CM360) is configured as an independent child sync beneath it.
  • The GA4 child sync captures the GA4 client ID, which the integration reads server-side under context.providers.googleAnalytics4.clientID.
  • The CM360 child sync captures gclid and dclid; the Google Ads child sync captures wbraid. All three fall back to context.providers.googleGtag.data when the specific child sync is not configured.
  • matchId is not sync-dependent — it is mapped from MetaRouter's anonymousId and used as a fallback identifier when no click ID is available.
  • Consent categories set in the MetaRouter UI gate when each sync fires, and captured identifiers are appended to the server-side event under context.providers.

Child Syncs


Starter Kit Setup Guide

1. Deploy the Google Data Manager - Events Sync

  • To collect the sync values (e.g., clientId, gclid, wbraid, dclid), you must implement the Google Tag (decoupled) parent and the required child syncs (GA4, Google Ads, and/or CM360). The parent Google Tag Settings must be deployed before any child sync will function. Refer to the following documentation to complete the setup: Google Tag Decoupled - ID Sync Guide.

2. Gather Credentials

  • Create a Google Cloud project, enable the Data Manager API, and create a service account with the datamanager scope. Grant the service account's email access to each destination (for GA4, add it as a user on the property). Then collect:
    • Service account email
    • RSA private key (PEM)
    • Each destination's account type, account ID, and productDestinationId (GA4 Measurement ID, Google Ads conversion action ID, or Floodlight activity ID)
  • For how to create a service account, configure the datamanager scope, and grant destination access, see Set up API Access.
  • For details on accountType, accountId, and productDestinationId, see Configure Destinations and the Destination Resource reference.
  • Note: For a step-by-step walkthrough of the Google Ads side — creating the service account, enabling the API, granting access, and creating conversion actions — see Google Ads Setup for Data Manager.

3. Add a Google Data Manager - Events Integration

  • From the integration library, add a Google Data Manager - Events integration. Then, fill out the Connection Parameters:
Connection ParameterDescription
API_VERSIONAPI version segment in the endpoint URL. Defaults to v1.
SERVICE_ACCOUNT_EMAILService account email used as the JWT issuer (iss) for OAuth2 authentication.
PRIVATE_KEYRSA private key (PEM) used to sign the OAuth2 JWT assertion.

4. Configure Event Mapping

  • MetaRouter provides all of the event mappings that Google Data Manager - Events integrations typically require. You may add custom events, parameters, or mappings in accordance with Google's API documentation.

5. Deploy to Pipeline

  • In the Pipelines tab, add your Google Data Manager - Events integration.
  • Select the correct integration revision.
  • Click Add Integration to finalize deployment.

Event Mappings

Global

Global mappings will be applied to all events. If your parameter names do not match the Expected Inputs provided, you will need to overwrite the Inputs provided with your own.

Output KeyDescriptionExpected Input
event.consent.adUserDataString: Consent signal for ad user data.Enrichment – CONSENT_GRANTED
event.consent.adPersonalizationString: Consent signal for ad personalization.Enrichment – CONSENT_GRANTED
encoding RequiredString: Encoding of hashed user identifiers; required for UserData uploads.Enrichment – HEX
validateOnlyBoolean: When true, validates requests without executing them; returns only errors.Enrichment – false
destinations RequiredArray: Destination objects that receive the events.Expression – builds destination(reference, accountType, accountId, productDestinationId) entries for ga4, google_ads_purchase, google_ads_page, floodlight_purchase, floodlight_page
event.adIdentifiers.gclidString: Google click ID.Expression – context.providers.CM360.gclid or googleGtag gclid
event.adIdentifiers.wbraidString: iOS web-to-app click identifier.Expression – context.providers.googleAds.wbraid or googleGtag wbraid
event.adIdentifiers.dclidString: Display click ID.Expression – context.providers.CM360.dclid or googleGtag dclid
event.adIdentifiers.matchIdString: Match ID used to join this event with a prior event.anonymousId
event.adIdentifiers.landingPageDeviceInfo.ipAddressString: Landing-page device IP address.context.ip
event.adIdentifiers.landingPageDeviceInfo.userAgentString: Landing-page device user agent.context.userAgent
event.adIdentifiers.landingPageDeviceInfo.languageCodeString: ISO 639-1 language code.Expression – SPLIT of context.locale
event.transactionIdString: Unique identifier for the event.messageId
event.eventTimestamp RequiredString: RFC 3339 timestamp of when the event occurred.Expression – input.timestamp or input.originalTimestamp
event.eventSourceString: Enum WEB or APP.Expression – 'APP' if context.app.name, context.device.type, or context.os.name, else 'WEB'
event.userData.userIdentifiersArray: SHA-256 hashed user identifiers.Expression – hashes traits.email, traits.phone, and address (givenName from firstName, familyName from lastName, postalCode, regionCode via TO_ISO_COUNTRY(country))
event.adIdentifiers.mobileDeviceIdString: Mobile advertising ID (IDFA/AAID).context.device.advertisingId
event.clientIdString: GA4 web client instance identifier.Expression – googleAnalytics4.clientID or parsed from googleGtag ga cookie
event.userIdString: Advertiser-defined user identifier.userId
event.destinationReferencesArray: Default destination routing references.Expression – {"ga4"}
event.currencyString: Currency code for monetary values.properties.currency

Event Specific

Page

Output KeyDescriptionExpected Input
event.eventName RequiredString: GA4 event name.Enrichment – page
event.destinationReferencesArray: Destination routing references.Expression – {"ga4","floodlight_page","google_ads_page"}
event.additionalEventParametersArray: GA4 event parameters.Expression – page_location, page_title, page_referrer, search

Order Completed

Output KeyDescriptionExpected Input
event.eventName RequiredString: GA4 event name.Enrichment – purchase
event.destinationReferencesArray: Destination routing references.Expression – {"ga4","floodlight_purchase","google_ads_purchase"}
event.conversionValueFloat: Conversion value.properties.revenue
event.conversionCountInteger: Conversion quantity.Expression – sum of product quantities
event.transactionIdString: Unique identifier for the event; overrides the global messageId for purchases.properties.order_id
event.additionalEventParametersArray: GA4 event parameters.Expression – tax, shipping
event.cartDataObject: Cart items, Merchant Center ID, and event-level coupon codes.Expression – merchantId (ADD_MERCHANT_ID_HERE placeholder); couponCodes from properties.coupon; items map item_name, item_category; itemId and merchantProductId from product_id, quantity, unitPrice

Products Searched

Output KeyDescriptionExpected Input
event.eventName RequiredString: GA4 event name.Enrichment – search
event.additionalEventParametersArray: GA4 event parameters.Expression – search_term from properties.query

Product Clicked

Output KeyDescriptionExpected Input
event.eventName RequiredString: GA4 event name.Enrichment – select_item
event.conversionValueFloat: Conversion value.Expression – TOTAL_VALUE(properties)
event.conversionCountInteger: Conversion quantity.properties.quantity
event.cartData.itemsArray: Cart items.Expression – item_name, item_category, item_variant, item_brand, discount, index from position, coupon; itemId from product_id, quantity, unitPrice

Product Added

Output KeyDescriptionExpected Input
event.eventName RequiredString: GA4 event name.Enrichment – add_to_cart
event.conversionValueFloat: Conversion value.Expression – TOTAL_VALUE(properties)
event.conversionCountInteger: Conversion quantity.properties.quantity
event.cartData.itemsArray: Cart items.Expression – item_name, item_category, item_variant, item_brand, discount, index from position, coupon; itemId from product_id, quantity, unitPrice

Product Added To Wishlist

Output KeyDescriptionExpected Input
event.eventName RequiredString: GA4 event name.Enrichment – add_to_wishlist
event.conversionValueFloat: Conversion value.Expression – TOTAL_VALUE(properties)
event.conversionCountInteger: Conversion quantity.properties.quantity
event.cartData.itemsArray: Cart items.Expression – item_name, item_category, item_variant, coupon, item_brand, discount, index from position; itemId from product_id, quantity, unitPrice

Product Removed

Output KeyDescriptionExpected Input
event.eventName RequiredString: GA4 event name.Enrichment – remove_from_cart
event.conversionValueFloat: Conversion value.Expression – TOTAL_VALUE(properties)
event.conversionCountInteger: Conversion quantity.properties.quantity
event.cartData.itemsArray: Cart items.Expression – item_name, item_category, item_variant, coupon, item_brand, discount, index from position; itemId from product_id, quantity, unitPrice

Checkout Started

Output KeyDescriptionExpected Input
event.eventName RequiredString: GA4 event name.Enrichment – begin_checkout
event.conversionValueFloat: Conversion value.properties.revenue
event.conversionCountInteger: Conversion quantity.Expression – sum of product quantities
event.cartDataObject: Cart items and event-level coupon codes.Expression – couponCodes from properties.coupon; items map item_name, item_category; itemId from product_id, quantity, unitPrice

Order Refunded

Output KeyDescriptionExpected Input
event.eventName RequiredString: GA4 event name.Enrichment – refund
event.conversionValueFloat: Conversion value.properties.revenue
event.conversionCountInteger: Conversion quantity.Expression – sum of product quantities
event.additionalEventParametersArray: GA4 event parameters.Expression – tax, shipping
event.cartDataObject: Cart items and event-level coupon codes.Expression – couponCodes from properties.coupon; items map item_name, item_category, index from position; itemId from product_id, quantity, unitPrice

Cart Viewed

Output KeyDescriptionExpected Input
event.eventName RequiredString: GA4 event name.Enrichment – view_cart
event.conversionValueFloat: Conversion value.Expression – TOTAL_VALUE(properties.products)
event.conversionCountInteger: Conversion quantity.Expression – sum of product quantities
event.cartData.itemsArray: Cart items.Expression – item_name, item_category; itemId from product_id, quantity, unitPrice

Product Viewed

Output KeyDescriptionExpected Input
event.eventName RequiredString: GA4 event name.Enrichment – view_item
event.conversionValueFloat: Conversion value.Expression – TOTAL_VALUE(properties)
event.conversionCountInteger: Conversion quantity.properties.quantity
event.cartData.itemsArray: Cart items.Expression – item_name, item_category, item_variant, item_brand, coupon, discount, index from position; itemId from product_id, quantity, unitPrice

Product List Viewed

Output KeyDescriptionExpected Input
event.eventName RequiredString: GA4 event name.Enrichment – view_item_list
event.additionalEventParametersArray: GA4 event parameters.Expression – item_list_id, item_list_name
event.cartData.itemsArray: Cart items.Expression – item_name, item_category, index from position; itemId from product_id, quantity, unitPrice

Promotion Clicked

Output KeyDescriptionExpected Input
event.eventName RequiredString: GA4 event name.Enrichment – select_promotion
event.additionalEventParametersArray: GA4 event parameters.Expression – promotion_id, promotion_name from name, creative_name from creative, creative_slot from position

Required & Recommended Identifiers

These identifiers must be mapped to Google Data Manager in order for successful user matching to occur. Without these IDs, any events sent to Google Data Manager may not be accurately reflected in reporting.

AttributeExampleSync Injector Required?
clientId Required1234567890.1234567890Yes
gclid RecommendedCj0KCQjw_pvalYes
wbraid RecommendedCj0KCQiAr8cYes
dclid RecommendedCKDdz-fE_IUDFYtTCQkdbyMOPgYes
matchId Recommendedb171a9b06ce011ecafcd1b209be8601bNo
mobileDeviceId Recommended38400000-8cf0-11bd-b23e-10b96e40000dNo
email_hash Recommended3e693cf7e5b67880bff33b2d2626dadb7bf1d4bc737192e47cf8baa89acf2250No
phone_hash Recommendedd634b0526e6b...No

Integration Validation

validateOnly is set to false in the global enrichments, so the kit sends live events by default. To test without writing data, set validateOnly to true — the API validates each request and returns only errors, not results. Switch it back to false before going live.

Use RetrieveRequestStatus with the requestId from a successful ingestion response to check per-destination processing status. Google recommends waiting 30 minutes before the first check, then polling with exponential backoff up to 24 hours until status reaches SUCCESS, PARTIAL_SUCCESS, or FAILURE. Alternatively, you can check each platform's dashboard.


Additional Google Data Manager Documentation