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.
Google Ads Account
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.
- Sign in to Google Ads.
- Your Customer ID is displayed in the top-right corner of the dashboard, formatted as
123-456-7890. - 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.
- In Google Ads, navigate to Tools & Settings > Measurement > Conversions.
- Click + New Conversion Action.
- Select Import as the conversion source.
- Choose Other data sources or CRMs > Track conversions from clicks.
- Name the conversion action (e.g. “Website Purchase”, “Lead Form Submit”).
- Set the Category (e.g. Purchase, Lead, Sign-up), Value, and Count (one per click or every).
- Click Create and Continue.
- 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.
- In Google Ads, go to Tools & Settings > Measurement > Conversions.
- Click on the conversion action you created.
- Expand the Enhanced conversions section.
- Toggle Enhanced conversions on.
- Select Google Ads API as the method for sending enhanced conversion data.
- Accept the customer data terms.
- 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:
- Go to Google Cloud Console.
- Create a new project or select an existing one.
- Navigate to APIs & Services > Library.
- Search for Google Ads API and click Enable.
- Go to APIs & Services > Credentials.
- Click Create Credentials > OAuth Client ID.
- If prompted, configure the OAuth consent screen first (External or Internal depending on your organisation).
- Select Web application as the application type.
- Under Authorized redirect URIs, add:
https://developers.google.com/oauthplayground - Click Create.
- 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.
- Go to the OAuth 2.0 Playground.
- Click the gear icon (Settings) in the top-right corner.
- Check Use your own OAuth credentials.
- Enter your Client ID and Client Secret from the previous step.
- Close the settings panel.
- In the left panel under Step 1, find and expand Google Ads API (or manually enter the scope:
https://www.googleapis.com/auth/adwords). - Select the
https://www.googleapis.com/auth/adwordsscope. - Click Authorize APIs.
- Sign in with a Google account that has admin access to the Google Ads account you want to track conversions for.
- Grant the requested permissions.
- Back in the Playground, under Step 2, click Exchange authorization code for tokens.
- 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.
Link Manager Account (If Using MCC)
If you manage multiple Google Ads accounts through a Manager Account (MCC) and want to upload conversions to a child account:
- In your MCC dashboard, go to Tools & Settings > Setup > Linked accounts.
- Ensure the target account is linked and the link is accepted.
- Use the MCC Customer ID as the
customer_idin 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
| Field | Required | Type | Description |
|---|---|---|---|
customer_id | Yes | string | Your 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_id | Yes | string | The numeric ID of the conversion action in Google Ads. Found under Tools > Conversions, or in the URL when viewing the conversion action. |
oauth_credentials | Yes | secret | OAuth2 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
- Go to Integrations > Add Integration > Google Ads Conversions.
- Enter your Customer ID (e.g.
123-456-7890). - Enter your Conversion Action ID (e.g.
987654321). - Paste your OAuth credentials JSON into the OAuth Credentials field.
- Select consent categories (typically
advertising). - 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.
| Variant | Key | Description | Notable Defaults |
|---|---|---|---|
| Default | default | Standard conversion tracking for general-purpose campaign measurement and bid optimisation. | Enhanced conversions enabled, partial failure handling. |
| Retail | retail | E-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. |
| Travel | travel | Travel 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. |
| Media | media | Media 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:
| Signal | Source | Description |
|---|---|---|
gclid | URL parameter | Google Click ID. Automatically extracted from the landing page URL when a user clicks a Google Ads ad. This is the primary attribution identifier. |
wbraid | URL parameter | Web-to-app attribution identifier. Used for iOS conversions after ATT (App Tracking Transparency). Automatically extracted from the URL. |
gbraid | URL parameter | App-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:
| Signal | Hashing | Description |
|---|---|---|
email | SHA-256, lowercase, trimmed | User’s email address |
phone | SHA-256, E.164 format | User’s phone number (e.g. +44207946000) |
first_name | SHA-256, lowercase, trimmed | First name |
last_name | SHA-256, lowercase, trimmed | Last name |
street_address | SHA-256, lowercase, trimmed | Street address line |
city | SHA-256, lowercase | City |
state | SHA-256, lowercase | State or region |
postal_code | SHA-256, trimmed | Postal/zip code |
country | SHA-256, 2-letter ISO code | Country 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 Event | Google Ads Conversion | Notes |
|---|---|---|
Order Completed / Product Purchased | Purchase conversion | Requires value, currency. Maps to the configured conversion action. |
Lead Generated | Lead conversion | Configurable conversion action. |
Signed Up | Sign-up conversion | Configurable conversion action. |
Checkout Started | Begin Checkout conversion | Retail variant only. |
Product Added | Add to Cart conversion | Retail variant only. |
| Custom events | Custom conversion | Map 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:
- A user identifies themselves on your site (e.g. during checkout).
- You call
_df.identify()with their details (email, phone, etc.). - When a conversion event fires, Signal automatically includes the hashed user identifiers in the Google Ads API upload.
- 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.
Consent Mode
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 Signal | Mapped From | Description |
|---|---|---|
ad_user_data | context.consent.advertising | Consent to use data for advertising purposes. |
ad_personalization | context.consent.advertising | Consent 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:
- Trigger a test conversion on your site (e.g. complete a test purchase or submit a lead form).
- In Google Ads, navigate to Tools & Settings > Measurement > Conversions.
- Click on your conversion action.
- Check the Diagnostics tab — recent uploads should appear within a few hours.
- Conversion source should display as “Uploaded (from API)” or “Website (Enhanced conversions from API)”.
- 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:
- Go to Integrations and select your Google Ads integration.
- Check the Delivery Log for recent events.
- A
200response code withpartial_failure_erroras empty confirms successful delivery.
Troubleshooting
| Problem | Cause | Solution |
|---|---|---|
AUTHENTICATION_ERROR | Invalid or expired OAuth credentials. | Regenerate the refresh token using the OAuth Playground (Step 5 above) and update the credentials in Signal. |
AUTHORIZATION_ERROR | The 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_FOUND | Incorrect customer ID. | Verify the customer ID matches the account in Google Ads. If using MCC, ensure the child account is linked. |
CONVERSION_ACTION_NOT_FOUND | Incorrect 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_FOUND | The gclid is invalid or expired (>90 days). | Ensure gclid values are captured correctly. Google Click IDs expire after 90 days. |
| Conversions not appearing | Reporting delay. | Google Ads can take up to 24 hours to display uploaded conversions. Check Signal delivery logs for API success. |
TOO_MANY_CONVERSIONS_IN_REQUEST | Batch size exceeds Google’s limit. | Signal handles batching automatically. If this persists, contact support. |
DUPLICATE_CONVERSION | Same order_id or gclid + timestamp combination sent twice. | This is expected behaviour if events are retried. Google deduplicates on order_id. |
| Enhanced conversions not matching | User 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
| Setting | Default |
|---|---|
rate_limit_rps | 50 |
rate_limit_burst | 100 |
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.