Insert your first product

Adding products is a fundamental step in managing your business presence on Google. By providing product data through the Merchant API, you enable Google to display your inventory to potential customers across various platforms and services.

This document is the last part of a multi-part series about getting started with Merchant API. For further assistance or to explore common questions, refer to the FAQ section .

Create a primary products data source

To insert a product, you need a primary products data source. The following request shows how to create a data source you can use to insert a product through the API:

  POST https://merchantapi.googleapis.com/products/v1/accounts/ {ACCOUNT_ID} 
/dataSources 
 Content-Type: application/json 
 Authorization: Bearer {ACCESS_TOKEN} 
" 
 { 
 "displayName": " {DISPLAY_NAME} 
" 
 "primaryProductDataSource": 
 { 
 "countries": [ "US" ] 
 } 
 } 
 

Replace the following:

  • ACCOUNT_ID : your Merchant Center ID
  • ACCESS_TOKEN : the authorization token to make the API Call
  • DISPLAY_NAME : the display name of the primary data source

Upon a successful request, the API returns a DataSource resource containing the server-generated resource name, which you can use for subsequent operations like inserting products.

  { 
  
 "name" 
 : 
  
 "accounts/ {ACCOUNT_ID} 
/dataSources/ {DATASOURCE_ID} 
" 
 , 
  
 "dataSourceId" 
 : 
  
 " {DATASOURCE_ID} 
" 
 , 
  
 "displayName" 
 : 
  
 " {DISPLAY_NAME} 
" 
 , 
  
 "primaryProductDataSource" 
 : 
  
 { 
  
 "countries" 
 : 
  
 [ 
  
 "US" 
  
 ], 
  
 "defaultRule" 
 : 
  
 { 
  
 "takeFromDataSources" 
 : 
  
 [ 
  
 { 
  
 "self" 
 : 
  
 true 
  
 } 
  
 ] 
  
 } 
  
 }, 
  
 "input" 
 : 
  
 "API" 
 } 
 

Copy the value of the name field. You need it to insert a product.

Alternatively, if you already have an existing DataSource , use the dataSources.get method to get its details.

Python

Download the samples and follow the guidance from the Google Merchant API Python Samples to set up the python client libraries.

  from 
  
 examples.authentication 
  
 import 
 configuration 
 from 
  
 examples.authentication 
  
 import 
 generate_user_credentials 
 from 
  
 google.shopping.merchant_datasources_v1 
  
 import 
 CreateDataSourceRequest 
 from 
  
 google.shopping.merchant_datasources_v1 
  
 import 
 DataSource 
 from 
  
 google.shopping.merchant_datasources_v1 
  
 import 
 DataSourcesServiceClient 
 from 
  
 google.shopping.merchant_datasources_v1 
  
 import 
 PrimaryProductDataSource 
 _ACCOUNT 
 = 
 configuration 
 . 
 Configuration 
 () 
 . 
 read_merchant_info 
 () 
 _PARENT 
 = 
 f 
 "accounts/ 
 { 
 _ACCOUNT 
 } 
 " 
 def 
  
 create_primary_product_data_source_multiple_languages 
 (): 
  
 """Creates a `DataSource` resource.""" 
 # Gets OAuth Credentials. 
 credentials 
 = 
 generate_user_credentials 
 . 
 main 
 () 
 # Creates a client. 
 client 
 = 
 DataSourcesServiceClient 
 ( 
 credentials 
 = 
 credentials 
 ) 
 # Creates a PrimaryProductDataSource. 
 primary_datasource 
 = 
 PrimaryProductDataSource 
 () 
 primary_datasource 
 . 
 countries 
 = 
 [ 
 "GB" 
 ] 
 # Creates a DataSource and populates its attributes. 
 data_source 
 = 
 DataSource 
 () 
 data_source 
 . 
 display_name 
 = 
 "Example Multiple Languages Primary DataSource" 
 data_source 
 . 
 primary_product_data_source 
 = 
 primary_datasource 
 # Creates the request. 
 request 
 = 
 CreateDataSourceRequest 
 ( 
 parent 
 = 
 _PARENT 
 , 
 data_source 
 = 
 data_source 
 ) 
 # Makes the request and catches and prints any error messages. 
 try 
 : 
 response 
 = 
 client 
 . 
 create_data_source 
 ( 
 request 
 = 
 request 
 ) 
 print 
 ( 
 f 
 "DataSource successfully created: 
 { 
 response 
 } 
 " 
 ) 
 except 
 RuntimeError 
 as 
 e 
 : 
 print 
 ( 
 "DataSource creation failed" 
 ) 
 print 
 ( 
 e 
 ) 
 if 
 __name__ 
 == 
 "__main__" 
 : 
 create_primary_product_data_source_multiple_languages 
 () 
  
 

Java

