Merchant API code sample to insert product input.

### C#

    // Copyright 2025 Google LLC
    //
    // Licensed under the Apache License, Version 2.0 (the "License");
    // you may not use this file except in compliance with the License.
    // You may obtain a copy of the License at
    //
    //     https://www.apache.org/licenses/LICENSE-2.0
    //
    // Unless required by applicable law or agreed to in writing, software
    // distributed under the License is distributed on an "AS IS" BASIS,
    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    // See the License for the specific language governing permissions and
    // limitations under the License.

    using Google.Apis.Auth.OAuth2;
    using Google.Shopping.Merchant.Products.V1;
    using Google.Shopping.Type;
    using System;
    using static MerchantApi.Authenticator;
    using Price = Google.Shopping.Type.Price;

    namespace MerchantApi
    {

        public class InsertProductInputSample
        {
            /// Inserts a product input into a specified data source.
            public void InsertProductInput(string merchantId, string dataSource)
            {
                Console.WriteLine("=================================================================");
                Console.WriteLine("Inserting a ProductInput into a data source...");
                Console.WriteLine("=================================================================");

                // Authenticate using either oAuth or service account
                ICredential auth = Authenticator.Authenticate(
                    MerchantConfig.Load(),
                    ProductsServiceClient.DefaultScopes[0]);

                // Creates the ProductInputsServiceClient.
                var productInputsServiceClient = new ProductInputsServiceClientBuilder
                {
                    Credential = auth
                }.Build();

                // The parent account.
                string parent = $"accounts/{merchantId}";

                // The price for shipping.
                Price price = new Price { AmountMicros = 33_450_000, CurrencyCode = "USD" };

                // Shipping information for Great Britain.
                Shipping shipping = new Shipping
                {
                    Price = price,
                    Country = "GB",
                    Service = "1st class post"
                };

                // Shipping information for France.
                Shipping shipping2 = new Shipping
                {
                    Price = price,
                    Country = "FR",
                    Service = "1st class post"
                };

                // The attributes of the product.
                ProductAttributes 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",
                    ImageLink = "https://exampleWebsite.com/tale-of-two-cities.jpg",
                    Availability = Availability.InStock,
                    Condition = Condition.New,
                    GoogleProductCategory = "Media > Books",
                    Gtins = { "9780007350896" },
                    Shipping = { shipping, shipping2 }
                };

                // The product input to insert.
                ProductInput productInput = new ProductInput
                {
                    ContentLanguage = "en",
                    FeedLabel = "US",
                    OfferId = "sku123",
                    ProductAttributes = attributes
                };

                // Creates the request to insert the product input.
                // The data source can be a primary or supplemental data source.
                // You can only insert products into data sources of type "API" or "FILE".
                InsertProductInputRequest request = new InsertProductInputRequest
                {
                    Parent = parent,
                    DataSource = dataSource,
                    ProductInput = productInput
                };

                try
                {
                    Console.WriteLine("Sending insert ProductInput request...");
                    ProductInput response = productInputsServiceClient.InsertProductInput(request);

                    Console.WriteLine("Inserted ProductInput Name below:");
                    // The last part of the product input name is the product ID assigned by Google.
                    // Format: `contentLanguage~feedLabel~offerId`
                    Console.WriteLine(response.Name);

                    Console.WriteLine("Inserted Product Name below:");
                    Console.WriteLine(response.Product);
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                }
            }

            public static void Main(string[] args)
            {
                MerchantConfig config = MerchantConfig.Load();

                string merchantId = config.MerchantId.Value.ToString();
                // The ID of the data source that will own the product input.
                // This field takes the `name` of the data source.
                // Replace {INSERT_DATASOURCE_ID} with your actual data source ID.
                string dataSourceId = "{INSERT_DATASOURCE_ID}";
                string dataSource = $"accounts/{merchantId}/dataSources/{dataSourceId}";

                var sample = new InsertProductInputSample();
                sample.InsertProductInput(merchantId, dataSource);
            }
        }
    }

