All posts

Import Salesforce Closed-Won Deals into Google Ads

By Rajesh Kumar, Founder, Attribi ·

Google Ads reports 112 conversions at 41 dollars each while Salesforce shows 6 deals actually
closed worth 196,000 dollars. Nothing links the two until those 6 are sent back through offline
conversion import.

Google Ads counts a form fill and stops there. Your revenue arrives weeks later, in Salesforce, attached to an opportunity that Google has never heard of. Importing offline conversions closes that gap: when a deal reaches a won stage, you send it back to Google Ads with the click identifier that produced it, so Smart Bidding optimizes toward deals instead of forms. This guide covers the current setup end to end, including the two routes that have been retired and the one place the whole thing usually breaks.

The short answer

Capture the GCLID at the ad click, store it against the person, and when the Salesforce opportunity is won, upload the conversion through the Data Manager API into a Google Ads conversion action. If you have no click identifier, use enhanced conversions for leads, which matches on hashed email and phone instead, after you accept the customer data terms in Google Ads.

Two routes that no longer work

Most of the guides you will find describe one of these. Both are dead.

Two retired routes and the two that work now. The legacy Salesforce connector became unsupported
on 31 May 2025, and UploadClickConversions in the Google Ads API is blocked for developer tokens
with no prior upload history from 15 June 2026. Both current routes, click ID import and enhanced
conversions for leads, go through the Data Manager
API.

The native Salesforce connector. Google Ads used to offer Conversion Import for Salesforce, a built-in link that read your opportunities directly. Google stopped supporting it on 31 May 2025 and directs users to Data Manager instead. If your account still has a linked Salesforce data source from years ago, it is not doing anything for you.

UploadClickConversions in the Google Ads API. Since 15 June 2026, these requests fail if the developer token has not previously uploaded offline conversions or enhanced conversions for leads. Existing integrations with history keep working, so this reads as "everything is fine" right up until you build something new and it does not work. New builds go to the Data Manager API.

Step 1: Create the conversion action

In Google Ads, create a conversion action with Import as the source, then choose whether it records a value. Two settings matter more than the rest:

  • Count: use "one" for a closed deal. "Every" is for repeatable purchases and will inflate a B2B pipeline.
  • Click-through conversion window: set it to match your sales cycle, up to the 90 day maximum. A deal that closes outside the window is not counted, no matter how correct your upload is.

Note the numeric conversion action ID. You will need it, and the Data Manager API wants the plain number, not the full customers/.../conversionActions/... resource name.

Step 2: Capture the GCLID, and keep it alive

This is where almost every Salesforce implementation loses.

The GCLID arrives as a query parameter on the ad click. You capture it into a hidden form field and store it on the Salesforce Lead. So far so good. Then the Lead is converted, and a Contact and an Opportunity are created from it.

The click ID reaches the Lead record and stops there. On Lead conversion it does not travel to
the Contact or Opportunity unless the field mapping is configured, so the closed-won upload carries
no click ID and Google cannot match it.

Custom Lead fields do not travel through conversion on their own. You have to create the matching field on Contact or Opportunity and configure the lead conversion field mapping. If you skip it, the GCLID sits on a converted Lead record nobody queries, the Opportunity has no click identifier, and every upload matches nothing. The uploads still succeed. Google reports the file as processed. Nothing appears in your conversion column, and the reason is three objects upstream.

Two more constraints worth knowing before you design around GCLID:

  • 90 days. A conversion uploaded more than 90 days after the last click will not be imported. For B2B cycles that regularly run past a quarter, some of your best deals are structurally unmatchable this way.
  • Enhanced conversions for leads is stricter at 63 days, so the fallback path has a shorter reach than the click ID path, not a longer one.

Step 3: Decide between click ID and enhanced conversions

You do not have to choose. Send both when you have both.

GCLID importEnhanced conversions for leads
Matches onThe click itselfHashed email and phone
Match qualityHighestGood, lower than a click ID
Upload deadline after click90 days63 days
Survives a missing click IDNoYes
Extra setupCapture and store the GCLIDAccept the customer data terms in Google Ads

The terms acceptance is not optional and not cosmetic. If you send user-provided data without having accepted them, Google rejects the entire request, not the offending event, with DESTINATION_ACCOUNT_ENHANCED_CONVERSIONS_TERMS_NOT_SIGNED. One unaccepted checkbox can take down a whole night's batch.

Step 4: Send the conversion

Post to the Data Manager ingest endpoint:

POST https://datamanager.googleapis.com/v1/events:ingest
Authorization: Bearer {OAUTH_ACCESS_TOKEN}
{
  "destinations": [
    {
      "operatingAccount": {
        "accountType": "GOOGLE_ADS",
        "accountId": "1234567890"
      },
      "productDestinationId": "987654321"
    }
  ],
  "encoding": "HEX",
  "events": [
    {
      "eventTimestamp": "2026-08-20T14:03:00Z",
      "transactionId": "0065g00000ABCDE:closed_won",
      "conversionValue": 48000,
      "currency": "USD",
      "eventSource": "WEB",
      "adIdentifiers": { "gclid": "Cj0KCQjw_EXAMPLE" },
      "userData": {
        "userIdentifiers": [
          { "emailAddress": "b642b4217b34b1e8d3bd915fc65c4452" },
          { "phoneNumber": "b0b6d1a4c1b6a9d8f5e2c3a1b7d4e6f8" }
        ]
      }
    }
  ]
}

Details that cost people a day each:

  • conversionValue is the currency amount, not micros. The Google Ads API used micros for years, so this is an easy reflex to get wrong. 48000 means 48,000, not 0.048.
  • productDestinationId is the bare numeric conversion action ID. The resource name is rejected.
  • The Data Manager API takes only the OAuth bearer token. No developer token header, no login-customer-id header. It is simpler than the Google Ads API, which surprises people who have worked with the latter.
  • transactionId is your deduplication key. Make it deterministic per deal and stage so a retried job cannot book the same revenue twice.
  • Hash email and phone with SHA-256, and format the phone in E.164 with the leading plus sign. Meta wants digits with no plus. If you are sending to both platforms from one codebase, these two rules will collide at some point. The Meta half of this loop is covered in Send Salesforce Closed-Won Deals Back to Meta Ads.
  • The OAuth scope is https://www.googleapis.com/auth/datamanager, which is separate from the older adwords scope. An existing integration's token does not carry it.

Step 5: Confirm it actually matched

Check the conversion action's status in Google Ads, not the API response. A 200 means Google accepted your request, not that it credited a click. Give it up to a few hours, then look for a rising count on that conversion action. If it stays at zero while your uploads succeed, work backwards: is the click identifier present on the record you uploaded, was the click inside the window, and did the deal close inside the conversion window you configured in step 1.

Doing this with Attribi

Attribi connects Salesforce and Google Ads and runs this loop for you. Connect Salesforce, pick the stages that mean qualified and won in your own org, connect Google Ads, and won deals upload automatically.

The part that matters most is step 2, and Attribi solves it structurally rather than with better field mapping.

The click identifier lives outside Salesforce. Attribi's tracker records the GCLID against the visitor at the moment of the click, on a first-party cookie set from your own domain, and keeps it attached to that person. When a Salesforce opportunity is won, Attribi matches the deal to that person and uploads with the click identifier it already holds. Lead conversion cannot break the link, because the link was never stored on a Lead record. This also means the click identifier survives the Opportunity and Contact objects never carrying it, which is the specific reason Salesforce implementations tend to fall back to email-only matching.

Two more things you get:

Multi-touch attribution. The upload tells Google what happened. It does not tell you where to spend. Attribi records the whole journey across channels and lets you read the same closed deal through first touch, last touch, linear, position-based, and data-driven models, so you can see which channel opened the deal and not just which one closed it.

Salesforce gets the attribution written back. Attribi provisions 16 custom fields on the Salesforce Lead object and fills them at capture: first and last touch source, medium and campaign, the attribution path, touchpoint count, landing page, referrer, and the click identifier. Your reps see the origin of every lead inside the record they already work in.

The same connection covers Meta, LinkedIn, Microsoft, TikTok, and Snapchat, each with its own hashing and payload rules handled for you.

Connect Salesforce and Google Ads free.

Attribi compared with a direct Salesforce to Google Ads build

Direct buildAttribi
RouteYou build on Data ManagerConnect and map stages
GCLID survives Lead conversionOnly with correct field mappingHeld against the visitor, outside Salesforce
Enhanced conversions fallbackYou implement itAutomatic, with the terms state surfaced
Whole-request terms rejectionYou debug itDetected, retried on the click ID path, flagged in the UI
Micros and E.164 formattingYou get it right per platformHandled per platform
Other ad platformsA separate build eachSame connection covers six
Multi-touch attributionNot includedFive models across all channels
Attribution written into SalesforceNot included16 fields on the Lead object
Renamed won stageSilently stopsRead from the org's own won flag
CostEngineering timeFree tier, then paid plans

If you run Google Ads only, your sales cycle fits inside 90 days, and you have engineering time to own the field mapping and the retries, a direct build is a reasonable choice. The recurring cost is maintenance, and it is paid in silence: these integrations fail without erroring.

Frequently asked questions

Does the Salesforce to Google Ads conversion import still work? The legacy native connector is no longer supported as of 31 May 2025. Google directs Salesforce users to Data Manager, and new API-based integrations use the Data Manager API rather than UploadClickConversions.

Why do my uploads succeed while my conversion count stays at zero? Almost always a missing click identifier on the uploaded record. The most common cause in Salesforce is that the GCLID was stored on the Lead and never mapped through lead conversion to the Contact or Opportunity.

Can I import a Salesforce deal that closed six months after the click? Not with a GCLID. Google will not import a conversion uploaded more than 90 days after the last click, and enhanced conversions for leads is limited to 63 days. Long-cycle deals need a mid-funnel signal, such as a qualified stage, in addition to the won event.

What does DESTINATION_ACCOUNT_ENHANCED_CONVERSIONS_TERMS_NOT_SIGNED mean? You sent user-provided data before accepting the customer data terms in your Google Ads conversion settings. Google rejects the entire request rather than the single event, so the whole batch fails until the terms are accepted.

Should I send the click ID or hashed customer data? Send both when the record has both. The click identifier gives the strongest match and the hashed data covers the records where the click identifier is missing or the click has aged out.

Is conversionValue in micros? No. The Data Manager API takes the plain currency amount. Micros are a Google Ads API convention and sending them here inflates values by a million.

The takeaway

Two of the three routes into Google Ads have closed in the last eighteen months, so the first job is making sure you are building on the one that is still open. After that, everything depends on whether a click identifier can survive the trip from the ad to a won opportunity, across a Lead conversion that discards custom fields by default. Solve that, and Smart Bidding starts optimizing toward revenue instead of forms. Try Attribi free, or follow the steps above and build it yourself.


Attribi tracks every marketing touchpoint and pushes revenue back to your ad platforms, so campaigns optimize on closed deals — not raw form fills. See how it works or start free.