Download the samples and follow the guidance from Google Merchant API Java Samples to set up the python client libraries.

  import 
  
 com.google.api.gax.core.FixedCredentialsProvider 
 ; 
 import 
  
 com.google.auth.oauth2.GoogleCredentials 
 ; 
 import 
  
 com.google.shopping.merchant.datasources.v1.CreateDataSourceRequest 
 ; 
 import 
  
 com.google.shopping.merchant.datasources.v1.DataSource 
 ; 
 import 
  
 com.google.shopping.merchant.datasources.v1.DataSourcesServiceClient 
 ; 
 import 
  
 com.google.shopping.merchant.datasources.v1.DataSourcesServiceSettings 
 ; 
 import 
  
 com.google.shopping.merchant.datasources.v1.PrimaryProductDataSource 
 ; 
 import 
  
 shopping.merchant.samples.utils.Authenticator 
 ; 
 import 
  
 shopping.merchant.samples.utils.Config 
 ; 
 /** 
 * This class demonstrates how to create a primary product data source for all `feedLabel` and 
 * `contentLanguage` combinations. 
 */ 
 public 
  
 class 
 CreatePrimaryProductDataSourceMultipleLanguagesSample 
  
 { 
  
 private 
  
 static 
  
 String 
  
 getParent 
 ( 
 String 
  
 merchantId 
 ) 
  
 { 
  
 return 
  
 String 
 . 
 format 
 ( 
 "accounts/%s" 
 , 
  
 merchantId 
 ); 
  
 } 
  
 public 
  
 static 
  
 String 
  
 createDataSource 
 ( 
 Config 
  
 config 
 , 
  
 String 
  
 displayName 
 ) 
  
 throws 
  
 Exception 
  
 { 
  
 GoogleCredentials 
  
 credential 
  
 = 
  
 new 
  
 Authenticator 
 (). 
 authenticate 
 (); 
  
 DataSourcesServiceSettings 
  
 dataSourcesServiceSettings 
  
 = 
  
 DataSourcesServiceSettings 
 . 
 newBuilder 
 () 
  
 . 
 setCredentialsProvider 
 ( 
 FixedCredentialsProvider 
 . 
 create 
 ( 
 credential 
 )) 
  
 . 
 build 
 (); 
  
 String 
  
 parent 
  
 = 
  
 getParent 
 ( 
 config 
 . 
 getAccountId 
 (). 
 toString 
 ()); 
  
 // The type of data that this datasource will receive. 
  
 PrimaryProductDataSource 
  
 primaryProductDataSource 
  
 = 
  
 PrimaryProductDataSource 
 . 
 newBuilder 
 () 
  
 . 
 addCountries 
 ( 
 "GB" 
 ) 
  
 . 
 build 
 (); 
  
 try 
  
 ( 
 DataSourcesServiceClient 
  
 dataSourcesServiceClient 
  
 = 
  
 DataSourcesServiceClient 
 . 
 create 
 ( 
 dataSourcesServiceSettings 
 )) 
  
 { 
  
 CreateDataSourceRequest 
  
 request 
  
 = 
  
 CreateDataSourceRequest 
 . 
 newBuilder 
 () 
  
 . 
 setParent 
 ( 
 parent 
 ) 
  
 . 
 setDataSource 
 ( 
  
 DataSource 
 . 
 newBuilder 
 () 
  
 . 
 setDisplayName 
 ( 
 displayName 
 ) 
  
 . 
 setPrimaryProductDataSource 
 ( 
 primaryProductDataSource 
 ) 
  
 . 
 build 
 ()) 
  
 . 
 build 
 (); 
  
 System 
 . 
 out 
 . 
 println 
 ( 
 "Sending Create PrimaryProduct DataSource request" 
 ); 
  
 DataSource 
  
 response 
  
 = 
  
 dataSourcesServiceClient 
 . 
 createDataSource 
 ( 
 request 
 ); 
  
 System 
 . 
 out 
 . 
 println 
 ( 
 "Created DataSource Name below" 
 ); 
  
 System 
 . 
 out 
 . 
 println 
 ( 
 response 
 . 
 getName 
 ()); 
  
 return 
  
 response 
 . 
 getName 
 (); 
  
 } 
  
 catch 
  
 ( 
 Exception 
  
 e 
 ) 
  
 { 
  
 System 
 . 
 out 
 . 
 println 
 ( 
 e 
 ); 
  
 System 
 . 
 exit 
 ( 
 1 
 ); 
  
 // Null is necessary to satisfy the compiler as we're not returning a String on failure. 
  
 return 
  
 null 
 ; 
  
 } 
  
 } 
  
 public 
  
 static 
  
 void 
  
 main 
 ( 
 String 
 [] 
  
 args 
 ) 
  
 throws 
  
 Exception 
  
 { 
  
 Config 
  
 config 
  
 = 
  
 Config 
 . 
 load 
 (); 
  
 // The displayed data source name in the Merchant Center UI. 
  
 String 
  
 displayName 
  
 = 
  
 "Primary Product Data Multiple Languages" 
 ; 
  
 createDataSource 
 ( 
 config 
 , 
  
 displayName 
 ); 
  
 } 
 } 
  
 

PHP

Download the samples and follow the guidance from the Google Merchant API PHP Samples to set up the php client libraries.

  use Google\ApiCore\ApiException; 
 use Google\Shopping\Merchant\DataSources\V1\Client\DataSourcesServiceClient; 
 use Google\Shopping\Merchant\DataSources\V1\CreateDataSourceRequest; 
 use Google\Shopping\Merchant\DataSources\V1\DataSource; 
 use Google\Shopping\Merchant\DataSources\V1\PrimaryProductDataSource; 
 /** 
 * This class demonstrates how to create a primary product datasource for all `feedLabel` and 
 * `contentLanguage` combinations. 
 */ 
 class CreatePrimaryProductDataSourceMultipleLanguagesSample 
 { 
 /** 
 * Creates a primary product data source. 
 * 
 * @param int    $merchantId The Merchant Center account ID. 
 * @param string $displayName The displayed data source name in the Merchant Center UI. 
 * 
 * @return string The name of the newly created data source. 
 */ 
 public function createDataSource(int $merchantId, string $displayName): string 
 { 
 // Gets the OAuth credentials to make the request. 
 $credentials = Authentication::useServiceAccountOrTokenFile(); 
 // Creates options config containing credentials for the client to use. 
 $options = ['credentials' => $credentials]; 
 // Creates a client. 
 $dataSourcesServiceClient = new DataSourcesServiceClient($options); 
 $parent = sprintf('accounts/%s', $merchantId); 
 // The type of data that this datasource will receive. 
 $primaryProductDataSource = (new PrimaryProductDataSource()) 
 ->setCountries(['GB']); 
 // Calls the API and catches and prints any network failures/errors. 
 try { 
 $response = $dataSourcesServiceClient->createDataSource( 
 (new CreateDataSourceRequest()) 
 ->setParent($parent) 
 ->setDataSource( 
 (new DataSource()) 
 ->setDisplayName($displayName) 
 ->setPrimaryProductDataSource($primaryProductDataSource) 
 ) 
 ); 
 printf('Created DataSource Name below:' . PHP_EOL); 
 printf('%s' . PHP_EOL, $response->getName()); 
 return $response->getName(); 
 } catch (ApiException $ex) { 
 printf('Call failed with message: %s' . PHP_EOL, $ex->getMessage()); 
 exit(1); 
 } 
 } 
 // Helper to execute the sample. 
 public function callSample(): void 
 { 
 $config = Config::generateConfig(); 
 // The Merchant Center Account ID. 
 $merchantId = $config['accountId']; 
 // The displayed datasource name in the Merchant Center UI. 
 $displayName = 'Primary Product Data Multiple Languages'; 
 self::createDataSource($merchantId, $displayName); 
 } 
 } 
 $sample = new CreatePrimaryProductDataSourceMultipleLanguagesSample(); 
 $sample->callSample();  
 
 