### Go

    // Copyright 2025 Google LLC
    //
    // Licensed under the Apache License, Version 2.0 (the "License");
    // you may not use this file except in compliance with the License.
    // You may obtain a copy of the License at
    //
    //     https://www.apache.org/licenses/LICENSE-2.0
    //
    // Unless required by applicable law or agreed to in writing, software
    // distributed under the License is distributed on an "AS IS" BASIS,
    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    // See the License for the specific language governing permissions and
    // limitations under the License.

    // Package v1 provides examples for managing a product input using the Merchant API.
    package v1


    import (
    	"context"
    	"fmt"
    	"log"

    	"cloud.google.com/go/shopping/merchant/products/apiv1/productspb"
    	"cloud.google.com/go/shopping/type/typepb"

    	products "cloud.google.com/go/shopping/merchant/products/apiv1"

    	"google.golang.org/api/option"

    	"github.com/google/merchant-api-samples/go/collection"
    	"github.com/google/merchant-api-samples/go/examples/googleauth"
    )

    const dataSourceForInsert = "accounts/1234567890/dataSources/1234567890"
    const accountForInsert = "accounts/1234567890"

    type insertProductInputSample struct{}

    func init() {
    	if err := collection.Add("products.productinputs.v1.insert_product_input", &insertProductInputSample{}); err != nil {
    		log.Fatalf("could not add example: %v", err)
    	}
    }

    func (s *insertProductInputSample) Description() string {
    	return "This sample demonstrates how to insert a product input"
    }

    func (s *insertProductInputSample) Execute() error {
    	ctx := context.Background()

    	tokenSource, err := googleauth.AuthWithGoogle(ctx)
    	if err != nil {
    		return fmt.Errorf("failed to authenticate: %w", err)
    	}

    	productInputsClient, err := products.NewProductInputsClient(ctx, option.WithTokenSource(tokenSource))
    	if err != nil {
    		return fmt.Errorf("could not create product inputs client: %w", err)
    	}
    	defer productInputsClient.Close()

    	parent := accountForInsert

    	// Define Price using inline pointers
    	price := &typepb.Price{
    		AmountMicros: collection.Ptr(int64(33450000)),
    		CurrencyCode: collection.Ptr("USD"),
    	}

    	// Shipping fields (Country/Service) are raw strings, so no ptr() needed here.
    	shipping1 := &productspb.Shipping{
    		Price:   price,
    		Country: "GB",
    		Service: "1st class post",
    	}

    	shipping2 := &productspb.Shipping{
    		Price:   price,
    		Country: "FR",
    		Service: "1st class post",
    	}

    	// Define Attributes using inline pointers for strings and enums
    	attributes := &productspb.ProductAttributes{
    		Title:                 collection.Ptr("A Tale of Two Cities"),
    		Description:           collection.Ptr("A classic novel about the French Revolution"),
    		Link:                  collection.Ptr("https://exampleWebsite.com/tale-of-two-cities.html"),
    		ImageLink:             collection.Ptr("https://exampleWebsite.com/tale-of-two-cities.jpg"),
    		Availability:          collection.Ptr(productspb.Availability_IN_STOCK),
    		Condition:             collection.Ptr(productspb.Condition_NEW),
    		GoogleProductCategory: collection.Ptr("Media > Books"),
    		Gtins:                 []string{"9780007350896"},
    		Shipping:              []*productspb.Shipping{shipping1, shipping2},
    	}

    	productInput := &productspb.ProductInput{
    		ContentLanguage:   "en",
    		FeedLabel:         "label",
    		OfferId:           "sku123",
    		ProductAttributes: attributes,
    	}

    	req := &productspb.InsertProductInputRequest{
    		Parent:       parent,
    		DataSource:   dataSourceForInsert,
    		ProductInput: productInput,
    	}

    	fmt.Println("Sending insert ProductInput request")
    	resp, err := productInputsClient.InsertProductInput(ctx, req)
    	if err != nil {
    		return fmt.Errorf("could not insert product input: %w", err)
    	}

    	fmt.Println("Inserted ProductInput Name below")
    	fmt.Println(resp.Name)
    	return nil
    }


