IntegrationsAdvertisingGoogle Ads Conversions

Google Ads Conversions

Datafly Signal delivers offline and enhanced conversions to Google Ads server-to-server via the Google Ads API (ConversionUploadService). This replaces client-side conversion tags with direct server uploads, improving measurement accuracy and enabling conversion-based bidding optimisation without relying on browser-side scripts.

Prerequisites

Setting up Google Ads for server-side conversion tracking requires a Google Ads account, a conversion action, OAuth2 credentials, and (optionally) Enhanced Conversions enabled. Follow each step below before configuring the integration in Signal.

You need an active Google Ads account. If you manage multiple accounts through a Manager Account (MCC), you can use either the MCC customer ID or the individual account’s customer ID.

  1. Sign in to Google Ads.
  2. Your Customer ID is displayed in the top-right corner of the dashboard, formatted as 123-456-7890.
  3. Note this value — you will need it when configuring the integration in Signal.

When entering the Customer ID in Signal, you can use either the dashed format (123-456-7890) or the plain numeric format (1234567890). Signal accepts both.

Create a Conversion Action

A conversion action tells Google Ads what type of conversion you are tracking and how to count it.

  1. In Google Ads, navigate to Tools & Settings > Measurement > Conversions.
  2. Click + New Conversion Action.
  3. Select Import as the conversion source.
  4. Choose Other data sources or CRMs > Track conversions from clicks.
  5. Name the conversion action (e.g. “Website Purchase”, “Lead Form Submit”).
  6. Set the Category (e.g. Purchase, Lead, Sign-up), Value, and Count (one per click or every).
  7. Click Create and Continue.
  8. After creation, find the Conversion Action ID — this is a numeric ID visible in the conversion action’s details page URL or under the tag setup instructions.
⚠️

The Conversion Action ID is a numeric value (e.g. 987654321), not the conversion action name. You can find it in the URL when viewing the conversion action: ...&ctId=987654321.

Enable Enhanced Conversions

Enhanced Conversions allow Google to match server-uploaded conversions to signed-in Google users using hashed first-party data (email, phone, address). This significantly improves attribution when gclid is not available.

  1. In Google Ads, go to Tools & Settings > Measurement > Conversions.
  2. Click on the conversion action you created.
  3. Expand the Enhanced conversions section.
  4. Toggle Enhanced conversions on.
  5. Select Google Ads API as the method for sending enhanced conversion data.
  6. Accept the customer data terms.
  7. Click Save.

Enhanced Conversions are optional but strongly recommended. Without them, conversions can only be attributed via click identifiers (gclid, wbraid, gbraid). With Enhanced Conversions enabled, Signal automatically hashes and sends user data alongside the conversion for improved match rates.

Set Up OAuth2 Credentials

Google Ads API requires OAuth2 authentication. You need to create credentials in Google Cloud Console and generate a refresh token.

Create OAuth Client Credentials:

  1. Go to Google Cloud Console.
  2. Create a new project or select an existing one.
  3. Navigate to APIs & Services > Library.
  4. Search for Google Ads API and click Enable.
  5. Go to APIs & Services > Credentials.
  6. Click Create Credentials > OAuth Client ID.
  7. If prompted, configure the OAuth consent screen first (External or Internal depending on your organisation).
  8. Select Web application as the application type.
  9. Under Authorized redirect URIs, add: https://developers.google.com/oauthplayground
  10. Click Create.
  11. Note the Client ID and Client Secret from the confirmation dialog.

Generate a Refresh Token