cURL

  curl -X POST "https://merchantapi.googleapis.com/datasources/v1/accounts/ {ACCOUNT_ID} 
/dataSources" \ 
 -H "Content-Type: application/json" \ 
 -H "Authorization: Bearer {ACCESS_TOKEN} 
" \ 
 -d '{ 
 "primaryProductDataSource": { 
 "countries": ["US"] 
 }, 
 "name": "primary-data-source", 
 "displayName": " {DISPLAY_NAME} 
" 
 }' 
 

You can view your data sources in the Merchant Center UI. For more information, see How to find the Data sources tab .

Insert a product

Once you create the data source, try to insert a product into it. Run the following productInputs.insert method call, supplying the correct ACCOUNT_ID . Replace DATASOURCE_NAME with the value you copied earlier.

  POST https://merchantapi.googleapis.com/products/v1/accounts/ {ACCOUNT_ID} 
/productInputs:insert?dataSource= {DATASOURCE_NAME} 
 
 Content-Type: application/json 
 Authorization: Bearer {ACCESS_TOKEN} 
 
 { 
 "contentLanguage": "en", 
 "feedLabel": "US", 
 "name": "Red T-shirt", 
 "productAttributes": { "gender": "MALE", "brand": "New brand" }, 
 "offerId": "tshirt-123" 
 } 
 

Replace the following:

  • ACCOUNT_ID : your Merchant Center ID
  • ACCESS_TOKEN : the authorization token to make the API Call
  • DATASOURCE_NAME : the name of the primary data source, which is in the following format: accounts/{ACCOUNT_ID}/dataSources/{DATASOURCE_ID}

After you run this request successfully, you should see the following response:

  { 
  
 "name" 
 : 
  
 "accounts/ {ACCOUNT_ID} 
/productInputs/en~US~tshirt-123" 
 , 
  
 "product" 
 : 
  
 "accounts/ {ACCOUNT_ID} 
/products/en~US~tshirt-123" 
 , 
  
 "offerId" 
 : 
  
 "tshirt-123" 
 , 
  
 "contentLanguage" 
 : 
  
 "en" 
 , 
  
 "feedLabel" 
 : 
  
 "US" 
 , 
  
 "productAttributes" 
 : 
  
 { 
  
 "brand" 
 : 
  
 "New brand" 
 , 
  
 "gender" 
 : 
  
 "MALE" 
  
 } 
 } 
 

A successful call returns the newly created ProductInput resource. The name field in the output response for this product is accounts/{ACCOUNT_ID}/productInputs/en~US~tshirt-123 and it represents the identifier of the product. It must be unique within a merchant account, and it generally follows the structure:

accounts/{account}/productInputs/{productinput}

productinput respects the following syntax: contentLanguage~feedLabel~offerId .

The product field contains the name of the final, processed product you can later use to retrieve it. You can use the accounts.products.get method to retrieve details about this product or see it in the Merchant Center UI.

For more information about viewing your product data, see Products overview in Merchant Center .

Python

  from 
  
 examples.authentication 
  
 import 
 configuration 
 from 
  
 examples.authentication 
  
 import 
 generate_user_credentials 
 from 
  
 google.shopping 
  
 import 
 merchant_products_v1 
 from 
  
 google.shopping.merchant_products_v1 
  
 import 
 Availability 
 from 
  
 google.shopping.merchant_products_v1 
  
 import 
 Condition 
 from 
  
 google.shopping.type 
  
 import 
 Price 
 _ACCOUNT 
 = 
 configuration 
 . 
 Configuration 
 () 
 . 
 read_merchant_info 
 () 
 _PARENT 
 = 
 f 
 "accounts/ 
 { 
 _ACCOUNT 
 } 
 " 
 # You can only insert products into datasource types of Input "API" and 
 # "FILE", and of Type "Primary" or "Supplemental." 
 _DATA_SOURCE 
 = 
 "[INSERT_DATA_SOURCE_HERE]" 
 _DATA_SOURCE_NAME 
 = 
 f 
 "accounts/ 
 { 
 _ACCOUNT 
 } 
 /dataSources/ 
 { 
 _DATA_SOURCE 
 } 
 " 
 def 
  
 create_product_input 
 (): 
  
 """Creates a `ProductInput` resource.""" 
 # Creates a shipping setting 
 price 
 = 
 Price 
 () 
 price 
 . 
 amount_micros 
 = 
 33_450_000 
 price 
 . 
 currency_code 
 = 
 "GBP" 
 shipping_option_1 
 = 
 merchant_products_v1 
 . 
 Shipping 
 () 
 shipping_option_1 
 . 
 price 
 = 
 price 
 shipping_option_1 
 . 
 country 
 = 
 "GB" 
 shipping_option_1 
 . 
 service 
 = 
 "1st class post" 
 price2 
 = 
 Price 
 () 
 price2 
 . 
 amount_micros 
 = 
 33_450_000 
 price2 
 . 
 currency_code 
 = 
 "EUR" 
 shipping_option_2 
 = 
 merchant_products_v1 
 . 
 Shipping 
 () 
 shipping_option_2 
 . 
 price 
 = 
 price2 
 shipping_option_2 
 . 
 country 
 = 
 "FR" 
 shipping_option_2 
 . 
 service 
 = 
 "2nd class post" 
 # Sets product attributes. Make sure to replace these values with your own. 
 attributes 
 = 
 merchant_products_v1 
 . 
 ProductAttributes 
 () 
 attributes 
 . 
 title 
 = 
 "A Tale of Two Cities" 
 attributes 
 . 
 description 
 = 
 "A classic novel about the French Revolution" 
 attributes 
 . 
 link 
 = 
 "https://exampleWebsite.com/tale-of-two-cities.html" 
 attributes 
 . 
 image_link 
 = 
 "https://exampleWebsite.com/tale-of-two-cities.jpg" 
 attributes 
 . 
 price 
 = 
 price 
 attributes 
 . 
 availability 
 = 
 Availability 
 . 
 IN_STOCK 
 attributes 
 . 
 condition 
 = 
 Condition 
 . 
 NEW 
 attributes 
 . 
 google_product_category 
 = 
 "Media > Books" 
 attributes 
 . 
 gtins 
 = 
 [ 
 "9780007350896" 
 ] 
 attributes 
 . 
 shipping 
 = 
 [ 
 shipping_option_1 
 , 
 shipping_option_2 
 ] 
 return 
 merchant_products_v1 
 . 
 ProductInput 
 ( 
 content_language 
 = 
 "en" 
 , 
 feed_label 
 = 
 "GB" 
 , 
 offer_id 
 = 
 "sku123" 
 , 
 product_attributes 
 = 
 attributes 
 , 
 ) 
 def 
  
 insert_product_input 
 (): 
  
 """Inserts the specified `ProductInput` resource.""" 
 # Gets OAuth Credentials. 
 credentials 
 = 
 generate_user_credentials 
 . 
 main 
 () 
 # Creates a client. 
 client 
 = 
 merchant_products_v1 
 . 
 ProductInputsServiceClient 
 ( 
 credentials 
 = 
 credentials 
 ) 
 # Creates the request. 
 request 
 = 
 merchant_products_v1 
 . 
 InsertProductInputRequest 
 ( 
 parent 
 = 
 _PARENT 
 , 
 # If this product is already owned by another datasource, when 
 # re-inserting, the new datasource will take ownership of the product. 
 product_input 
 = 
 create_product_input 
 (), 
 data_source 
 = 
 _DATA_SOURCE_NAME 
 , 
 ) 
 # Makes the request and catches and prints any error messages. 
 try 
 : 
 response 
 = 
 client 
 . 
 insert_product_input 
 ( 
 request 
 = 
 request 
 ) 
 # The last part of the product name will be the product ID assigned to a 
 # product by Google. Product ID has the format 
 # `contentLanguage~feedLabel~offerId` 
 print 
 ( 
 f 
 "Input successful: 
 { 
 response 
 } 
 " 
 ) 
 except 
 RuntimeError 
 as 
 e 
 : 
 print 
 ( 
 "Input failed" 
 ) 
 print 
 ( 
 e 
 ) 
 # After the product is inserted, the product ID will be returned in the 
 # response. We recommend that you check the Merchant Center to ensure that 
 # the product is approved and visible to users before using the product ID 
 # in any downstream processes. 
 if 
 __name__ 
 == 
 "__main__" 
 : 
 insert_product_input 
 () 
  
 

