Uploading Enhanced conversion via REST API (not client library)

2,088 views
Skip to first unread message

MKostrosO2

unread,
Aug 8, 2023, 10:10:02 AM8/8/23
to Google Ads API and AdWords API Forum

Hey folks,

it has took me some time to go through the docs, forums or another sources, but I haven't found an answer, so hopefully I'll be more successful here. 

I'm preparing custom integration for Uploading enhanced conversions. As I'm using a CRM system able to comunicate via REST API, I need to prepare simple HTTPS request to upload enhanced conversion.
I'm not able to use any programming language, such as python, java, etc, so current documentation with examples using GoogleAdsClient is not helpful enough for me :/.

Will be grateful for any help/example, how to prepare REST API request, analogy to the script upload_conversion_with_identifiers.py

So I'm looking for:


Thank you for any details in andvance.

 

Regards,

Marius Kostros

Google Ads API Forum Advisor

unread,
Aug 8, 2023, 12:14:06 PM8/8/23
to marius....@o2.cz, adwor...@googlegroups.com

Hi Marius,

Thank you for reaching out to Google Ads API Forum.

For the REST method in uploading enhanced conversions, you may refer to the REST method customers.uploadClickConversions for the request url and request body structure. You may also utilize the api explorer customers.uploadClickConversions to test out the method. 

For your reference, you may refer to this guide for uploading Enhanced Conversions for Leads.

Let us know if you have additional questions.
 

This message is in relation to case "ref:_00D1U1174p._5004Q2nd55H:ref"

Thanks,
 
Google Logo Google Ads API Team


MKostrosO2

unread,
Aug 9, 2023, 4:28:09 AM8/9/23
to Google Ads API and AdWords API Forum
Thank you for your help.
I've managed to prepare whole request and it's working.

I have just no idea which conversions could be updated this way.
I've tried few of them, but with the request body:

    body = {
        "conversions": [
            {
                "user_identifiers": [
                    {
                      "hashedEmail": {HASHED_EMAIL},
                      "userIdentifierSource": "FIRST_PARTY"
                    }
                ],
                "conversionAction": "customers/{CUSTOMER_ID}/conversionActions/{CONVERSION_ACTION_ID}",
                "conversionDateTime": {CONVERSION_DATE_TIME}
            }
        ],
        "partialFailure": True,
        "validateOnly": True,
        "debugEnabled": True
    }

I get the error:

"errorCode": {"conversionUploadError": "CLICK_NOT_FOUND"},
"message": "The click can't be found for the specified identifiers. This may be because it did not come from a Google Ads campaign."

Let's say I'm trying to update this conversionAction"

"conversionAction": {
        "resourceName": "customers/ {CUSTOMER_ID}/conversionActions/{CONVERSION_ACTION_ID}",
        "status": "ENABLED",
        "type": "WEBPAGE",
        "category": "DEFAULT",
        "id": "{CONVERSION_ACTION_ID}",
        "name": "xXx",
        "ownerCustomer": "customers/{CUSTOMER_ID}"
      }

I suppose this is not supported by uploadConversionAction, but could you please help how to create one, which will work ?
Maybe how to create one within Google Ads GUI, that will be updateable via API ?

Grateful for any help.

Regards,
Marius Kostros

MKostrosO2

unread,
Aug 9, 2023, 6:13:28 AM8/9/23
to Google Ads API and AdWords API Forum
According to docs UploadClickConversionsRequest, do I understand well, that it's expected behaviour ?

my payload once again:

    body = {
        "conversions": [
            {
                "user_identifiers": [
                    {
                      "hashedEmail": {HASHED_EMAIL},
                      "userIdentifierSource": "FIRST_PARTY"
                    }
                ],
                "conversionAction": "customers/{CUSTOMER_ID}/conversionActions/{CONVERSION_ACTION_ID}",
                "conversionDateTime": {CONVERSION_DATE_TIME}
            }
        ],
        "partialFailure": True,
        "validateOnly": True,
        "debugEnabled": True
    }


If debug_enabled true, the API will perform all upload checks and return errors if any are found. If false, it will perform only basic input validation, skip subsequent upload checks, and return success even if no click was found for the provided user_identifiers.