### AppsScript

    // Copyright 2025 Google LLC
    //
    // Licensed under the Apache License, Version 2.0 (the "License");
    // you may not use this file except in compliance with the License.
    // You may obtain a copy of the License at
    //
    //     https://www.apache.org/licenses/LICENSE-2.0
    //
    // Unless required by applicable law or agreed to in writing, software
    // distributed under the License is distributed on an "AS IS" BASIS,
    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    // See the License for the specific language governing permissions and
    // limitations under the License.


    /**
     * Inserts a product into the products list. Logs the API response.
     */
    function productInsert() {
      // IMPORTANT:
      // Enable the Merchant API Products sub-API Advanced Service and call it
      // "MerchantApiProducts"

      // Replace this with your Merchant Center ID.
      const accountId = 'INSERT_MERCHANT_ID';

      // Replace this with the Data Source ID you want to use.
      const dataSourceId = 'INSERT_DATASOURCE_ID';

      // Construct the parent name
      const parent = 'accounts/' + accountId;

      // Construct the Data Source name
      const dataSource = parent + '/dataSources/' + dataSourceId;

      // Create a product resource and insert it
      const productResource = {
        'offerId': 'fromAppsScript',
        'contentLanguage': 'en',
        'feedLabel': 'US',
        'productAttributes': {
          'title': 'A Tale of Two Cities',
          'description': 'A classic novel about the French Revolution',
          'link': 'http://my-book-shop.com/tale-of-two-cities.html',
          'imageLink': 'http://my-book-shop.com/tale-of-two-cities.jpg',
          'availability': 'IN_STOCK',
          'condition': 'new',
          'googleProductCategory': 'Media > Books',
          'gtins': '[9780007350896]',
          'price': {'amountMicros': '2500000', 'currencyCode': 'USD'},
        },
      };

      try {
        console.log('Sending insert ProductInput request');
        // Call the ProductInputs.insert API method.
        const response = MerchantApiProducts.Accounts.ProductInputs.insert(
            productResource, parent, {dataSource});
        // RESTful insert returns the JSON object as a response.
        console.log('Inserted ProductInput below');
        console.log(response);
      } catch (e) {
        console.log('ERROR!');
        console.log(e);
      }
    }

### Java

    // Copyright 2024 Google LLC
    //
    // Licensed under the Apache License, Version 2.0 (the "License");
    // you may not use this file except in compliance with the License.
    // You may obtain a copy of the License at
    //
    //     https://www.apache.org/licenses/LICENSE-2.0
    //
    // Unless required by applicable law or agreed to in writing, software
    // distributed under the License is distributed on an "AS IS" BASIS,
    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    // See the License for the specific language governing permissions and
    // limitations under the License.

    package shopping.merchant.samples.products.v1;

    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 ProductInput 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());

        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("GB")
                          .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());
          return response;
        }
      }

      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);
      }
    }