Java

  import 
  
 com.google.api.gax.core.FixedCredentialsProvider 
 ; 
 import 
  
 com.google.auth.oauth2.GoogleCredentials 
 ; 
 import 
  
 com.google.shopping.merchant.products.v1.Availability 
 ; 
 import 
  
 com.google.shopping.merchant.products.v1.Condition 
 ; 
 import 
  
 com.google.shopping.merchant.products.v1.InsertProductInputRequest 
 ; 
 import 
  
 com.google.shopping.merchant.products.v1.ProductAttributes 
 ; 
 import 
  
 com.google.shopping.merchant.products.v1.ProductInput 
 ; 
 import 
  
 com.google.shopping.merchant.products.v1.ProductInputsServiceClient 
 ; 
 import 
  
 com.google.shopping.merchant.products.v1.ProductInputsServiceSettings 
 ; 
 import 
  
 com.google.shopping.merchant.products.v1.Shipping 
 ; 
 import 
  
 com.google.shopping.type.Price 
 ; 
 import 
  
 shopping.merchant.samples.utils.Authenticator 
 ; 
 import 
  
 shopping.merchant.samples.utils.Config 
 ; 
 /** This class demonstrates how to insert a product input */ 
 public 
  
 class 
 InsertProductInputSample 
  
 { 
  
 private 
  
 static 
  
 String 
  
 getParent 
 ( 
 String 
  
 accountId 
 ) 
  
 { 
  
 return 
  
 String 
 . 
 format 
 ( 
 "accounts/%s" 
 , 
  
 accountId 
 ); 
  
 } 
  
 public 
  
 static 
  
 void 
  
 insertProductInput 
 ( 
 Config 
  
 config 
 , 
  
 String 
  
 dataSource 
 ) 
  
 throws 
  
 Exception 
  
 { 
  
 // Obtains OAuth token based on the user's configuration. 
  
 GoogleCredentials 
  
 credential 
  
 = 
  
 new 
  
 Authenticator 
 (). 
 authenticate 
 (); 
  
 // Creates service settings using the credentials retrieved above. 
  
 ProductInputsServiceSettings 
  
 productInputsServiceSettings 
  
 = 
  
 ProductInputsServiceSettings 
 . 
 newBuilder 
 () 
  
 . 
 setCredentialsProvider 
 ( 
 FixedCredentialsProvider 
 . 
 create 
 ( 
 credential 
 )) 
  
 . 
 build 
 (); 
  
 // Creates parent to identify where to insert the product. 
  
 String 
  
 parent 
  
 = 
  
 getParent 
 ( 
 config 
 . 
 getAccountId 
 (). 
 toString 
 ()); 
  
 // Calls the API and catches and prints any network failures/errors. 
  
 try 
  
 ( 
 ProductInputsServiceClient 
  
 productInputsServiceClient 
  
 = 
  
 ProductInputsServiceClient 
 . 
 create 
 ( 
 productInputsServiceSettings 
 )) 
  
 { 
  
 // Price to be used for shipping ($33.45). 
  
 Price 
  
 price 
  
 = 
  
 Price 
 . 
 newBuilder 
 (). 
 setAmountMicros 
 ( 
 33_450_000 
 ). 
 setCurrencyCode 
 ( 
 "USD" 
 ). 
 build 
 (); 
  
 Shipping 
  
 shipping 
  
 = 
  
 Shipping 
 . 
 newBuilder 
 () 
  
 . 
 setPrice 
 ( 
 price 
 ) 
  
 . 
 setCountry 
 ( 
 "GB" 
 ) 
  
 . 
 setService 
 ( 
 "1st class post" 
 ) 
  
 . 
 build 
 (); 
  
 Shipping 
  
 shipping2 
  
 = 
  
 Shipping 
 . 
 newBuilder 
 () 
  
 . 
 setPrice 
 ( 
 price 
 ) 
  
 . 
 setCountry 
 ( 
 "FR" 
 ) 
  
 . 
 setService 
 ( 
 "1st class post" 
 ) 
  
 . 
 build 
 (); 
  
 ProductAttributes 
  
 attributes 
  
 = 
  
 ProductAttributes 
 . 
 newBuilder 
 () 
  
 . 
 setTitle 
 ( 
 "A Tale of Two Cities" 
 ) 
  
 . 
 setDescription 
 ( 
 "A classic novel about the French Revolution" 
 ) 
  
 . 
 setLink 
 ( 
 "https://exampleWebsite.com/tale-of-two-cities.html" 
 ) 
  
 . 
 setImageLink 
 ( 
 "https://exampleWebsite.com/tale-of-two-cities.jpg" 
 ) 
  
 . 
 setAvailability 
 ( 
 Availability 
 . 
 IN_STOCK 
 ) 
  
 . 
 setCondition 
 ( 
 Condition 
 . 
 NEW 
 ) 
  
 . 
 setGoogleProductCategory 
 ( 
 "Media > Books" 
 ) 
  
 . 
 addGtins 
 ( 
 "9780007350896" 
 ) 
  
 . 
 addShipping 
 ( 
 shipping 
 ) 
  
 . 
 addShipping 
 ( 
 shipping2 
 ) 
  
 . 
 build 
 (); 
  
 // The datasource can be either a primary or supplemental datasource. 
  
 InsertProductInputRequest 
  
 request 
  
 = 
  
 InsertProductInputRequest 
 . 
 newBuilder 
 () 
  
 . 
 setParent 
 ( 
 parent 
 ) 
  
 // You can only insert products into datasource types of Input "API" and "FILE", and 
  
 // of Type "Primary" or "Supplemental." 
  
 // This field takes the `name` field of the datasource. 
  
 . 
 setDataSource 
 ( 
 dataSource 
 ) 
  
 // If this product is already owned by another datasource, when re-inserting, the 
  
 // new datasource will take ownership of the product. 
  
 . 
 setProductInput 
 ( 
  
 ProductInput 
 . 
 newBuilder 
 () 
  
 . 
 setContentLanguage 
 ( 
 "en" 
 ) 
  
 . 
 setFeedLabel 
 ( 
 "label" 
 ) 
  
 . 
 setOfferId 
 ( 
 "sku123" 
 ) 
  
 . 
 setProductAttributes 
 ( 
 attributes 
 ) 
  
 . 
 build 
 ()) 
  
 . 
 build 
 (); 
  
 System 
 . 
 out 
 . 
 println 
 ( 
 "Sending insert ProductInput request" 
 ); 
  
 ProductInput 
  
 response 
  
 = 
  
 productInputsServiceClient 
 . 
 insertProductInput 
 ( 
 request 
 ); 
  
 System 
 . 
 out 
 . 
 println 
 ( 
 "Inserted ProductInput Name below" 
 ); 
  
 // The last part of the product name will be the product ID assigned to a product by Google. 
  
 // Product ID has the format `contentLanguage~feedLabel~offerId` 
  
 System 
 . 
 out 
 . 
 println 
 ( 
 response 
 . 
 getName 
 ()); 
  
 System 
 . 
 out 
 . 
 println 
 ( 
 "Inserted Product Name below" 
 ); 
  
 System 
 . 
 out 
 . 
 println 
 ( 
 response 
 . 
 getProduct 
 ()); 
  
 } 
  
 catch 
  
 ( 
 Exception 
  
 e 
 ) 
  
 { 
  
 System 
 . 
 out 
 . 
 println 
 ( 
 e 
 ); 
  
 } 
  
 } 
  
 public 
  
 static 
  
 void 
  
 main 
 ( 
 String 
 [] 
  
 args 
 ) 
  
 throws 
  
 Exception 
  
 { 
  
 Config 
  
 config 
  
 = 
  
 Config 
 . 
 load 
 (); 
  
 // Identifies the data source that will own the product input. 
  
 String 
  
 dataSource 
  
 = 
  
 "accounts/" 
  
 + 
  
 config 
 . 
 getAccountId 
 () 
  
 + 
  
 "/dataSources/{INSERT_DATASOURCE_ID}" 
 ; 
  
 insertProductInput 
 ( 
 config 
 , 
  
 dataSource 
 ); 
  
 } 
 } 
  
 

