Some tips on handling duplicate errors when uploading keywords via the Bing Ads API

Sometimes when adding keywords to Bing Ads, you might be surprised to encounter a duplicate keyword error when the keywords actually have different text. This is due to a process called normalization where Bing Ads eliminates certain superfluous characters such as punctuation marks when comparing newly added keywords for certain languages. Examples of how this process works are in our help topic on duplicate keywords.

Since the normalization rules vary across different languages in Bing Ads, it is sometimes may be difficult for developers to come up with effective strategies for consistently dealing with duplicate keyword issues. This blog post is intended to share our current best practices for adding keywords to the Bing Ads system via the API.

General guidelines for adding keywords

To avoid unnecessary redundancy in your keywords please use this information while working with Bing Ads. These recommendation are valid for all languages supported by Bing Ads.

 Bing doesn’t differentiate keywords based on

-          Case-sensitivity (i.e. Milk and milk)

-          Number of white spaces or usage of tabs instead of whitespaces

-          Decorated characters and accent mark (i.e. café and café )

-          Numbers and date formats: there is no need to extensively add numbers and dates in different formats. Bing Ads will recognize any format you provide.

-          Punctuation characters (i.e. “car” and “car.” will be considered the same)

These recommendations should be kept in mind especially when using keyword expansion tools which may unnecessarily bloat your keyword list with keywords that are considered the same by Bing Ads.

Effective error handling when calling AddKeywords with multiple keywords

Bing Ads APIs allow performing bulk upload of keywords to your campaigns via the AddKeywords service operation. The AddKeywords operation accepts up to 1000 keywords in one batch. However a challenge with this batch operation mode is that the entire operation fails if there are any duplicates detected in the batch.  Duplicate detection includes failing the operation if two keywords have the same normalized form such as “Car” and “car”.

When writing code to add keywords to Bing Ads, it is recommended that you handle the exception that occurs when duplicate keywords are detected, retrieve the exact keywords that caused the failure from the exception details then retry the operation with the specified keywords omitted.

Below is the C# code that shows how to handle an exception that occurs as part of the AddKeywords call and then list out the duplicates that were detected

            catch (FaultException<EditorialApiFaultDetail> faultException)
            {
                const int CampaignServiceDuplicateKeyword = 1542;
                Console.WriteLine("Duplicate keywords detected: ");
                foreach (var error in faultException.Detail.BatchErrors.Where(error => error.Code == CampaignServiceDuplicateKeyword))
                {
                    Console.WriteLine("[{0}] {1}", error.Index, keywords[error.Index].Text);
                }
            }

An application can use the Index property of the error to locate the problem keyword from the original upload attempt, remove it and then retry the operation. 

Below is a more complete sample showing adding keywords, handling the duplicate error and then filtering out of problem keywords before retrying.

 

using System;

using System.ServiceModel;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using BingAdsPractice.BingAdsSandbox;

 

namespace BingAdsPractice

{

       class Program

       {

              static void Main(string[] args)

              {

            var client = new CampaignManagementServiceClient();

                     Keyword[] keywords = GenerateKeywordsArray("car", "SUV", "Car", "cars!", "car", "sedan", "SUV");

           

            try

            {

                // 1. Try to add keywords and detect if call will fail

                //

                client.AddKeywords(

                    new AddKeywordsRequest(null, Settings.CustomerAccountId, Settings.CustomerId,

                        Settings.DeveloperToken, Settings.Password, Settings.UserName, Settings.AdGroupId,

                        keywords));

            }

            catch (FaultException<EditorialApiFaultDetail> faultException)

            {

                const int CampaignServiceDuplicateKeyword = 1542;

                var duplicateKeywordIndexes = new List<int>();

 

                // 2. Retrieve information about duplicate keywords

                //

                foreach (var error in faultException.Detail.BatchErrors.Where(error => error.Code == CampaignServiceDuplicateKeyword))

                {

                    if (duplicateKeywordIndexes.Count == 0)

                    {

                        Console.WriteLine("Following keywords are considered to be duplicates:");                   

                    }

                    duplicateKeywordIndexes.Add(error.Index);

                    Console.WriteLine("[{0}] {1}", error.Index, keywords[error.Index].Text);

                }

 

                // 3. Retry to add keywords with filtered array

                //

                if (duplicateKeywordIndexes.Count > 0 && duplicateKeywordIndexes.Count < keywords.Length)

                {

                    // Filter keywords array

                    //

                    Keyword[] filteredKeywords = FilterKeywords(keywords, duplicateKeywordIndexes);

                    client.AddKeywords(

                        new AddKeywordsRequest(null, Settings.CustomerAccountId, Settings.CustomerId,

                           Settings.DeveloperToken, Settings.Password, Settings.UserName, Settings.AdGroupId,

                           filteredKeywords));

                }

            }

 

                     Console.Read();

              }

 

        private static Keyword[] GenerateKeywordsArray(params string[] keywords)

        {

            var keywordsList = new List<Keyword>();

            foreach (string k in keywords)

            {

                Keyword newKeyword = new Keyword()

                {

                    BroadMatchBid = null,

                    ExactMatchBid = new Bid { Amount = .1 },

                    Param2 = "10% Off",

                    PhraseMatchBid = null,

                    Text = k

                };

                keywordsList.Add(newKeyword);

            }

 

            return keywordsList.ToArray();

        }

 

        private static Keyword[] FilterKeywords(IEnumerable<Keyword> keywords, IEnumerable<int> indexesToRemove)

        {

            Keyword tempKeyword = new Keyword();

            List<Keyword> keywordToRemove = new List<Keyword>(keywords);

            foreach (var index in indexesToRemove)

            {

                keywordToRemove[index] = tempKeyword;

            }

            keywordToRemove.RemoveAll(k => k == tempKeyword);

            return keywordToRemove.ToArray();

        }

       }

}

A note on the usage of GetNormalizedStrings

Some developers use the GetNormalizedKeywords service operation to determine how to filter keywords before calling the AddKeywords service operation.  Using this method is not recommended. This method does not utilize the same normalization steps as the AddKeywords operation and more importantly is redundant given the previously shown sample about handling duplicate errors thrown by AddKeywords.

This method will be deprecated in the next major release of the Bing Ads API which should be before the end of the year. Below is the current description of the behavior of the method

 

Language ID

Current normalization behavior

“English”, “French”, “Traditional Chinese”, “Portuguese”

Returns normalized version of keyword, stop words removed.

“German”

Returns normalized version of keyword, stop words are not removed.

All other languages

Returns the input keyword with no normalization applied

 

Note: Portuguese is currently not supported in Bing Ads but will be in the future.

 

Dare Obasanjo

Program Manager, Bing Ads Platform