Skip to content

Latest commit

 

History

History
1409 lines (1061 loc) · 41.8 KB

code-example-manage-catalogs.md

File metadata and controls

1409 lines (1061 loc) · 41.8 KB
title description author ms.service ms.topic ms.author dev_langs
Managing Catalogs Code Example
Code sample showing how to manage catalogs with the Content API.
jonmeyers
bing-ads-shopping-content
article
jonmeyers
csharp
java
python
php

Managing Catalogs Code Example

This desktop console example shows how to get, add, update, and delete catalogs in the specified store.

For information about the catalog-related classes used by this example, see Catalogs and Catalog. For information about working with catalogs, see Managing your Catalogs.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Threading.Tasks;
using System.Net;
using Content.OAuth;
using Newtonsoft.Json;           // NuGet Json.NET

namespace Catalogs
{
    class Program
    {
        // The application ID that you were given when you
        // registered your application.

        private static string clientId = "<APPLICATIONIDGOESHERE>";
        private static string storedRefreshToken = "<REFRESHTOKENGOESHERE>";
        private static CodeGrantOauth tokens = null;
        private static DateTime tokenExpiration;

        private static string devToken = "<DEVELOPERTOKENGOESHERE>";

        // URI templates used to get resources.

        public const string BaseUri = "https://content.api.bingads.microsoft.com/shopping/v9.1";
        public static string BmcUri = BaseUri + "/bmc/{0}";
        public static string CatalogsUri = BmcUri + "/catalogs";
        public static string CatalogUri = CatalogsUri + "/{1}";

        // Replace with your store id.

        public static ulong merchantId = <STOREIDGOESHERE>;