PHP

  use Google\ApiCore\ApiException; 
 use Google\Shopping\Merchant\Products\V1\Availability; 
 use Google\Shopping\Merchant\Products\V1\Condition; 
 use Google\Shopping\Merchant\Products\V1\ProductAttributes; 
 use Google\Shopping\Merchant\Products\V1\InsertProductInputRequest; 
 use Google\Shopping\Merchant\Products\V1\ProductInput; 
 use Google\Shopping\Merchant\Products\V1\Client\ProductInputsServiceClient; 
 use Google\Shopping\Merchant\Products\V1\Shipping; 
 use Google\Shopping\Type\Price; 
 /** 
 * Uploads a product input to your Merchant Center account. 
 */ 
 class InsertProductInput 
 { 
 // ENSURE you fill in the datasource ID for the sample to work. 
 private const DATASOURCE = 'INSERT_DATASOURCE_ID'; 
 /** 
 * A helper function to create the parent string. 
 * 
 * @param array $accountId 
 *      The account that owns the product. 
 * 
 * @return string The parent has the format: `accounts/{account_id}` 
 */ 
 private static function getParent($accountId) 
 { 
 return sprintf("accounts/%s", $accountId); 
 } 
 /** 
 * Uploads a product input to your Merchant Center account. If an input 
 * with the same feedLabel, contentLanguage, offerId, and dataSource 
 * already exists, this method replaces that entry. 
 * 
 * After inserting, updating, or deleting a product input, it may take several 
 * minutes before the processed product can be retrieved. 
 * 
 * @param array $config 
 *      The configuration data used for authentication and getting the acccount 
 *      ID. 
 * @param string $dataSource 
 *      The primary or supplemental product data source name. If the 
 *      product already exists and data source provided is different, then the 
 *      product will be moved to a new data source. 
 *      Format: `accounts/{account}/dataSources/{datasource}`. 
 * 
 * @return void 
 */ 
 public static function insertProductInputSample($config, $dataSource): void 
 { 
 // Gets the OAuth credentials to make the request. 
 $credentials = Authentication::useServiceAccountOrTokenFile(); 
 // Creates options config containing credentials for the client to use. 
 $options = ['credentials' => $credentials]; 
 // Creates a client. 
 $productInputsServiceClient = new ProductInputsServiceClient($options); 
 // Creates parent to identify where to insert the product. 
 $parent = self::getParent($config['accountId']); 
 // Calls the API and catches and prints any network failures/errors. 
 try { 
 // Price to be used for shipping ($33.45). 
 $price = new Price( 
 [ 
 'amount_micros' => 33450000, 
 'currency_code' => 'USD' 
 ] 
 ); 
 $shipping = new Shipping( 
 [ 
 'price' => $price, 
 'country' => 'GB', 
 'service' => '1st class post' 
 ] 
 ); 
 $shipping2 = new Shipping( 
 [ 
 'price' => $price, 
 'country' => 'FR', 
 'service' => '1st class post' 
 ] 
 ); 
 // Creates the attributes of the product. 
 $attributes = new ProductAttributes( 
 [ 
 'title' => 'A Tale of Two Cities', 
 'description' => 'A classic novel about the French Revolution', 
 'link' => 'https://exampleWebsite.com/tale-of-two-cities.html', 
 'image_link' = 
> 'https://exampleWebsite.com/tale-of-two-cities.jpg', 
 'availability' => Availability::IN_STOCK, 
 'condition' => Condition::PBNEW, 
 'google_product_category' => 'Media > Books', 
 'gtins' => ['9780007350896'], 
 'shipping' => [$shipping, $shipping2] 
 ] 
 ); 
 // Creates the productInput with the fundamental identifiers. 
 $productInput = new ProductInput( 
 [ 
 'content_language' => 'en', 
 'feed_label' => 'label', 
 'offer_id' => 'sku123ABCD', 
 'product_attributes' => $attributes 
 ] 
 ); 
 // Prepares the request message. 
 $request = new InsertProductInputRequest( 
 [ 
 'parent' => $parent, 
 'data_source' => $dataSource, 
 'product_input' => $productInput 
 ] 
 ); 
 print "Sending insert ProductInput request\n"; 
 $response = $productInputsServiceClient->insertProductInput($request); 
 print "Inserted ProductInput Name below\n"; 
 print $response->getName() . "\n"; 
 print "Inserted Product Name below\n"; 
 print $response->getProduct() . "\n"; 
 } catch (ApiException $e) { 
 print $e->getMessage(); 
 } 
 } 
 /** 
 * Helper to execute the sample. 
 * 
 * @return void 
 */ 
 public function callSample(): void 
 { 
 $config = Config::generateConfig(); 
 // Identifies the data source that will own the product input. 
 $dataSource = sprintf( 
 "accounts/%s/dataSources/%s", 
 $config['accountId'], 
 self::DATASOURCE 
 ); 
 // Makes the call to insert a product to the MC account. 
 self::insertProductInputSample($config, $dataSource); 
 } 
 } 
 // Run the script 
 $sample = new InsertProductInput(); 
 $sample->callSample();  
 
 