This setting only affects Enhanced conversions for leads uploads that use user_identifiers instead of GCLIDGBRAID, or WBRAID. When uploading enhanced conversions for leads, you should upload all conversion events to the API, including those that may not come from Google Ads campaigns. The upload of an event that is not from a Google Ads campaign will result in a CLICK_NOT_FOUND error if this field is set to true. Since these errors are expected for such events, set this field to false so you can confirm your uploads are properly formatted but ignore CLICK_NOT_FOUND errors from all of the conversions that are not from a Google Ads campaign. This will allow you to focus only on errors that you can address.

Default is false.


MKostrosO2

unread,
Aug 9, 2023, 6:24:15 AM8/9/23
to Google Ads API and AdWords API Forum
So my question is, how to check, whether it works properly? How to check it processed request (for example in Google Ads GUI), as the only information I get is repsonse 200 with jobId
Thank you very much for help.



MKostrosO2

unread,
Aug 9, 2023, 7:29:22 AM8/9/23
to Google Ads API and AdWords API Forum
Note, that next steps from documentation does not work properly.
Upload summary is mentioned there - Next steps - but query from Update summary:
SELECT
  customer
.id,
  customer
.conversion_tracking_setting.google_ads_conversion_customer,
  customer
.offline_conversion_client_summaries
FROM customer

The query takes a while, however after a few minutes, I get only response:

{
  'results': [
    {
      'customer': {
        'resourceName': 'customers/92******29',
        'conversionTrackingSetting': {
          'googleAdsConversionCustomer': 'customers/92******29'
        },
        'id': '92******29'
      }
    }
  ],
  'fieldMask': 'customer.id,customer.conversionTrackingSetting.googleAdsConversionCustomer,customer.offlineConversionClientSummaries'
}

No daily summary as mentioned in docs

Google Ads API Forum Advisor

unread,
Aug 9, 2023, 8:41:37 AM8/9/23
to marius....@o2.cz, adwor...@googlegroups.com

Hi,

 

Thank you for your response.

 

Moving forward to your question on how to create request for conversionAction, you may refer to the following documentations:

 

Regarding your concern on how to determine if the request was successful/works properly, then you can set the debug_enabled to true, so that it will return errors if any are found. In addition, based on your sample request provided, you set "validateOnly": True. If this field is true, then the request is validated but not executed. Only errors are returned, not results. Kindly set this to false if you'd like the request to be executed. Once your request is successful, you may refer here for a sample response.

 

Let me know if you have any questions.
 

MKostrosO2

unread,
Aug 9, 2023, 9:51:45 AM8/9/23
to Google Ads API and AdWords API Forum
Thank you for your response.
I've read the documentation you shared, however is it necessary to create it via API ? I would prefer GUI, as it is only one-time task for testing, so it would be much more effective.

Nevertheless, your point about validateOnly was helpful, somehow I haven't realized it before.
Now I'm getting response as described in documentation:

{
  "results": [
    {
      "conversionAction": "customers/92*******29/conversionActions/101*******55",
      "conversionDateTime": "2023-08-08 09:30:00+02:00",
      "userIdentifiers": [
        {
          "userIdentifierSource": "FIRST_PARTY",
          "hashedEmail": "bc192bb8953b2a2bc4d256c80f932e0b548665dd949342a137e6ba744be44975"
        }
      ]
    }
  ],
  "jobId": "438902809389824964"
}

I suppose this means it's working properly.
However, I can not see any change in Google Ads GUI for the used Conversion.

As mentioned below, I'm still not able to use the query
SELECT
  customer.id,
  customer.conversion_tracking_setting.google_ads_conversion_customer,
  customer.offline_conversion_client_summaries
FROM customer


To see statistics of updated offline conversions..

Any ideas ?
Thx

Triple A

unread,
Aug 10, 2023, 4:15:33 AM8/10/23
to Google Ads API and AdWords API Forum
I'm quite amazed at how poor google API is regarding this. 
Any other provider let's you easily report conversions with just a curl
etc...)
 and then we have Google, wasting everyones time by giving complex flows that require entire SDKs for simple tasks.