### Node.js

    // Copyright 2025 Google LLC
    //
    // Licensed under the Apache License, Version 2.0 (the "License");
    // you may not use this file except in compliance with the License.
    // You may obtain a copy of the License at
    //
    //     https://www.apache.org/licenses/LICENSE-2.0
    //
    // Unless required by applicable law or agreed to in writing, software
    // distributed under the License is distributed on an "AS IS" BASIS,
    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    // See the License for the specific language governing permissions and
    // limitations under the License.

    'use strict';
    const fs = require('fs');
    const authUtils = require('../../authentication/authenticate.js');
    const {ProductInputsServiceClient} = require('@google-shopping/products').v1;

    const {protos} = require('@google-shopping/products');

    const Availability = protos.google.shopping.merchant.products.v1.Availability;
    const Condition = protos.google.shopping.merchant.products.v1.Condition;

    /**
     * Inserts a product input for a given Merchant Center account and data source.
     * @param {!object} config - The configuration object.
     * @param {string} dataSource - The data source name.
     */
    async function insertProductInput(config, dataSource) {
      // Read merchant_id from merchant-info.json.
      const merchantInfo = JSON.parse(
        fs.readFileSync(config.merchantInfoFile, 'utf8'),
      );
      const merchantId = merchantInfo.merchantId;

      // Construct the parent resource name.
      // Format: accounts/{account}
      const parent = `accounts/${merchantId}`;

      // Get credentials.
      const authClient = await authUtils.getOrGenerateUserCredentials();

      // Create options object for the client.
      const options = {authClient: authClient};

      // Create the ProductInputsServiceClient.
      const productInputsClient = new ProductInputsServiceClient(options);

      // Define the price objects.
      const shippingPrice = {
        amountMicros: 3000000, // 3 USD
        currencyCode: 'USD',
      };

      const price = {
        amountMicros: 33450000, // 33.45 USD
        currency_code: 'USD',
      };

      // Define shipping details.
      const shipping1 = {
        price: shippingPrice,
        country: 'GB',
        service: '1st class post',
      };

      const shipping2 = {
        price: shippingPrice,
        country: 'FR',
        service: '1st class post',
      };

      // Define product attributes.
      const attributes = {
        title: 'A Tale of Two Cities',
        description: 'A classic novel about the French Revolution',
        link: 'https://exampleWebsite.com/tale-of-two-cities.html',
        imageLink: 'https://exampleWebsite.com/tale-of-two-cities.jpg',
        availability: Availability.IN_STOCK,
        condition: Condition.NEW,
        googleProductCategory: 'Media > Books',
        gtins: ['9780007350896'], // GTIN is a repeated field
        shipping: [shipping1, shipping2], // Shipping is a repeated field
        price: price,
      };

      // Define the product input object.
      const productInput = {
        contentLanguage: 'en',
        feedLabel: 'label',
        offerId: 'sku123',
        productAttributes: attributes,
      };

      // Construct the request object.
      const request = {
        parent: 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.
        // If this product is already owned by another datasource, when re-inserting,
        // the new datasource will take ownership of the product.
        dataSource: dataSource,
        productInput: productInput,
      };

      try {
        console.log('Sending insert ProductInput request');
        // Call the API to insert the product input.
        const [response] = await productInputsClient.insertProductInput(request);

        console.log('Inserted ProductInput Name below');
        // The last part of the product name will be the product ID assigned by Google.
        // Product ID has the format `contentLanguage~feedLabel~offerId`
        console.log(response.name);
        console.log('Inserted Product Name below');
        console.log(response.product);
        console.log('Inserted Product below');
        console.log(response);
      } catch (error) {
        console.error(error.message);
      }
    }

    /**
     * Main function to call the insertProductInput function.
     */
    async function main() {
      const config = authUtils.getConfig();
      // Read merchant_id from merchant-info.json.
      const merchantInfo = JSON.parse(
        fs.readFileSync(config.merchantInfoFile, 'utf8'),
      );
      const merchantId = merchantInfo.merchantId;

      // Identifies the data source that will own the product input.
      // Replace {INSERT_DATASOURCE_ID} with the actual ID of your data source.
      // Format: accounts/{account}/dataSources/{dataSource}
      const dataSource = `accounts/${merchantId}/dataSources/{INSERT_DATASOURCE_ID}`;

      await insertProductInput(config, dataSource);
    }

    main();

### PHP

    <?php
    /**
     * Copyright 2024 Google LLC
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *
     *     https://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */

    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\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();

### Python

    # -*- coding: utf-8 -*-
    # Copyright 2024 Google LLC
    #
    # Licensed under the Apache License, Version 2.0 (the "License");
    # you may not use this file except in compliance with the License.
    # You may obtain a copy of the License at
    #
    #     http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License.
    """A module to insert a Product Input."""

    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


    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(account_id: str, data_source: str):
      """Inserts the specified `ProductInput` resource.

      Args:
        account_id: The Merchant Center account ID.
        data_source: The resource name of the data source that will own the product
          input.

      Returns:
        The inserted `ProductInput` resource.
      """

      # Gets OAuth Credentials.
      credentials = generate_user_credentials.main()

      # Creates a client.
      client = merchant_products_v1.ProductInputsServiceClient(
          credentials=credentials
      )

      parent = f"accounts/{account_id}"

      # 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,
      )

      # 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}")
        return 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.
        raise


    if __name__ == "__main__":
      # Retrieves the Merchant Center account ID from the configuration file.
      merchant_account_id = configuration.Configuration().read_merchant_info()
      # Identifies the data source that will own the product input.
      # You can only insert products into datasource types of Input "API" and
      # "FILE", and of Type "Primary" or "Supplemental."
      target_data_source = (
          f"accounts/{merchant_account_id}/dataSources/[INSERT_DATA_SOURCE_HERE]"
      )

      insert_product_input(merchant_account_id, target_data_source)