cURL

  curl -X POST "https://merchantapi.googleapis.com/products/v1/accounts/ {ACCOUNT_ID} 
/productInputs:insert?dataSource= {DATASOURCE_NAME} 
" \ 
 -H "Content-Type: application/json" \ 
 -H "Authorization: Bearer {ACCESS_TOKEN} 
" \ 
 -d '{ 
 "contentLanguage": "en", 
 "feedLabel": "US", 
 "name": "Red T-shirt", 
 "productAttributes": { 
 "gender": "MALE", 
 "brand": "New brand" 
 }, 
 "offerId": "tshirt-123" 
 }' 
 

Get information about a product

To retrieve the final processed state of a product, you use the products.get method. Pass the value of the product field that you've got in the response body of the productInputs.insert method:

  GET https://merchantapi.googleapis.com/products/v1/accounts/ {ACCOUNT_ID} 
/products/ {PRODUCT_ID} 
 
 Content-Type: application/json 
 Authorization: Bearer {ACCESS_TOKEN} 
 
 

Replace the following:

  • ACCOUNT_ID : your Merchant Center ID
  • ACCESS_TOKEN : the authorization token to make the API Call
  • PRODUCT_ID : the value of the product field that you've got in the response body of the productInputs.insert method. Encoded (unpadded base64url) if it contains MAPI specific or URL-reserved characters.

A successful request returns the Product resource:

  { 
  
 "name" 
 : 
  
 "accounts/ {ACCOUNT_ID} 
/products/ {PRODUCT_ID} 
" 
 , 
  
 "offerId" 
 : 
  
 "SKU12345" 
 , 
  
 "contentLanguage" 
 : 
  
 "en" 
 , 
  
 "feedLabel" 
 : 
  
 "US" 
 , 
  
 "dataSource" 
 : 
  
 "accounts/ {ACCOUNT_ID} 
/dataSources/ {DATASOURCE_ID} 
" 
 , 
  
 "productAttributes" 
 : 
  
 { 
  
 "title" 
 : 
  
 "Classic Cotton T-Shirt" 
 , 
  
 "description" 
 : 
  
 "A comfortable, durable, and stylish t-shirt made from 100% cotton." 
 , 
  
 "link" 
 : 
  
 "https://www.example.com/p/SKU12345" 
 , 
  
 "imageLink" 
 : 
  
 "https://www.example.com/img/SKU12345.jpg" 
 , 
  
 "availability" 
 : 
  
 "IN_STOCK" 
 , 
  
 "price" 
 : 
  
 { 
  
 "amountMicros" 
 : 
  
 "15990000" 
 , 
  
 "currencyCode" 
 : 
  
 "USD" 
  
 }, 
  
 "condition" 
 : 
  
 "NEW" 
 , 
  
 "gtins" 
 : 
  
 [ 
  
 "9780007350896" 
  
 ] 
  
 }, 
  
 "productStatus" 
 : 
  
 { 
  
 "destinationStatuses" 
 : 
  
 [ 
  
 { 
  
 "reportingContext" 
 : 
  
 "SHOPPING_ADS" 
 , 
  
 "approvedCountries" 
 : 
  
 [ 
  
 "US" 
  
 ] 
  
 } 
  
 ], 
  
 "creationDate" 
 : 
  
 "2024-05-20T10:00:00Z" 
 , 
  
 "lastUpdateDate" 
 : 
  
 "2024-05-20T10:05:00Z" 
 , 
  
 "googleExpirationDate" 
 : 
  
 "2024-06-19T10:05:00Z" 
  
 } 
 } 
 