It takes minutes of not seconds to implement a conversion on Tiktok, Facebook, etc.. & it takes hours if not days for Google.

Google Ads API Forum Advisor

unread,
Aug 10, 2023, 9:07:17 AM8/10/23
to veng...@gmail.com, adwor...@googlegroups.com

Hi everyone,

 

@ Marius,

 

If you'd like to do this via the UI, then it would be best to ask for assistance from the Google Ads Product support team as they are more familiar with the features and functionalities of the Google Ads UI. You can reach them here: https://support.google.com/google-ads/gethelp

 

Moving forward to your issue of not being able to use Monitor upload summaries, can you elaborate on the issue or if you encountered any error kindly provide privately the Complete request and response logs, with the request-id generated for the error. Make sure to send this privately via the "Reply to author" option. If this option is not available on your end, you may send it through our email (googleadsa...@google.com) instead.

 

Looking forward to your response.

 

@ Triple A team

 

Thank you for your insights. Unfortunately we would not be able to comment further on other platforms' features. From the Google Ads AI perspective, you can refer to our documentation on Conversion Management on how to achieve this via the API.

MKostrosO2

unread,
Aug 14, 2023, 3:41:05 AM8/14/23
to Google Ads API and AdWords API Forum
Monitoring upload summaries (with query via googleAds:search API) suddenly started to work. The query passes the query validator (maybe some fix on google side, I have no idea).

However, my uploads were not successful, see the summary:
            'alerts': [
              {
                'error': {
                  'conversionUploadError': 'CLICK_NOT_FOUND'
                },
                'errorPercentage': 1
              }
            ]


As mentioned below, you recommended to turn of debuging

        "conversions": [
            {
                "user_identifiers": [
                    {
                      "hashedEmail": {HASHED_EMAIL},
                      "userIdentifierSource": "FIRST_PARTY"
                    }
                ],
                "conversionAction": f"customers/{CUSTOMER_ID}/conversionActions/{CONVERSION_ACTION_ID}",
                "conversionDateTime": {CONVERSION_DATE_TIME},
                "conversionValue": 10,
                "currencyCode": "CZK"
            }
        ],
        "partialFailure": True,
        "validateOnly": False,
        "debugEnabled": False
    }


However, with debugging set to false, the request is accepted by uploadClickConversion, but at the end of the day it leads to error anyway.
If I understand it well from docs, it's caused by the fact, that I'm sending EMAIL address and conversionDateTime, which can not be paired with real click tracked in Google Ads.

Then my question is, what's the purpose of uploading conversions via API, when I'm not able to create new ones without previous "evidence" of a click in Google ?
Or am I doing something wrong ?
Or the only purpose is to update existing conversions (match them with any orders, campaigns, etc)?

Am I able to create new conversions, or not at all ?

Thanks for any help, all these "excercises" to prepare API integration becomes really frustrating :/

Google Ads API Forum Advisor

unread,
Aug 14, 2023, 7:37:33 AM8/14/23
to marius....@o2.cz, adwor...@googlegroups.com

Hello,

Thank you for getting back to us.

Upon checking your error message, you are getting a CLICK_NOT_FOUND error, the click can't be found for the specified identifiers. This may be because it did not come from a Google Ads campaign(https://developers.google.com/google-ads/api/reference/rpc/v14/ConversionUploadErrorEnum.ConversionUploadError#click_not_found).

Please note that based on our Code Example found here(https://developers.google.com/google-ads/api/docs/conversions/upload-clicks#code_example), You need to associate your offline click conversions with a conversion action by passing either the gclidgbraid, or wbraid identifier. In addition, provide the conversion date timeconversion action resource name and optionally the conversion value and currency to ConversionUploadService.

Additionally, there are several requirements that must be met when uploading a ClickConversion, for more information on these requirements please refer to this section of the documentation(https://developers.google.com/google-ads/api/docs/conversions/upload-clicks#upload_clickconversion).

Can you also please provide us with the full API logs(request and response with request ID) and the respective IDs of these resources which caused this error to occur? I am asking for this so we can check on our end the error and provide precise recommendations.

You can provide it via Reply privately to the author option. If this option is not available, then send it instead on this email address googleadsa...@google.com

MKostrosO2

unread,
Aug 16, 2023, 2:45:18 AM8/16/23
to Google Ads API and AdWords API Forum
Thanks for response,

but, with every answer I'm not sure, whether we're moving forward or backwards.
You say - You need to associate your offline click conversions with a conversion action by passing either the gclidgbraid, or wbraid identifier
And you referencing me to Upload Click Conversionsbut let me summarize the conversation again:
1. I'm preparing process for Uploading Enhanced conversions for Leads (using hashed Email/Phone as user_identifier)
2. Then I was redirected to REST API method customer.uploadClickConversions (using hashed Email/Phone as user_identifier) - as a detailed description of REST API for enhanced conversions
3. Currently, Google Ads account accept my requests, but after few hours I see in monitor summaries, that the uploads failed according to CLICK_NOT_FOUND error

And now, you are redirecting me to upload-clicks using gclidgbraid, or wbraid, instead of enhanced conversions using user_identifiers (email, phone) - about which I'm speaking about.
Could we please try to keep a consistency in this conversion ? Because now we're only going in circles :(

Thank you!

Google Ads API Forum Advisor

unread,
Aug 16, 2023, 8:14:24 AM8/16/23
to marius....@o2.cz, adwor...@googlegroups.com

Hi,

 

Thank you for getting back and providing your insights on this. Allow me to raise your concern to our wider team for further investigation on the matter. Rest assured that one of our colleagues will get back to update this thread soon.

 

In the meantime, your patience is greatly appreciated.

Google Ads API Forum Advisor

unread,
Aug 16, 2023, 2:18:55 PM8/16/23
to adwor...@googlegroups.com, marius....@o2.cz
Hi:

The case was passed to me and I have read all of the correspondence, but I'm not clear on the problem you are trying to solve.

You provided:

"conversionAction": {
        "resourceName": "customers/ {CUSTOMER_ID}/conversionActions/{CONVERSION_ACTION_ID}",
        "status": "ENABLED",
        "type": "WEBPAGE",
        "category": "DEFAULT",
        "id": "{CONVERSION_ACTION_ID}",
        "name": "xXx",
        "ownerCustomer": "customers/{CUSTOMER_ID}"
      }

but later:
You reference uploading enhanced conversions for leads. This is the latest correspondence. Can you confirm that your attempting to upload enhanced conversions for leads via the REST API?

There has been a lot of back and forth, so please verify that my understanding of the following points are correct:
  • You are uploading enhanced conversions for leads and NOT web. https://support.google.com/google-ads/answer/9888656#leads
  • You are using the REST API.
  • You are able execute a REST request without error.
  • When you query the summary for the status of your upload you receive the error CLICK_NOT_FOUND for this conversion upload.


A couple of things I notice in the request and response that you sent. The response specifies "jobId": "20887662158502278", but this does is not in the list of jobs in your request for a summary. This is most likely because it has not yet been processed on our side. It generally takes about 24 hours.

The alert in the response is, we realize, less than ideal. The error CLICK_NOT_FOUND can not be attributed to a specific job. It means one of the jobs in the summary has this error. Since your job does not appear in the summary, this particular error cannot be attributed to the job in your request.

The most common reason for CLICK_NOT_FOUND it when a non-Google conversion is uploaded. You can get this error immediately if in your request you set debug and partial failure to true. With these setting, the error will appear in your response. This is most useful when developing your application.

I'm sure you have already read it, but I recommend reviewing https://developers.google.com/google-ads/api/docs/conversions/upload-identifiers

 

This message is in relation to case "ref:_00D1U1174p._5004Q2nd55H:ref"

Thanks,
 
Google Logo
Bob Hancock
Google Ads API Team


MKostrosO2

unread,
Aug 17, 2023, 2:30:20 AM8/17/23
to Google Ads API and AdWords API Forum
Hey Bob,

thanks for joining the conversation.

    • YES, there was maybe quite a misunderstanding (also from my side) during to implementation, but YES, this is what I need to achieve
  • You are using the REST API.
  • You are able execute a REST request without error.
    • YES, if I turn off debuging ("debugEnabled": False). I'm providing whole payload with response below once again.
  • When you query the summary for the status of your upload you receive the error CLICK_NOT_FOUND for this conversion upload.
    • It's not quite a clear, as there is a summary of uploads for last week and then jobSummaries. See the example below
I've also waited more than 24 hours and then checked the summaries, so this is not the case..
The error CLICK_NOT_FOUND has percentage = 1, I'm not sure, but maybe it means 100% of jobs listed within the summary failed with this error ?

You can get this error immediately if in your request you set debug and partial failure to true. With these setting, the error will appear in your response. This is most useful when developing your application.
Yes, I was working with this settings. However, then I was recommended to set debugEnabled to False.

Here's a full example of my request & response:

    headers = {
        'content-type': 'application/json',
        'Authorization': 'Bearer ' + {ACCESS_TOKEN},
        "login-customer-id": "{CUSTOMER_ID}",
        "developer-token": "{DEVELOPER_TOKEN}"
    }
   
   
    body = {

        "conversions": [
            {
                "user_identifiers": [
                    {
                      "hashedEmail": {HASHED_EMAIL},
                      "userIdentifierSource": "FIRST_PARTY"
                    }
                ],
                "conversionAction": "customers/{CUSTOMER_ID}/conversionActions/{CONVERSION_ACTION_ID}",

                "conversionDateTime": {CONVERSION_DATE_TIME},
                "conversionValue": 10,
                "currencyCode": "CZK"
            }
        ],
        "partialFailure": True,
        "validateOnly": False,
        "debugEnabled": False
    }
  
   
With "debugEnabled": False Google accepts the request with response 200 and body:
{
  "results": [
    {
      "conversionAction": "customers/{CUSTOMER_ID}/conversionActions/{CONVERSION_ACTION_ID}",
      "conversionDateTime": "2023-08-17 07:58:16+02:00",
      "userIdentifiers": [
        {
          "userIdentifierSource": "FIRST_PARTY",
          "hashedEmail": "1216daeb8ce98dd9a47a40c301a32dcdde3a4c663318da09163d0f4b8c0ad8ce"
        }
      ]
    }
  ],
  "jobId": "7191316501863973724"
}


For now it's still not processed by google, so I will not find the jobId in monitor summary, but I've tested very same request few times during past days and it's still same:
{
  'results': [
    {
      'customer': {
        'resourceName': 'customers/
{CUSTOMER_ID}',
        'conversionTrackingSetting': {
          'googleAdsConversionCustomer': 'customers/
{CUSTOMER_ID}'
        },
        'id': '
{CUSTOMER_ID}',
        'offlineConversionClientSummaries': [
          {
            'client': 'GOOGLE_ADS_API',
            'status': 'NEEDS_ATTENTION',
            'totalEventCount': '1',
            'lastUploadDateTime': '2023-08-16 08:21:20.75725',
            'dailySummaries': [
              {
                'uploadDate': '2023-08-09',
                'failedCount': '1'
              },
              {
                'uploadDate': '2023-08-10',
                'failedCount': '3'
              },
              {
                'uploadDate': '2023-08-11',
                'failedCount': '6'
              },
              {
                'uploadDate': '2023-08-14',
                'failedCount': '3'
              },
              {
                'uploadDate': '2023-08-15',
                'failedCount': '1'
              },
              {
                'uploadDate': '2023-08-16',
                'failedCount': '1'
              }
            ],
            'jobSummaries': [
              {
                'jobId': '108445157845911769',
                'failedCount': '1'
              },
              {
                'jobId': '2615533122696232816',
                'failedCount': '1'
              },
              {
                'jobId': '4007121670900219769',
                'failedCount': '1'
              },
              {
                'jobId': '4244552316996877552',
                'failedCount': '1'
              },
              {
                'jobId': '4540552247167422733',
                'failedCount': '1'
              },
              {
                'jobId': '7538745964134905049',
                'failedCount': '1'
              },
              {
                'jobId': '8510561100029352245',
                'failedCount': '1'
              }
            ],

            'alerts': [
              {
                'error': {
                  'conversionUploadError': 'CLICK_NOT_FOUND'
                },
                'errorPercentage': 1
              }

            ]
          }
        ]
      }
    }
  ],
  'fieldMask': 'customer.id,customer.conversionTrackingSetting.googleAdsConversionCustomer,customer.offlineConversionClientSummaries'
}


However, note, that the Email address is not the real conversion, only an gmail address.

So, to be more specific. Could you please guide me, or answer the specific question:
  • As I'm developing the process, I have no real conversions
    • How am I able to E2E test the integration. I imagine the situation, that I send the request mentioned above, see some success in monitor summary and see some change in Conversion in Google Ads GUI as well. Is this possible, or it does not work like this ?
  • I think I should prepare the RESP API request vith "debugEnabled": True, but I'm not able to get through the CLICK_NOT_FOUND error here. How to do so, or how to replicate real conversion, so I can verify everything with my integration is working properly?

Thank you for any valuable details in advance.

Google Ads API Forum Advisor

unread,
Aug 17, 2023, 9:29:57 AM8/17/23
to marius....@o2.cz, adwor...@googlegroups.com
Thanks for the detailed response. Unfortunately, there is no way to perform the type of E2E testing with your current setup. The conversions process needs PII (the hashed email in your case) and the accompanying GCLID forwarded from a website to start the process. Otherwise, it will respond with CLICK_NOT_FOUND.

The way I've seen other users do this is to create a test account in Ads and then have a development website where you setup a lead form and then click on it to generate your own test conversions.

Kudos, on working through the process to get the correct REST request and wanting to perform E2E testing. 

MKostrosO2

unread,
Aug 18, 2023, 2:57:21 AM8/18/23
to Google Ads API and AdWords API Forum
OK, thank you.
I understand, that this means my integration should work properly then.
Let's go through example scenario and please validate every step, whether this will work or not:

  1. Customer is targeted with some Google ad
  2. He clicks through it and is redirected to my website, moreover, the URL contains parameter gclid
    • does google store this information, is it the lead we need before we can send enhanced conversion via REST API discussed above?
    • if so, is it stored even if customer does not allow marketing (or any other cookies on website) - in case this is his very first website visit ?
  3. Am I subsequently ready to send enhanced conversion? Or should I firstly create the lead using gclid from URL and then I have everything prepared for enhanced conversion (in case of any customer offline action)
And I'm a bit confused by this: "The conversions process needs PII (the hashed email in your case) and the accompanying GCLID forwarded from a website"
If the steps I've described will work, how does google merge the conversion ?
- does it work like - gclid is connected to a customer's email address, so when I send enhanced conversion (with PII but no gclid), the email will be merged with previous lead's gclid ?
This does not make sense, a customer could have clicked on more ads, so I suppose I'm not right :/

I'm grateful for your time, help and additional information.

Regards,
Marius

MKostrosO2

unread,
Aug 22, 2023, 10:12:33 AM8/22/23
to Google Ads API and AdWords API Forum
Are you able to answer the questions/notes from the last reply?
Thank you in advance.

Have a nice day

Google Ads API Forum Advisor

unread,
Nov 2, 2023, 2:22:10 PM11/2/23
to marius....@o2.cz, adwor...@googlegroups.com
Hi,

Thank you for getting back to us. Apologies for the delay in the response.

By reviewing your concern, I understand that you had queries related to upload offline click conversions via Google Ads API. Please refer to this link for more information on conversions. According to the documentation, conversion actions can be used to upload offline click conversions into Google Ads by setting the conversion action type to UPLOAD_CLICKS.

Moreover, I would suggest you to refer to this help center article to get more information on storage of GCLID's. Also I would recommend you to refer to this link to know more about the required fields for each conversion operation.

If you still have concerns related to conversions, please get back to us with the uncropped UI screenshot of the issue along with some description and complete API request and response logs.
 
This message is in relation to case "ref:!00D1U01174p.!5004Q02nd55H:ref"

Thanks,
 
Google Logo Google Ads API Team


Reply all
Reply to author
Forward
0 new messages