The refresh token gives Signal ongoing access to your Google Ads account without requiring repeated sign-in.

  1. Go to the OAuth 2.0 Playground.
  2. Click the gear icon (Settings) in the top-right corner.
  3. Check Use your own OAuth credentials.
  4. Enter your Client ID and Client Secret from the previous step.
  5. Close the settings panel.
  6. In the left panel under Step 1, find and expand Google Ads API (or manually enter the scope: https://www.googleapis.com/auth/adwords).
  7. Select the https://www.googleapis.com/auth/adwords scope.
  8. Click Authorize APIs.
  9. Sign in with a Google account that has admin access to the Google Ads account you want to track conversions for.
  10. Grant the requested permissions.
  11. Back in the Playground, under Step 2, click Exchange authorization code for tokens.
  12. Copy the Refresh Token from the response.
⚠️

Store your OAuth credentials securely. The refresh token provides ongoing access to your Google Ads account and does not expire unless explicitly revoked. If compromised, revoke it immediately in Google Cloud Console > Credentials.

If you manage multiple Google Ads accounts through a Manager Account (MCC) and want to upload conversions to a child account:

  1. In your MCC dashboard, go to Tools & Settings > Setup > Linked accounts.
  2. Ensure the target account is linked and the link is accepted.
  3. Use the MCC Customer ID as the customer_id in Signal, and the conversion action from the child account.

When using an MCC, the OAuth credentials must be for a user with access to the MCC. Signal will use the MCC customer ID to authenticate and upload conversions to the linked child account.

Configuration

FieldRequiredTypeDescription
customer_idYesstringYour Google Ads customer ID (MCC or account level). Format: 123-456-7890 or 1234567890. Found in the top-right corner of the Google Ads console.
conversion_action_idYesstringThe numeric ID of the conversion action in Google Ads. Found under Tools > Conversions, or in the URL when viewing the conversion action.
oauth_credentialsYessecretOAuth2 client credentials as a JSON object containing client_id, client_secret, and refresh_token.

The oauth_credentials field expects a JSON object in this format:

{
  "client_id": "123456789-abcdefg.apps.googleusercontent.com",
  "client_secret": "GOCSPX-abcdefghijklmnop",
  "refresh_token": "1//0abcdefghijklmnopqrstuvwxyz"
}

Configure in Signal

Management UI Setup

  1. Go to Integrations > Add Integration > Google Ads Conversions.
  2. Enter your Customer ID (e.g. 123-456-7890).
  3. Enter your Conversion Action ID (e.g. 987654321).
  4. Paste your OAuth credentials JSON into the OAuth Credentials field.
  5. Select consent categories (typically advertising).
  6. Click Save.

Management API Setup

curl -X POST http://localhost:8084/v1/admin/integrations \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "source_id": "src_abc123",
    "vendor": "google_ads",
    "name": "Google Ads Conversions",
    "enabled": true,
    "config": {
      "customer_id": "123-456-7890",
      "conversion_action_id": "987654321",
      "oauth_credentials": "{\"client_id\":\"123456789-abcdefg.apps.googleusercontent.com\",\"client_secret\":\"GOCSPX-abcdefghijklmnop\",\"refresh_token\":\"1//0abcdefghijklmnopqrstuvwxyz\"}"
    },
    "consent_categories": ["advertising"]
  }'

Variants

Signal provides four pre-configured variants to match common use cases. Each variant includes sensible defaults for conversion types and data handling. Select the variant that best matches your business when adding the integration.

VariantKeyDescriptionNotable Defaults
DefaultdefaultStandard conversion tracking for general-purpose campaign measurement and bid optimisation.Enhanced conversions enabled, partial failure handling.
RetailretailE-commerce focused with transaction value, cart data, and product-level conversion uploads for Shopping campaigns.Includes cart data and transaction value. Tracks Purchase, Add to Cart, Begin Checkout, Page View. Default currency: USD.
TraveltravelTravel and hospitality focused with booking value and itinerary data for hotel and flight conversion tracking.Includes transaction value. Tracks Purchase, Booking, Search, Page View. Default currency: USD.
MediamediaMedia and subscription focused with lead gen, sign-up, and subscription conversion uploads.Includes subscription data. Tracks Sign Up, Subscribe, Lead, Page View.

All variants use the Google Ads API v18, enable enhanced conversions, and hash user identifiers server-side by default.

Identity Signals

Datafly Signal automatically captures and forwards the following identity signals for Google Ads conversion matching:

SignalSourceDescription
gclidURL parameterGoogle Click ID. Automatically extracted from the landing page URL when a user clicks a Google Ads ad. This is the primary attribution identifier.
wbraidURL parameterWeb-to-app attribution identifier. Used for iOS conversions after ATT (App Tracking Transparency). Automatically extracted from the URL.
gbraidURL parameterApp-to-web attribution identifier. Used for app campaign conversions. Automatically extracted from the URL.

User-Provided Signals (Hashed)

When user data is available via _df.identify(), the following fields are SHA-256 hashed server-side before sending to Google Ads as Enhanced Conversion user identifiers:

SignalHashingDescription
emailSHA-256, lowercase, trimmedUser’s email address
phoneSHA-256, E.164 formatUser’s phone number (e.g. +44207946000)
first_nameSHA-256, lowercase, trimmedFirst name
last_nameSHA-256, lowercase, trimmedLast name
street_addressSHA-256, lowercase, trimmedStreet address line
citySHA-256, lowercaseCity
stateSHA-256, lowercaseState or region
postal_codeSHA-256, trimmedPostal/zip code
countrySHA-256, 2-letter ISO codeCountry code (e.g. GB, US)

All PII hashing is performed server-side by the Delivery Worker. Raw PII never leaves your infrastructure. Google uses these hashed values to match conversions to signed-in Google users.

Event Mapping

Only conversion events are sent to Google Ads. Page views and other non-conversion events are filtered out automatically.

Datafly EventGoogle Ads ConversionNotes
Order Completed / Product PurchasedPurchase conversionRequires value, currency. Maps to the configured conversion action.
Lead GeneratedLead conversionConfigurable conversion action.
Signed UpSign-up conversionConfigurable conversion action.
Checkout StartedBegin Checkout conversionRetail variant only.
Product AddedAdd to Cart conversionRetail variant only.
Custom eventsCustom conversionMap via Pipeline transformation to the appropriate conversion action.

Example: Purchase Conversion

Datafly.js call:

_df.track("Order Completed", {
  order_id: "ORD-001",
  total: 129.99,
  currency: "GBP"
});

Google Ads API payload (simplified):

{
  "conversions": [
    {
      "conversion_action": "customers/1234567890/conversionActions/987654321",
      "conversion_date_time": "2026-01-29 14:30:00+00:00",
      "order_id": "ORD-001",
      "conversion_value": 129.99,
      "currency_code": "GBP",
      "gclid": "Tester123456789",
      "user_identifiers": [
        {
          "hashed_email": "836f82db99121b3481011f16b49dfa5fbc714a0d1b1b9f784a1ebbbf5b39577f"
        },
        {
          "hashed_phone_number": "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6abcd"
        }
      ]
    }
  ],
  "partial_failure": true
}

Multiple Conversion Actions

If you need to report different event types to different conversion actions, create multiple Google Ads integrations, each with a different conversion_action_id, and use event filters to route the appropriate events:

{
  "vendor": "google_ads",
  "name": "Google Ads - Purchases",
  "config": {
    "customer_id": "123-456-7890",
    "conversion_action_id": "111111111",
    "oauth_credentials": "..."
  },
  "event_filter": {
    "event_names": ["Order Completed"]
  }
}
{
  "vendor": "google_ads",
  "name": "Google Ads - Leads",
  "config": {
    "customer_id": "123-456-7890",
    "conversion_action_id": "222222222",
    "oauth_credentials": "..."
  },
  "event_filter": {
    "event_names": ["Lead Generated"]
  }
}

Enhanced Conversions

Enhanced Conversions improve attribution accuracy by supplementing click-based identifiers with hashed first-party user data. When a user converts on your site, Signal hashes their personal information (email, phone, name, address) and sends it alongside the conversion to Google Ads. Google then matches this data against its own signed-in user graph to attribute the conversion, even when gclid is not available.

How it works in Signal:

  1. A user identifies themselves on your site (e.g. during checkout).
  2. You call _df.identify() with their details (email, phone, etc.).
  3. When a conversion event fires, Signal automatically includes the hashed user identifiers in the Google Ads API upload.
  4. Google matches the hashed data to a user and attributes the conversion to the original ad click.
// Step 1: Identify the user
_df.identify({
  email: "[email protected]",
  phone: "+44207946000",
  first_name: "Jane",
  last_name: "Smith"
});
 
// Step 2: Track the conversion
_df.track("Order Completed", {
  order_id: "ORD-001",
  total: 89.99,
  currency: "GBP"
});

Enhanced Conversions are enabled by default on all variants. Signal handles all normalisation (lowercasing, trimming, E.164 formatting) and SHA-256 hashing server-side. No raw PII is sent to Google.

For users in the European Economic Area (EEA), Google requires that consent state be included with conversion uploads. Signal forwards the consent state from the event’s context.consent object.

Consent SignalMapped FromDescription
ad_user_datacontext.consent.advertisingConsent to use data for advertising purposes.
ad_personalizationcontext.consent.advertisingConsent to personalised advertising.
{
  "conversions": [
    {
      "consent": {
        "ad_user_data": "GRANTED",
        "ad_personalization": "GRANTED"
      }
    }
  ]
}
⚠️

For EEA users, if consent is DENIED for ad_user_data, Google will accept the conversion but will not use it for bidding optimisation. Ensure your consent management platform populates the context.consent object correctly.

Testing

After configuring the integration, verify that conversions are arriving in Google Ads:

  1. Trigger a test conversion on your site (e.g. complete a test purchase or submit a lead form).
  2. In Google Ads, navigate to Tools & Settings > Measurement > Conversions.
  3. Click on your conversion action.
  4. Check the Diagnostics tab — recent uploads should appear within a few hours.
  5. Conversion source should display as “Uploaded (from API)” or “Website (Enhanced conversions from API)”.
  6. In the All conversions column, you should see the uploaded conversion count increase.

Google Ads may take up to 24 hours to process and display uploaded conversions. For real-time verification, check the Signal Management UI delivery logs to confirm that the API call returned a success response.

To validate in the Management UI:

  1. Go to Integrations and select your Google Ads integration.
  2. Check the Delivery Log for recent events.
  3. A 200 response code with partial_failure_error as empty confirms successful delivery.

Troubleshooting

ProblemCauseSolution
AUTHENTICATION_ERRORInvalid or expired OAuth credentials.Regenerate the refresh token using the OAuth Playground (Step 5 above) and update the credentials in Signal.
AUTHORIZATION_ERRORThe authenticated user does not have access to the Google Ads account.Ensure the Google account used in the OAuth flow has admin access to the target Google Ads account.
CUSTOMER_NOT_FOUNDIncorrect customer ID.Verify the customer ID matches the account in Google Ads. If using MCC, ensure the child account is linked.
CONVERSION_ACTION_NOT_FOUNDIncorrect conversion action ID, or the action was deleted.Check the conversion action exists in Google Ads under Tools > Conversions. Use the numeric ID, not the name.
CLICK_NOT_FOUNDThe gclid is invalid or expired (>90 days).Ensure gclid values are captured correctly. Google Click IDs expire after 90 days.
Conversions not appearingReporting delay.Google Ads can take up to 24 hours to display uploaded conversions. Check Signal delivery logs for API success.
TOO_MANY_CONVERSIONS_IN_REQUESTBatch size exceeds Google’s limit.Signal handles batching automatically. If this persists, contact support.
DUPLICATE_CONVERSIONSame order_id or gclid + timestamp combination sent twice.This is expected behaviour if events are retried. Google deduplicates on order_id.
Enhanced conversions not matchingUser identifiers not provided or incorrectly formatted.Ensure _df.identify() is called before the conversion event with at least an email or phone number.

Rate Limits

SettingDefault
rate_limit_rps50
rate_limit_burst100

Google Ads API has per-account rate limits that vary by account tier. The defaults above are conservative. If you have a high-volume account with elevated API quotas, you can increase these values in the integration’s advanced settings.

Signal automatically batches conversion uploads and handles retries with exponential backoff. If rate limits are hit, events are queued and retried without data loss.