The Product resource represents a processed product and is typically built from one primary data source product input, and multiple supplemental data source inputs.

After inserting, updating, or deleting a product input, it may take from several seconds to a few minutes before the updated processed product can be retrieved.

This processed product matches what is shown in your Merchant Center account.

Python

  import 
  
 base64 
 from 
  
 examples.authentication 
  
 import 
 configuration 
 from 
  
 examples.authentication 
  
 import 
 generate_user_credentials 
 from 
  
 google.shopping.merchant_products_v1 
  
 import 
 GetProductRequest 
 from 
  
 google.shopping.merchant_products_v1 
  
 import 
 ProductsServiceClient 
 # This is needed for base64url encoding if product IDs contain special 
 # characters such as forward slashes. 
 def 
  
 encode_product_id 
 ( 
 product_id_to_encode 
 : 
 str 
 ) 
 - 
> str 
 : 
  
 """Base64url encodes a string without padding. 
 Args: 
 product_id_to_encode: The product ID string to encode. 
 Returns: 
 The encoded product ID string. 
 """ 
 encoded_bytes 
 = 
 base64 
 . 
 urlsafe_b64encode 
 ( 
 product_id_to_encode 
 . 
 encode 
 ( 
 "utf-8" 
 )) 
 return 
 encoded_bytes 
 . 
 rstrip 
 ( 
 b 
 "=" 
 ) 
 . 
 decode 
 ( 
 "utf-8" 
 ) 
 def 
  
 get_product 
 ( 
 account_id_arg 
 : 
 str 
 , 
 product_id_arg 
 : 
 str 
 ) 
 - 
> None 
 : 
  
 """Retrieves a single product from a Merchant Center account. 
 Args: 
 account_id_arg: The ID of the Merchant Center account. 
 product_id_arg: The ID of the product to retrieve. 
 """ 
 # Gets OAuth Credentials. 
 credentials 
 = 
 generate_user_credentials 
 . 
 main 
 () 
 # Creates a client. 
 client 
 = 
 ProductsServiceClient 
 ( 
 credentials 
 = 
 credentials 
 ) 
 # The name has the format: accounts/{account}/products/{product} 
 name 
 = 
 f 
 "accounts/ 
 { 
 account_id_arg 
 } 
 /products/ 
 { 
 product_id_arg 
 } 
 " 
 # Creates the request. 
 request 
 = 
 GetProductRequest 
 ( 
 name 
 = 
 name 
 ) 
 print 
 ( 
 "Sending get product request:" 
 ) 
 # Makes the request and catches and prints any error messages. 
 try 
 : 
 response 
 = 
 client 
 . 
 get_product 
 ( 
 request 
 = 
 request 
 ) 
 print 
 ( 
 "Retrieved Product below" 
 ) 
 print 
 ( 
 response 
 ) 
 except 
 RuntimeError 
 as 
 e 
 : 
 print 
 ( 
 e 
 ) 
 if 
 __name__ 
 == 
 "__main__" 
 : 
 # Retrieves the configured account ID from the config file. 
 account_id 
 = 
 configuration 
 . 
 Configuration 
 () 
 . 
 read_merchant_info 
 () 
 # The ID of the product, which is the final component of the product's 
 # resource name. The product ID is the same as the offer ID. 
 # For example, `en~US~sku123`. 
 product_id 
 = 
 "en~US~sku123" 
 # Replace with your actual product ID. 
 # Uncomment the following line if the product ID contains special characters 
 # (such as forward slashes) and needs base64url encoding. 
 # product_id = encode_product_id(product_id) 
 get_product 
 ( 
 account_id 
 , 
 product_id 
 ) 
  
 

Java

  import 
  
 com.google.api.gax.core.FixedCredentialsProvider 
 ; 
 import 
  
 com.google.auth.oauth2.GoogleCredentials 
 ; 
 import 
  
 com.google.common.io.BaseEncoding 
 ; 
 import 
  
 com.google.shopping.merchant.products.v1.GetProductRequest 
 ; 
 import 
  
 com.google.shopping.merchant.products.v1.Product 
 ; 
 import 
  
 com.google.shopping.merchant.products.v1.ProductsServiceClient 
 ; 
 import 
  
 com.google.shopping.merchant.products.v1.ProductsServiceSettings 
 ; 
 import 
  
 java.nio.charset.StandardCharsets 
 ; 
 import 
  
 shopping.merchant.samples.utils.Authenticator 
 ; 
 import 
  
 shopping.merchant.samples.utils.Config 
 ; 
 /** This class demonstrates how to get a single product for a given Merchant Center account */ 
 public 
  
 class 
 GetProductSample 
  
 { 
  
 // Base64Url encoder/decoder without padding 
  
 private 
  
 static 
  
 final 
  
 BaseEncoding 
  
 BASE64URL_NOPADDING 
  
 = 
  
 BaseEncoding 
 . 
 base64Url 
 (). 
 omitPadding 
 (); 
  
 // Encodes a string to base64url without padding 
  
 public 
  
 static 
  
 String 
  
 encodeProductId 
 ( 
 String 
  
 productId 
 ) 
  
 { 
  
 return 
  
 BASE64URL_NOPADDING 
 . 
 encode 
 ( 
 productId 
 . 
 getBytes 
 ( 
 StandardCharsets 
 . 
 UTF_8 
 )); 
  
 } 
  
 public 
  
 static 
  
 void 
  
 getProduct 
 ( 
 Config 
  
 config 
 , 
  
 String 
  
 accountId 
 , 
  
 String 
  
 productId 
 ) 
  
 throws 
  
 Exception 
  
 { 
  
 // Obtains OAuth token based on the user's configuration. 
  
 GoogleCredentials 
  
 credential 
  
 = 
  
 new 
  
 Authenticator 
 (). 
 authenticate 
 (); 
  
 // Creates service settings using the credentials retrieved above. 
  
 ProductsServiceSettings 
  
 productsServiceSettings 
  
 = 
  
 ProductsServiceSettings 
 . 
 newBuilder 
 () 
  
 . 
 setCredentialsProvider 
 ( 
 FixedCredentialsProvider 
 . 
 create 
 ( 
 credential 
 )) 
  
 . 
 build 
 (); 
  
 // Calls the API and catches and prints any network failures/errors. 
  
 try 
  
 ( 
 ProductsServiceClient 
  
 productsServiceClient 
  
 = 
  
 ProductsServiceClient 
 . 
 create 
 ( 
 productsServiceSettings 
 )) 
  
 { 
  
 // The name has the format: accounts/{account}/products/{productId} 
  
 String 
  
 name 
  
 = 
  
 "accounts/" 
  
 + 
  
 accountId 
  
 + 
  
 "/products/" 
  
 + 
  
 productId 
 ; 
  
 // The name has the format: accounts/{account}/products/{productId} 
  
 GetProductRequest 
  
 request 
  
 = 
  
 GetProductRequest 
 . 
 newBuilder 
 (). 
 setName 
 ( 
 name 
 ). 
 build 
 (); 
  
 System 
 . 
 out 
 . 
 println 
 ( 
 "Sending get product request:" 
 ); 
  
 Product 
  
 response 
  
 = 
  
 productsServiceClient 
 . 
 getProduct 
 ( 
 request 
 ); 
  
 System 
 . 
 out 
 . 
 println 
 ( 
 "Retrieved Product below" 
 ); 
  
 System 
 . 
 out 
 . 
 println 
 ( 
 response 
 ); 
  
 } 
  
 catch 
  
 ( 
 Exception 
  
 e 
 ) 
  
 { 
  
 System 
 . 
 out 
 . 
 println 
 ( 
 e 
 ); 
  
 } 
  
 } 
  
 public 
  
 static 
  
 void 
  
 main 
 ( 
 String 
 [] 
  
 args 
 ) 
  
 throws 
  
 Exception 
  
 { 
  
 Config 
  
 config 
  
 = 
  
 Config 
 . 
 load 
 (); 
  
 String 
  
 accountId 
  
 = 
  
 config 
 . 
 getAccountId 
 (). 
 toString 
 (); 
  
 // The name of the `product`, returned after a `Product.insert` request. We recommend 
  
 // having stored this value in your database to use for all future requests. 
  
 String 
  
 productId 
  
 = 
  
 "en~US~sku123" 
 ; 
  
 // Replace with your actual product ID 
  
 // Uncomment the following line if the product name contains special characters (such as forward 
  
 // slashes) and needs base64url encoding. 
  
 // productId = encodeProductId(productId); 
  
 getProduct 
 ( 
 config 
 , 
  
 accountId 
 , 
  
 productId 
 ); 
  
 } 
 } 
  
 