        static void Main(string[] args)
        {
            try
            {
                var headers = GetCredentialHeaders();

                // Build the catalogs endpoint URL.

                var url = string.Format(CatalogsUri, merchantId);

                // Get and print the current list of catalogs.

                var collection = GetResource(url, headers, typeof(CatalogCollection)) as CatalogCollection;
                PrintCatalogs(collection);

                // Add a couple of catalogs.

                var catalogs = AddCatalogs(url, headers);

                // Get and print the current list of catalogs.

                collection = GetResource(url, headers, typeof(CatalogCollection)) as CatalogCollection;
                PrintCatalogs(collection);

                // Update the first catalog that we added
                // to enable it for publishing. When you update the 
                // catalog, you must specify both Name and IsPublishingEnabled.

                Console.WriteLine("*** Updating Catalog ***\n");
                var catalogUrl = string.Format(CatalogUri, merchantId, catalogs[0].Id);
                var catalog = new Catalog()
                {
                    Name = catalogs[0].Name,
                    IsPublishingEnabled = true
                };
                UpdateResource(catalogUrl, headers, catalog);

                // Get and print the updated catalog.

                var updatedCatalog = GetResource(catalogUrl, headers, typeof(Catalog)) as Catalog;
                PrintCatalogDetails(updatedCatalog);

                // Delete the catalogs that we created.

                DeleteCatalogs(CatalogUri, headers, merchantId, catalogs);

                // Get and print the current list of catalogs.

                collection = GetResource(url, headers, typeof(CatalogCollection)) as CatalogCollection;
                PrintCatalogs(collection);
            }
            catch (WebException e)
            {
                Console.WriteLine("\n" + e.Message);

                HttpWebResponse response = (HttpWebResponse)e.Response;

                // If the request is bad, the API returns the errors in the 
                // body of the request. For cases where the path may be valid, but
                // the resource does not belong to the user, the API returns not found.

                if (HttpStatusCode.BadRequest == response.StatusCode ||
                    HttpStatusCode.NotFound == response.StatusCode ||
                    HttpStatusCode.InternalServerError == response.StatusCode)
                {
                    using (Stream stream = response.GetResponseStream())
                    {
                        StreamReader reader = new StreamReader(stream);
                        string json = reader.ReadToEnd();
                        reader.Close();

                        // Deserialize error string into errors object.

                        try
                        {
                            var errors = JsonConvert.DeserializeObject<ContentError>(json);

                            PrintErrors(errors);
                        }
                        catch (Exception deserializeError)
                        {
                            // This case occurs when the path is not valid.

                            if (HttpStatusCode.NotFound == response.StatusCode)
                            {
                                Console.WriteLine("Path not found: " + response.ResponseUri);
                            }
                            else
                            {
                                Console.WriteLine(deserializeError.Message);
                            }
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("\n" + e.Message);
            }
        }

        // Gets catalog data from the store.
        
        private static object GetResource(string uri, WebHeaderCollection headers, Type resourceType)
        {
            object resource = null;
            var request = (HttpWebRequest)WebRequest.Create(uri);
            request.Method = "GET";
            request.Headers = headers;
            request.Accept = "application/json";
            var response = (HttpWebResponse)request.GetResponse();

            using (Stream responseStream = response.GetResponseStream())
            {
                var reader = new StreamReader(responseStream);
                string json = reader.ReadToEnd();
                reader.Close();
                resource = JsonConvert.DeserializeObject(json, resourceType);
            }

            return resource;
        }

        // Adds a catalog to the store.
        
        private static Catalog AddResource(string uri, WebHeaderCollection headers, Catalog catalog)
        {
            var request = (HttpWebRequest)WebRequest.Create(uri);
            request.Method = "POST";
            request.Headers = headers;
            request.ContentType = "application/json";

            var json = JsonConvert.SerializeObject(catalog);
            request.ContentLength = json.Length;
            using (Stream requestStream = request.GetRequestStream())
            {
                StreamWriter writer = new StreamWriter(requestStream);
                writer.Write(json);
                writer.Close();
            }

            var response = (HttpWebResponse)request.GetResponse();

            Catalog catalogOut = null;

            using (Stream responseStream = response.GetResponseStream())
            {
                var reader = new StreamReader(responseStream);
                var jsonOut = reader.ReadToEnd();
                reader.Close();
                catalogOut = JsonConvert.DeserializeObject<Catalog>(jsonOut);
            }

            return catalogOut;
        }

        // Updates a catalog's attributes.
        
        private static ulong UpdateResource(string uri, WebHeaderCollection headers, Catalog catalog)
        {
            var request = (HttpWebRequest)WebRequest.Create(uri);
            request.Method = "PUT";
            request.Headers = headers;
            request.ContentType = "application/json";

            var json = JsonConvert.SerializeObject(catalog);
            request.ContentLength = json.Length;
            using (Stream requestStream = request.GetRequestStream())
            {
                StreamWriter writer = new StreamWriter(requestStream);
                writer.Write(json);
                writer.Close();
            }

            var response = (HttpWebResponse)request.GetResponse();

            Catalog catalogOut = null;

            using (Stream responseStream = response.GetResponseStream())
            {
                var reader = new StreamReader(responseStream);
                var jsonOut = reader.ReadToEnd();
                reader.Close();
                catalogOut = JsonConvert.DeserializeObject<Catalog>(jsonOut);
            }

            return catalogOut.Id;
        }

        // Deletes a catalog from the store.
        
        private static ContentError DeleteResource(string uri, WebHeaderCollection headers)
        {
            var request = (HttpWebRequest)WebRequest.Create(uri);
            request.Method = "DELETE";
            request.ContentType = "application/json";
            request.Headers = headers;

            var response = (HttpWebResponse)request.GetResponse();

            ContentError error = null;

            using (Stream responseStream = response.GetResponseStream())
            {
                var reader = new StreamReader(responseStream);
                var jsonOut = reader.ReadToEnd();
                reader.Close();
                error = JsonConvert.DeserializeObject<ContentError>(jsonOut);
            }

            return error;
        }

        private static List<Catalog> AddCatalogs(string url, WebHeaderCollection headers)
        {
            var catalogs = new List<Catalog>();

            Console.WriteLine("*** Adding Catalogs ***\n");

            // This catalog is not enabled for publishing.

            var catalog = new Catalog()
            {
                Name = "Mens Apparel",
                Market = "en-US",
                IsPublishingEnabled = false
            };

            catalogs.Add(AddResource(url, headers, catalog));

            // This catalog is enabled for publishing.

            catalog = new Catalog()
            {
                Name = "Womens Apparel",
                Market = "en-US",
                IsPublishingEnabled = true
            };

            catalogs.Add(AddResource(url, headers, catalog));

            return catalogs;
        }

        private static void DeleteCatalogs(string uri, WebHeaderCollection headers, ulong merchantId, List<Catalog> catalogs)
        {
            Console.WriteLine("*** Deleting Catalogs ***\n");

            foreach (var catalog in catalogs)
            {
                // Build the endpoint URL.

                var url = string.Format(uri, merchantId, catalog.Id);

                // Delete the catalog from the store.

                var errors = DeleteResource(url, headers);

                if (errors != null)
                {
                    Console.WriteLine("Error deleting catalog: " + catalog.Id);
                    PrintErrors(errors);
                }
                else
                {
                    Console.WriteLine("Deleted catalog: " + catalog.Id);
                }
            }

            Console.WriteLine();
        }

        private static void PrintCatalogs(CatalogCollection collection)
        {
            Console.WriteLine("There are " + collection.Catalogs.Count + " catalogs.\n");

            foreach (Catalog catalog in collection.Catalogs)
            {
                PrintCatalogDetails(catalog);
            }
        }

        // Print catalog details.

        private static void PrintCatalogDetails(Catalog catalog)
        {
            Console.WriteLine("Name: " + catalog.Name);
            Console.WriteLine("ID: " + catalog.Id);
            Console.WriteLine("Market: " + catalog.Market);
            Console.WriteLine("IsDefault: " + catalog.IsDefault);
            Console.WriteLine("IsPublishingEnabled: " + catalog.IsPublishingEnabled);
            Console.WriteLine();
        }

        // Print errors.
        
        private static void PrintErrors(ContentError contentError)
        {
            Console.WriteLine("HTTP status code: " + contentError.Error.Code);

            foreach (Error error in contentError.Error.Errors)
            {
                Console.WriteLine("reason: {0}\nmessage: {1}\nlocation type: {2}\nlocation: {3}\n",
                    error.Reason, error.Message, error.LocationType, error.Location);
            }
        }


        // Gets the AuthenticationToken and DeveloperToken headers 
        // that are required to call the API. This example use OAuth
        // instead of using the legacy credentials (username and password).

        private static WebHeaderCollection GetCredentialHeaders()
        {
            // TODO: Add logic to get the logged on user's refresh token 
            // from secured storage. 

            tokens = GetOauthTokens(storedRefreshToken);

            var headers = new WebHeaderCollection();
            headers.Add("AuthenticationToken", tokens.AccessToken);
            headers.Add("DeveloperToken", devToken);

            return headers;
        }

        // Gets the OAuth tokens. If the refresh token doesn't exist, get 
        // the user's consent and a new access and refresh token.
        
        private static CodeGrantOauth GetOauthTokens(string refreshToken)
        {
            CodeGrantOauth auth = null;

            if (string.IsNullOrEmpty(refreshToken))
            {
                auth = new CodeGrantOauth(clientId, clientSecret);
                auth.GetAccessToken();
            }
            else
            {
                auth = new CodeGrantOauth(clientId, clientSecret);
                auth.RefreshAccessToken(refreshToken);

                // Refresh tokens can become invalid for several reasons
                // such as the user's password changed.

                if (!string.IsNullOrEmpty(auth.Error))
                {
                    auth = GetOauthTokens(null);
                }
            }

            // TODO: Store the new refresh token in secured storage
            // for the logged on user.

            storedRefreshToken = auth.RefreshToken;
            tokenExpiration = DateTime.Now.AddSeconds(auth.Expiration);

            return auth;
        }
    }
}

public class Catalog
{
    [JsonProperty("id", DefaultValueHandling = DefaultValueHandling.Ignore)]
    public ulong Id { get; set; }

    [JsonProperty("name")]
    public string Name { get; set; }

    [JsonProperty("market", DefaultValueHandling = DefaultValueHandling.Ignore)]
    public string Market { get; set; }

    [JsonProperty("isPublishingEnabled")]
    public Boolean IsPublishingEnabled { get; set; }

    [JsonProperty("isDefault", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
    public Boolean IsDefault { get; set; }
}

public class CatalogCollection
{
    [JsonProperty("catalogs")]
    public List<Catalog> Catalogs { get; set; }
}

// Classes used to handle errors.
public class Error
{
    [JsonProperty("location")]
    public string Location { get; set; }

    [JsonProperty("locationType")]
    public string LocationType { get; set; }

    [JsonProperty("domain")]
    public string Domain { get; set; }

    [JsonProperty("message")]
    public string Message { get; set; }

    [JsonProperty("reason")]
    public string Reason { get; set; }
}

public class ErrorCollection
{
    [JsonProperty("code")]
    public string Code { get; set; }

    [JsonProperty("errors")]
    public List<Error> Errors { get; set; }

    [JsonProperty("message")]
    public string Message { get; set; }

}

public class ContentError
{
    [JsonProperty("error")]
    public ErrorCollection Error { get; set; }
}
package catalogs.capi.microsoft.com;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.util.Map.Entry;

// Uses Jackson to serialize and deserialize JSON.

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.annotation.*;
import com.fasterxml.jackson.annotation.JsonInclude.Include;


class Catalogs {

	// Jackson object used to serialize and deserialize JSON.

	private static ObjectMapper jsonMapper = new ObjectMapper();

	private static String accessToken = "<accesstokengoeshere>"; 
    public static String devToken = "<devtokengoeshere>"; 

    // URI templates used to get resources.
    
    public static final String BaseUri = "https://content.api.bingads.microsoft.com/shopping/v9.1";
    public static final String BmcUri = BaseUri + "/bmc/%d";
    public static final String CatalogsUri = BmcUri + "/catalogs";
    public static final String CatalogUri = CatalogsUri + "/%d";


    // Replace with your store ID.
    
    public static long merchantId = <merchantidgoeshere>; 

	// This example shows how to list, add, update, and delete
    // catalogs in the store.
    
	public static void main(String[] args) throws JsonParseException, JsonMappingException, IOException {

		try {
			Map<String, String> headers = getCredentialHeaders();

            String url = String.format(CatalogsUri, merchantId);

            // Get and print the current list of catalogs.

            CatalogCollection collection = (CatalogCollection) getResource(url, headers, CatalogCollection.class);
            printCatalogs(collection);

            // Add a couple of catalogs.

            List<Catalog> addedCatalogs = addCatalogs(url, headers);

            // Get and print the current list of catalogs.

            collection = (CatalogCollection) getResource(url, headers, CatalogCollection.class);
            printCatalogs(collection);

            // Update the first catalog that we added
            // to enable it for publishing. When you update the 
            // catalog, you must specify both Name and IsPublishingEnabled.

            System.out.println("*** Updating Catalog ***\n");
            String catalogUrl = String.format(CatalogUri, merchantId, ((Catalog) addedCatalogs.toArray()[0]).getId());
            Catalog catalog = new Catalog();
            catalog.setName(((Catalog) addedCatalogs.toArray()[0]).getName());
            catalog.setIsPublishingEnabled(true);

            updateResource(catalogUrl, headers, catalog);

            // Get and print the updated catalog.

            Catalog updatedCatalog = (Catalog) getResource(catalogUrl, headers, Catalog.class);
            printCatalogDetails(updatedCatalog);

            // Delete the catalogs that we created.

            deleteCatalogs(CatalogUri, headers, merchantId, addedCatalogs);

            // Get and print the current list of catalogs.

            collection = (CatalogCollection) getResource(url, headers, CatalogCollection.class);
            printCatalogs(collection);
		}
		catch (CapiException e) {
			if (e.getErrors() != null){
	    		printErrors(e.getErrors());
			}
			else
			{
				System.out.println(e.getMessage());
			}
		}
    	catch (IOException e) {
    		System.out.println(e.getMessage());
    	}
		catch (Exception e) {
			System.out.println("\n" + e.getMessage());
		}

	}

	// Get tokens for the authentication headers.

    private static Map<String, String> getCredentialHeaders()
    {
        // TODO: Add logic to get the user's OAuth token. 

        Map<String, String> headers = new HashMap<String, String>();
        headers.put("AuthenticationToken", accessToken);
        headers.put("DeveloperToken", devToken);

        return headers;
    }
    

    // Generic method to get a resource from the specified URL.
    
    private static Object getResource(String uri, Map<String, String> headers, Class\<?> type) throws IOException, CapiException 
    {
    	Object resource = null;
    	HttpURLConnection connection = null;
    	URL url;
    	InputStream istream = null;
    	BufferedReader reader = null;


    	try {
    		url = new URL(uri);
    		connection = (HttpURLConnection) url.openConnection();

    		connection.setRequestMethod("GET");
    		connection.setRequestProperty("Accept", "application/json");

    		for (Entry\<String, String> header : headers.entrySet())
    		{
    			connection.setRequestProperty(header.getKey(), header.getValue());
    		}

    		connection.setUseCaches(false);

    		int statusCode = connection.getResponseCode();
    		
    		if (statusCode >= HttpURLConnection.HTTP_BAD_REQUEST) {
    			istream = connection.getErrorStream();
    		}
    		else {
    			istream = connection.getInputStream();
    		}
 
    		StringBuffer response = new StringBuffer();
    		reader = new BufferedReader(new InputStreamReader(istream));
    		char[] buffer = new char[2048];
    		int len = 0;
    		
    		while ((len = reader.read(buffer)) != -1) {
    			response.append(new String(buffer, 0, len));
    		}

    		System.out.println(response);
    		
    		
    		if (statusCode >= HttpURLConnection.HTTP_BAD_REQUEST) {
    			if (statusCode == HttpURLConnection.HTTP_BAD_REQUEST) {
    	    		ContentError errors = jsonMapper.readValue(response.toString(), ContentError.class);
    				throw new CapiException("Batch request failed.\n", errors.getError().getErrors());
    			}
    			else {
    				throw new CapiException(response.toString());
    			}
    		}

    		resource = jsonMapper.readValue(response.toString(), type);
    	}
    	finally {
    		if (connection != null) {
    			connection.disconnect();
    		}

    		if (reader != null) {
    			reader.close();
    		}

    		if (istream != null) {
    			istream.close();
    		}
    	}

    	return resource;
    }


    // Adds a Catalog to the store.
    
    private static Catalog addResource(String uri, Map<String, String> headers, Catalog catalog) throws IOException, CapiException 
    {
    	HttpURLConnection connection = null;
    	URL url;
    	InputStream istream = null;
    	OutputStreamWriter ostream = null;
    	BufferedReader reader = null;
    	Catalog catalogOut = null;

    	try {
        	String json = jsonMapper.writeValueAsString(catalog);

    		url = new URL(uri);
    		connection = (HttpURLConnection) url.openConnection();

    		connection.setRequestMethod("POST");
    		connection.setRequestProperty("Content-Type", "application/json");
    		connection.setRequestProperty("Content-Length", String.valueOf(json.length()));

    		for (Entry\<String, String> header : headers.entrySet())
    		{
    			connection.setRequestProperty(header.getKey(), header.getValue());
    		}

    		connection.setDoInput(true);
    		connection.setDoOutput(true);
    		connection.setUseCaches(false);

    		ostream = new OutputStreamWriter(connection.getOutputStream());
    		ostream.write(json);
    		ostream.close();

    		int statusCode = connection.getResponseCode();
    		
    		if (statusCode >= HttpURLConnection.HTTP_BAD_REQUEST) {
        		istream = connection.getErrorStream();
    		}
    		else {
        		istream = connection.getInputStream();
    		}
 
    		StringBuffer response = new StringBuffer();
    		reader = new BufferedReader(new InputStreamReader(istream));
    		char[] buffer = new char[2048];
    		int len = 0;
    		
    		while ((len = reader.read(buffer)) != -1) {
    			response.append(new String(buffer, 0, len));
    		}

    		System.out.println(response);
    		
    		if (statusCode >= HttpURLConnection.HTTP_BAD_REQUEST) {
    			if (statusCode < HttpURLConnection.HTTP_INTERNAL_ERROR) {
    	    		ContentError errors = jsonMapper.readValue(response.toString(), ContentError.class);
    				throw new CapiException("Batch request failed.\n", errors.getError().getErrors());
    			}
    			else {
    				throw new CapiException(response.toString());
    			}
    		}

    		catalogOut = jsonMapper.readValue(response.toString(), Catalog.class);
    	}
    	finally {
    		if (connection != null) {
    			connection.disconnect();
    		}

    		if (reader != null) {
    			reader.close();
    		}

    		if (istream != null) {
    			istream.close();
    		}

    		if (ostream != null) {
    			ostream.close();
    		}
    	}

    	return catalogOut;
    }

    // Updates a Catalog in the store.
    
    private static Catalog updateResource(String uri, Map<String, String> headers, Catalog catalog) throws IOException, CapiException 
    {
    	HttpURLConnection connection = null;
    	URL url;
    	InputStream istream = null;
    	OutputStreamWriter ostream = null;
    	BufferedReader reader = null;
    	Catalog catalogOut = null;

    	try {
        	String json = jsonMapper.writeValueAsString(catalog);

    		url = new URL(uri);
    		connection = (HttpURLConnection) url.openConnection();

    		connection.setRequestMethod("PUT");
    		connection.setRequestProperty("Content-Type", "application/json");
    		connection.setRequestProperty("Content-Length", String.valueOf(json.length()));

    		for (Entry\<String, String> header : headers.entrySet())
    		{
    			connection.setRequestProperty(header.getKey(), header.getValue());
    		}

    		connection.setDoInput(true);
    		connection.setDoOutput(true);
    		connection.setUseCaches(false);

    		ostream = new OutputStreamWriter(connection.getOutputStream());
    		ostream.write(json);
    		ostream.close();

    		int statusCode = connection.getResponseCode();
    		
    		if (statusCode >= HttpURLConnection.HTTP_BAD_REQUEST) {
        		istream = connection.getErrorStream();
    		}
    		else {
        		istream = connection.getInputStream();
    		}
 
    		StringBuffer response = new StringBuffer();
    		reader = new BufferedReader(new InputStreamReader(istream));
    		char[] buffer = new char[2048];
    		int len = 0;
    		
    		while ((len = reader.read(buffer)) != -1) {
    			response.append(new String(buffer, 0, len));
    		}

    		System.out.println(response);
    		
    		if (statusCode >= HttpURLConnection.HTTP_BAD_REQUEST) {
    			if (statusCode < HttpURLConnection.HTTP_INTERNAL_ERROR) {
    	    		ContentError errors = jsonMapper.readValue(response.toString(), ContentError.class);
    				throw new CapiException("Batch request failed.\n", errors.getError().getErrors());
    			}
    			else {
    				throw new CapiException(response.toString());
    			}
    		}

    		catalogOut = jsonMapper.readValue(response.toString(), Catalog.class);
    	}
    	finally {
    		if (connection != null) {
    			connection.disconnect();
    		}

    		if (reader != null) {
    			reader.close();
    		}

    		if (istream != null) {
    			istream.close();
    		}

    		if (ostream != null) {
    			ostream.close();
    		}
    	}

    	return catalogOut;
    }

    // Deletes a Catalog from the store.
    
    private static void deleteResource(String uri, Map<String, String> headers) throws IOException, CapiException 
    {
    	HttpURLConnection connection = null;
    	URL url;
    	InputStream istream = null;
    	BufferedReader reader = null;


    	try {
    		url = new URL(uri);
    		connection = (HttpURLConnection) url.openConnection();

    		connection.setRequestMethod("DELETE");
    		connection.setRequestProperty("Accept", "application/json");

    		for (Entry\<String, String> header : headers.entrySet())
    		{
    			connection.setRequestProperty(header.getKey(), header.getValue());
    		}

    		connection.setUseCaches(false);

    		int statusCode = connection.getResponseCode();
    		
    		if (statusCode >= HttpURLConnection.HTTP_BAD_REQUEST) {
    			istream = connection.getErrorStream();

        		StringBuffer response = new StringBuffer();
        		reader = new BufferedReader(new InputStreamReader(istream));
        		char[] buffer = new char[2048];
        		int len = 0;
        		
        		while ((len = reader.read(buffer)) != -1) {
        			response.append(new String(buffer, 0, len));
        		}

        		System.out.println(response);
        		
    			if (statusCode < HttpURLConnection.HTTP_INTERNAL_ERROR) {
    	    		ContentError errors = jsonMapper.readValue(response.toString(), ContentError.class);
    				throw new CapiException("Batch request failed.\n", errors.getError().getErrors());
    			}
    			else {
    				throw new CapiException(response.toString());
    			}
    		}
    	}
    	finally {
    		if (connection != null) {
    			connection.disconnect();
    		}

    		if (reader != null) {
    			reader.close();
    		}

    		if (istream != null) {
    			istream.close();
    		}
    	}
    }

    // Creates a couple of catalogs and adds them 
    // to the store.
    
    private static List<Catalog> addCatalogs(String url, Map<String, String> headers) throws IOException, CapiException
    {
    	List<Catalog> catalogs = new ArrayList<Catalog>();

        System.out.println("*** Adding Catalogs ***\n");

        // This catalog is not enabled for publishing.

        Catalog catalog = new Catalog();
        catalog.setName("Mens Apparel");
        catalog.setMarket("en-US");
        catalog.setIsPublishingEnabled(false);

        catalogs.add(addResource(url, headers, catalog));

        // This catalog is enabled for publishing.

        catalog = new Catalog();
        catalog.setName("Womens Apparel");
        catalog.setMarket("en-US");
        catalog.setIsPublishingEnabled(true);

        catalogs.add(addResource(url, headers, catalog));

        return catalogs;
    }

    // Deletes the specified catalogs from the store.
    
    private static void deleteCatalogs(String uri, Map<String, String> headers, long merchantId, List<Catalog> catalogs) throws Exception
    {
        System.out.println("*** Deleting Catalogs ***\n");

        for (Catalog catalog : catalogs)
        {
            // Build the endpoint URL.

            String url = String.format(uri, merchantId, catalog.getId());

            // Delete the catalog from the store.

            deleteResource(url, headers);
            System.out.println("Deleted catalog: " + catalog.getId());
        }

        System.out.println();
    }

    
    
    // Prints the list of catalogs

    private static void printCatalogs(CatalogCollection collection)
    {
        System.out.println("There are " + collection.getCatalogs().size() + " catalogs.\n");

        for (Catalog catalog : collection.getCatalogs())
        {
            printCatalogDetails(catalog);
        }
    }

    // Print catalog details.

    private static void printCatalogDetails(Catalog catalog)
    {
    	System.out.println("Name: " + catalog.getName());
    	System.out.println("ID: " + catalog.getId());
    	System.out.println("Market: " + catalog.getMarket());
    	System.out.println("IsDefault: " + catalog.getIsDefault());
    	System.out.println("IsPublishingEnabled: " + catalog.getIsPublishingEnabled());
    	System.out.println();
    }

    
    // Print errors.
    
    private static void printErrors(List<Error> errors)
    {
        for (Error error : errors)
        {
            System.out.printf("reason: %s\nmessage: %s\ndomain: %s\n\n",
                error.getReason(), error.getMessage(), error.getDomain());
        }
    }

}


@SuppressWarnings("serial")
class CapiException extends Exception {

	private List<Error> errors = null;
	
	public CapiException(String message) {
		super(message);
	}

	public CapiException(String message, List<Error> errors) {
		super(message);
		this.errors = errors;
	}

	public CapiException(Throwable cause) {
		super(cause);
	}

	public CapiException(String message, Throwable cause) {
		super(message, cause);
	}
	
	public List<Error> getErrors() { return this.errors; }
	public void setErrors(List<Error> value) { this.errors = value; }
}

// The following define the Catalog classes.

@JsonInclude(Include.NON_DEFAULT)
class Catalog
{
	private long id;
	private String name;
	private String market;
    //@JsonDeserialize(using=StringBooleanDeserializer.class)
	private Boolean isPublishingEnabled;
    //@JsonDeserialize(using=StringBooleanDeserializer.class)
	private Boolean isDefault;
	
    public long getId() { return this.id; }
    public void setId(long value) { this.id = value; }

    public String getName() { return this.name; }
    public void setName(String value) { this.name = value; }

    public String getMarket() { return this.market; }
    public void setMarket(String value) { this.market = value; }

    public Boolean getIsPublishingEnabled() { return this.isPublishingEnabled; }
    public void setIsPublishingEnabled(Boolean value) { this.isPublishingEnabled = value; }

    public Boolean getIsDefault() { return this.isDefault; }
    public void setIsDefault(Boolean value) { this.isDefault = value; }
}

class CatalogCollection
{
	private List<Catalog> catalogs;
	
    public List<Catalog> getCatalogs() { return this.catalogs; }
    public void setCatalogs(List<Catalog> value) { this.catalogs = value; }
}


//Classes used to handle errors.

class Error
{
	private String location;
	private String locationType;
	private String domain;
	private String message;
	private String reason;
	
 public String getLocation() { return this.location; }

 public String getLocationType() { return this.locationType; }

 public String getDomain() { return this.domain; }

 public String getMessage() { return this.message; }

 public String getReason() { return this.reason; }
}

class ErrorCollection
{
	private List<Error> errors;
	
 public List<Error> getErrors() { return this.errors; }
}


class ContentError
{
	private ErrorCollection error;
	
 public ErrorCollection getError() { return this.error; }
}
# A simple example that shows how to get all catalogs in a store, 
# add a catalog, update the catalog, and then delete it.

import string
import json
import requests

# Concatenate together these strings to create the endpoint
# to send request to the Content API.

BASE_URI = 'https://content.api.bingads.microsoft.com/shopping/v9.1'
BMC_URI = BASE_URI + '/bmc/{0}'  # {0} will contain the merchant ID 

DEV_TOKEN = '<your dev token goes here>'
MERCHANT_ID = '<your store ID goes here>'

# This example does not show how to get the access token. Copy
# it here from another source.

AUTHENTICATION_TOKEN = "<your access token goes here>"

AUTHENTICATION_HEADERS = {'DeveloperToken': DEV_TOKEN, 'AuthenticationToken': AUTHENTICATION_TOKEN}


# Prints the error that was raised.

def print_error(errors):
    print('The following errors occurred:')
    for error in errors:
        print('Reason: {0}'.format(error['reason']))
        print('Message: {0}'.format(error['message']))
        print()


# Prints the catalog's values.

def print_catalog_values(catalog):
    print('Name: {0} ({1})'.format(catalog['name'], catalog['id']))
    print('Default catalog: {0}'.format(catalog['isDefault']))
    print('Publishing enabled: {0}'.format(catalog['isPublishingEnabled']))
    print('Market: {0}'.format(catalog['market']))
    print()


# Gets a list of catalogs in the merchant's store.

def get_catalogs():
    CATALOGS_URI = BMC_URI + "/catalogs"
    url = CATALOGS_URI.format(MERCHANT_ID)
    print(url)
    response = requests.get(url, headers=AUTHENTICATION_HEADERS)
    response.raise_for_status()
    return json.loads(response.text)['catalogs']


# Print all of the merchant's catalogs.

def print_catalogs():
    catalogs = get_catalogs()
    for catalog in catalogs:
        print_catalog_values(catalog)


# Gets a specific catalog in the merchant's store.

def get_catalog(catalogId):
    CATALOG_URI = BMC_URI + "/catalogs/{1}"
    url = CATALOG_URI.format(MERCHANT_ID, catalogId)
    print(url)
    response = requests.get(url, headers=AUTHENTICATION_HEADERS)
    response.raise_for_status()
    return json.loads(response.text)


# Adds an en-US catalog to the merchant's store.

def add_catalog(catalog_name, isEnabled=False):
    CATALOGS_URI = BMC_URI + "/catalogs"
    url = CATALOGS_URI.format(MERCHANT_ID)
    catalog = {'name': catalog_name, 'market': "en-US", 'isPublishingEnabled': isEnabled}
    response = requests.post(url, headers=AUTHENTICATION_HEADERS, data=json.dumps(catalog))
    response.raise_for_status()
    print('Request activity ID: {0}'.format(response.headers['WebRequestActivityId']))
    return json.loads(response.text)


# Update publishing flag

def update_catalog(catalogId, isEnabled):
    CATALOG_URI = BMC_URI + "/catalogs/{1}"
    url = CATALOG_URI.format(MERCHANT_ID, catalogId)
    catalog = get_catalog(catalogId)
    catalog = {'name': catalog['name'], 'isPublishingEnabled': isEnabled}
    response = requests.put(url, headers=AUTHENTICATION_HEADERS, data=json.dumps(catalog))
    response.raise_for_status()
    return json.loads(response.text)


# Delete catalog

def delete_catalog(catalogId):
    CATALOG_URI = BMC_URI + "/catalogs/{1}"
    url = CATALOG_URI.format(MERCHANT_ID, catalogId)
    response = requests.delete(url, headers=AUTHENTICATION_HEADERS)
    response.raise_for_status()


def main():
    # The main entry point of this example

    try:

        print("*** Catalogs ***")
        print_catalogs()

        # Adds a catalog with publishing disabled.

        print("*** Adding catalog ***")
        catalog = add_catalog('Everything Sale')
        print_catalog_values(catalog)

        # Gets the catalog that was just added.

        msg = "*** Getting catalog {0} ***".format(catalog['id'])
        print(msg)
        catalog = get_catalog(catalog['id'])
        print_catalog_values(catalog)

        # Enable the catalog for publishing.

        msg = "*** Updating catalog {0} ***".format(catalog['id'])
        print(msg)
        catalog = update_catalog(catalog['id'], True)
        print_catalog_values(catalog)

        # Delete the catalog that was added.

        msg = "*** Deleting catalog {0} ***\n".format(catalog['id'])
        print(msg)
        delete_catalog(catalog['id'])

        print("*** Catalogs ***")
        print_catalogs()

    except Exception as ex:
        print('Request activity ID: {0}'.format(ex.response.headers['WebRequestActivityId']))
        print_error(json.loads(ex.response.text)['error']['errors'])
        raise ex

# Main execution
if __name__ == '__main__':
    main()
<?php
$clientId = '<CLIENTIDGOESHERE>';
$devToken = '<DEVELOPERTOKENGOESHERE>';
$merchantId = '<STOREIDGOESHERE>';
$authenticationToken = '<AUTHENTICATIONTOKENGOESHERE>';

$baseUri = 'https://content.api.bingads.microsoft.com/shopping/v9.1';
$bmcUri = $baseUri . '/bmc/%s';
$catalogsUri = $bmcUri . "/catalogs";
$catalogUri = $catalogsUri . "/%s";

# List catalogs
echo("*** List catalogs ***\r\n");
$catalogs = list_catalogs();
$count = count($catalogs);
for ($i = 0; $i < $count; $i++) {
    printObject($catalogs[$i]);
}
echo("*** / End of catalogs list ***\r\n");
echo("\r\n");

# Add catalog
$testCatalog = add_catalog("Test Catalog (" . uniqid() . ")");
echo("*** Added test catalog (catalog.Id=" . $testCatalog['id'] . ")***\r\n");
echo printObject($testCatalog);
echo("*** / End of added test catalog (catalog.Id=" . $testCatalog['id'] . ")***\r\n");
echo("\r\n");

# Update catalog
$testCatalog['name'] = "Updated  - " . $testCatalog['name'];
$updatedCatalog = update_catalog($testCatalog);
echo("*** Updated catalog " . $updatedCatalog['id'] . "***\r\n");
printObject($updatedCatalog);
echo("*** / End of updated catalog " . $updatedCatalog['id'] . "***\r\n");
echo("\r\n");

# Delete catalog
echo("*** Deleting catalog " . $updatedCatalog['id'] . "***\r\n");
delete_catalog($updatedCatalog['id']);
echo("\r\n");

echo("*** List catalogs after delete ***\r\n");
$catalogs = list_catalogs();
$count = count($catalogs);
for ($i = 0; $i < $count; $i++) {
    printObject($catalogs[$i]);
}
echo("*** / End of catalogs list ***");

function list_catalogs(){
    global $merchantId, $catalogsUri;

    $url = sprintf($catalogsUri, $merchantId);
    $result = request('GET', $url);
    if ($result === FALSE) {  
        throw new Exception(var_dump($result));
    } else {
        $catalogs = json_decode($result, true)["catalogs"];
        return $catalogs;
    }    
}

function add_catalog($catalogName){
    global $merchantId, $catalogsUri;

    $url = sprintf($catalogsUri, $merchantId);
    $result = request('POST', $url, array(
        'name' => $catalogName,
        'market' => 'en-US',
        'isPublishingEnabled' => true
    ));
    if ($result === FALSE) {  
        throw new Exception(var_dump($result));
    } else {
        echo("add catalog response: " . var_dump($result) . "\r\n");
        return json_decode($result, true);        
    } 
}

function update_catalog($catalog){
    global $merchantId, $catalogUri;

    $url = sprintf($catalogUri, $merchantId, $catalog['id']);
    $result = request('PUT', $url, $catalog);
    if ($result === FALSE) {  
        throw new Exception(var_dump($result));
    } else {
        echo("update catalog response: " . var_dump($result) . "\r\n");
        return json_decode($result, true);        
    } 
}

function delete_catalog($catalogId){
    global $merchantId, $catalogUri;

    $url = sprintf($catalogUri, $merchantId, $catalogId);
    $result = request('DELETE', $url);
    if ($result === FALSE) {  
        throw new Exception(var_dump($result));
    } else {
        return json_decode($result, true);        
    } 
}

function request($method, $url, $data = null){
    global $devToken, $authenticationToken;
    $options = array(
        'http' => array(
            'method'  => $method,
            'header'  => "AuthenticationToken: $authenticationToken\r\n" .
                        "DeveloperToken: $devToken\r\n" .
                        "Content-type: application/json\r\n"
        )
    );
    $json = null;
    if ($data !== null) {
        $json = json_encode($data);
        $options['http']['content'] = $json;
    }
    $context  = stream_context_create($options);
    echo("requesting ($method): $url\r\n");
    if ($json !== null) {
        echo("json data: $json\r\n");
    }
    return file_get_contents($url, false, $context);
}

function printObject($object){
    foreach ($object as $prop => $value) {
        echo("$prop: $value\r\n");
    }
}