PHP

  require_once __DIR__ . '/../../../vendor/autoload.php'; 
 require_once __DIR__ . '/../../Authentication/Authentication.php'; 
 require_once __DIR__ . '/../../Authentication/Config.php'; 
 use Google\ApiCore\ApiException; 
 use Google\Shopping\Merchant\Products\V1\Client\ProductsServiceClient; 
 use Google\Shopping\Merchant\Products\V1\GetProductRequest; 
 /** 
 * This class demonstrates how to get a single product for a given Merchant 
 * Center account. 
 */ 
 class GetProductSample 
 { 
 /** 
 * A helper function to create the product name string. 
 * 
 * @param string $accountId 
 *      The account that owns the product. 
 * @param string $productId 
 *      The ID of the product. 
 * 
 * @return string The name has the format: `accounts/{account}/products/{product}` 
 */ 
 private static function getName(string $accountId, string $productId): string 
 { 
 return sprintf("accounts/%s/products/%s", $accountId, $productId); 
 } 
 /** 
 * Encodes a string to base64url without padding. This is needed if the 
 * product ID contains special characters (such as forward slashes) and 
 * needs base64url encoding. 
 * 
 * @param string $productId 
 *      The ID of the product. 
 * 
 * @return string The encoded product ID. 
 */ 
 public static function encodeProductId(string $productId): string 
 { 
 return rtrim(strtr(base64_encode($productId), '+/', '-_'), '='); 
 } 
 /** 
 * Retrieves a product from your Merchant Center account. 
 * 
 * @param array $config 
 *      The configuration data used for authentication and getting the 
 *      account ID. 
 * @param string $productId 
 *      The ID of the product, in the form of 
 *      `contentLanguage:feedLabel:offerId`. 
 * 
 * @return void 
 */ 
 public static function getProduct(array $config, string $productId): void 
 { 
 // Gets the OAuth credentials to make the request. 
 $credentials = Authentication::useServiceAccountOrTokenFile(); 
 // Creates options config containing credentials for the client to use. 
 $options = ['credentials' => $credentials]; 
 // Creates a client. 
 $productsServiceClient = new ProductsServiceClient($options); 
 // The name has the format: accounts/{account}/products/{productId} 
 $name = self::getName($config['accountId'], $productId); 
 // Creates the request. 
 $request = new GetProductRequest([ 
 'name' => $name 
 ]); 
 // Calls the API and catches and prints any network failures/errors. 
 try { 
 print "Sending get product request:\n"; 
 $response = $productsServiceClient->getProduct($request); 
 print "Retrieved Product below\n"; 
 // Pretty-prints the JSON representation of the response. 
 print $response->serializeToJsonString(true) . "\n"; 
 } catch (ApiException $e) { 
 printf("Call failed with message: %s\n", $e->getMessage()); 
 } 
 } 
 /** 
 * Helper to execute the sample. 
 * 
 * @return void 
 */ 
 public function callSample(): void 
 { 
 $config = Config::generateConfig(); 
 // The name of the `product`, returned after a `Product.insert` request. 
 // We recommend having stored this value in your database to use for all 
 // future requests. 
 $productId = 'en~US~sku123'; // Replace with your actual product ID 
 // Uncomment the following line if the product name contains special 
 // characters (such as forward slashes) and needs base64url encoding. 
 // $productId = self::encodeProductId($productId); 
 self::getProduct($config, $productId); 
 } 
 } 
 // Runs the sample. 
 $sample = new GetProductSample(); 
 $sample->callSample();  
 
 

cURL

  curl -X GET "https://merchantapi.googleapis.com/products/v1/accounts/ {ACCOUNT_ID} 
/products/ {PRODUCT_ID} 
" \ 
 -H "Authorization: Bearer {ACCESS_TOKEN} 
" 
 

Congratulations! You have now successfully completed the five-step setup process and inserted your first products using the Merchant API.

For further assistance or to explore common questions, refer to the FAQ section .

Create a Mobile Website
View Site in Mobile | Classic
Share by: