The Data Sources sub-API lets you create and manage data sources
specifically for uploading products through the API. You need to specify at
least one data source to be able to provide product details to the
Merchant Center.

This guide walks you through common use cases for managing these API-based data
sources. For information about uploading products using these data sources, see
the [Add and manage products](https://developers.google.com/merchant/api/guides/products/add-manage) guide.
You can also manage your data sources through the Merchant Center user
interface. For more information, see
[Manage your data sources](https://support.google.com/merchants/answer/13982673).

## Special considerations

When working with data sources in the Merchant API, keep the following in
mind:

- **Rules** : The Data Sources sub-API supports default rules for linking
  supplemental data sources to primary data sources. You can manage the order
  of supplemental data sources within the default rule. Complex custom rule
  creation and management aren't supported directly with this API. You can
  manage this using the
  [Merchant Center UI](https://support.google.com/merchants/answer/14994083).

- **Advanced account supplemental data sources** : The API doesn't support
  supplemental data sources and rules for advanced (multi-client) accounts.
  You can manage
  [supplemental data sources](https://developers.google.com/support.google.com/merchants/answer/14990942?ref_topic=12672304&sjid=14182222024994498957-EU#supplementaldatasource)
  and
  [rules](https://developers.google.com/support.google.com/merchants/answer/15157397?sjid=14182222024994498957-EU)
  only using the Merchant Center UI.

## Create a primary data source for products

When you want to create a
[`PrimaryProductDataSource`](https://developers.google.com/merchant/api/reference/rest/datasources_v1/accounts.dataSources#PrimaryProductDataSource)
that can accept products with any label and language, don't specify `feedLabel`
and `contentLanguage`. This setup simplifies management for merchants who don't
require distinct rules or configurations for different country or language
targets, as it allows them to manage only one data source ID.

Otherwise, you can create a data source and restrict it to a specific label and
language. If you plan to use data source rules or other configurations (like
[country targeting](https://developers.google.com/merchant/api/guides/data-sources/api-sources#country-targeting)) that apply to specific combinations of
labels and languages, specify the `feedLabel` and `contentLanguage`.

For more information about data source strategies, see [Choose your data source
strategy](https://developers.google.com/merchant/api/guides/compatibility/data-sources#choose-data-strategy).

Note that the data source `feedLabel` **has no impact** on targeted country. For
example, using `US` as a label doesn't automatically target users in the United
States. To control where your products are displayed and eligible, target
countries are determined as follows:

- **Data source level:** Set default target countries on the [`primary product data source`](https://developers.google.com/merchant/api/reference/rest/datasources_v1/accounts.dataSources#primaryproductdatasource) using the [`countries`](https://developers.google.com/merchant/api/reference/rest/datasources_v1/accounts.dataSources#PrimaryProductDataSource.FIELDS.countries) field. These apply to all products in that data source.
- **Product level (online):** For online marketing methods, specify target countries for individual items using the [`shipping`](https://developers.google.com/merchant/api/reference/rest/products_v1/ProductAttributes#FIELDS.shipping) field in [`product attributes`](https://developers.google.com/merchant/api/reference/rest/products_v1/ProductAttributes).
- **Account level (local):** For local marketing methods, target countries are determined automatically from the physical stores linked to your Merchant Center account.

For more information about targeting specific countries, see
[Add products targeting specific countries](https://developers.google.com/merchant/api/guides/products/add-manage#add_products_targeting_specific_countries).

All newly created data sources are available by default for all the destinations
enabled on the account. For more information, see
[Destinations](https://developers.google.com/merchant/api/reference/rest/datasources_v1/accounts.dataSources#destination).
This approach offers a unified, integrated experience, supporting the
[multi-channel](https://support.google.com/merchants/answer/16529073) strategy.

> [!NOTE]
> **Note:** Although it's possible to create data sources that target exclusively local products by setting the [`legacy_local`](https://developers.google.com/merchant/api/reference/rest/datasources_v1/accounts.dataSources#PrimaryProductDataSource.FIELDS.legacy_local) field to true, we don't recommend this approach because of its increased complexity.

### Country targeting

You can configure target countries in two ways:

- **No default countries (flexible targeting):** If you create the
  data source with an empty `primaryProductDataSource` object (as shown
  in the first example below), the data source itself targets no default
  countries. How countries are determined depends on your marketing method:

  - **Online store:** You can specify target countries for each product individually using the [`shipping`](https://developers.google.com/merchant/api/reference/rest/products_v1/ProductAttributes#FIELDS.shipping) attribute in the product data.
  - **Local stores:** Target countries are determined automatically from the physical stores linked to your Merchant Center account, so you don't need to specify shipping.
- **Default countries (data source-level targeting):** You can explicitly
  specify default target countries using the `countries` field (as shown
  in the second example below). All products uploaded to this data source
  default to targeting these countries.

#### Recommendations

- **Single data source targeting fixed countries:** If all products in the data source target the same country or set of countries, set the `countries` field on the data source.
- **Single data source targeting variable countries:** If you manage a single data source containing products distributed across different countries, omit `countries` on the data source and set them at the product level using the `shipping` attribute.
- **Multiple country-specific data sources:** If you prefer isolating products
  or business rules by region, create separate primary data sources for each
  country (or set of countries) and set the `countries` field on each data
  source. While managing multiple data source IDs requires additional
  overhead, this lets you configure distinct data source rules per country.

  > [!IMPORTANT]
  > **Important:** Data sources don't namespace products. To prevent products uploaded across different data sources from overwriting each other, distinguish them by assigning distinct `feedLabel` values (such as `US` and `CA`) or unique `offerId` values.

### Data source for any label and language

When products are inserted into this data source using the
[`products.insert`](https://developers.google.com/merchant/api/reference/rest/products_v1/accounts.productInputs/insert)
method, the API accepts any combination of `feedLabel` and `contentLanguage`
provided within the product data itself. The data source serves as a single
container for products targeting multiple different language and label
combinations. If you have a straightforward setup that doesn't use complex data
source rules, we recommend omitting the `feedLabel` and `contentLanguage`
fields.

#### Restrictions and considerations

- Creating a data source compatible with any label and language is only supported for primary data sources utilizing the `API`.
- These data sources can be linked with either broad or targeted supplemental data sources. Matching during processing occurs based on the individual product's specific `feedLabel` and `contentLanguage`.

#### Examples

Here is an example of creating a data source for any label and language
**without** a default country:

    POST https://merchantapi.googleapis.com/datasources/v1/accounts/{ACCOUNT_ID}/dataSources

    {
      "displayName": "My API Primary Product Source (No Default Countries)",
      "primaryProductDataSource": {}
    }

A successful request returns the following `DataSource` resource:

    {
      "name": "accounts/{ACCOUNT_ID}/dataSources/{DATASOURCE_ID}",
      "dataSourceId": "{DATASOURCE_ID}",
      "displayName": "My API Primary Product Source (No Default Countries)",
      "primaryProductDataSource": {},
      "input": "API"
    }

Here is an example of creating a data source for any label and language **with**
a default country (Great Britain):

    POST https://merchantapi.googleapis.com/datasources/v1/accounts/{ACCOUNT_ID}/dataSources

    {
      "displayName": "My API Primary Product Source (GB Default)",
      "primaryProductDataSource": {
        "countries": ["GB"]
      }
    }

A successful request returns the following `DataSource` resource:

    {
      "name": "accounts/{ACCOUNT_ID}/dataSources/{DATASOURCE_ID}",
      "dataSourceId": "{DATASOURCE_ID}",
      "displayName": "My API Primary Product Source (GB Default)",
      "primaryProductDataSource": {
        "countries": [
          "GB"
        ]
      },
      "input": "API"
    }

Use the `name` of the newly-created data source to refer to it when
inserting products with the Products sub-API.

The following code samples show how to create a
[`PrimaryProductDataSource`](https://developers.google.com/merchant/api/reference/rest/datasources_v1/accounts.dataSources#PrimaryProductDataSource)
without setting the `feedLabel`, `contentLanguage`, and `countries` fields.

### Java

    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

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

### Python

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

### cURL

    curl -X POST \
    "https://merchantapi.googleapis.com/datasources/v1/accounts/{ACCOUNT_ID}/dataSources" \
    -H "Authorization: Bearer {API_TOKEN}" \
    -H "Content-Type: application/json" \
    -d '{
          "displayName": "Primary Product Data Multiple Languages",
          "primaryProductDataSource": {
            "countries": ["GB"]
          }
        }'

### Data source for a specific label and language

To create a data source that only accepts products for a specific label and
language combination, set the `feedLabel` and `contentLanguage` fields using the
[`dataSources.create`](https://developers.google.com/merchant/api/reference/rest/datasources_v1/accounts.dataSources/create)
method:

    POST https://merchantapi.googleapis.com/datasources/v1/accounts/{ACCOUNT_ID}/dataSources

    {
      "displayName": "My API Primary Product Source (US-en)",
      "primaryProductDataSource": {
        "feedLabel": "US",
        "contentLanguage": "en",
        "countries": ["US"]
      }
    }

A successful request returns the newly-created `DataSource` resource. You can
use `name` of the newly-created data source to refer to this data source when
inserting products with the Products sub-API.

    {
      "name": "accounts/{ACCOUNT_ID}/dataSources/{DATASOURCE_ID}",
      "dataSourceId": "{DATASOURCE_ID}",
      "displayName": "My API Primary Product Source (US-en)",
      "primaryProductDataSource": {
        "feedLabel": "US",
        "contentLanguage": "en",
        "countries": ["US"]
      },
      "input": "API"
    }

The following code samples show how to create a data source that only accepts
products for a specific label and language combination.

### Java

    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 com.google.shopping.type.Destination.DestinationEnum;
    import shopping.merchant.samples.utils.Authenticator;
    import shopping.merchant.samples.utils.Config;

    /**
     * This class demonstrates how to create a primary product datasource for the "en" and "GB"
     * `feedLabel` and `contentLanguage` combination.
     */
    public class CreatePrimaryProductDataSourceSample {

      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")
                .setContentLanguage("en")
                .setFeedLabel("GB")
                // The destinations do not necessarily have to be explicitly listed in which case the
                // default enabled destinations will be used.
                .addDestinations(
                    PrimaryProductDataSource.Destination.newBuilder()
                        .setDestination(DestinationEnum.FREE_LISTINGS)
                        .setState(PrimaryProductDataSource.Destination.State.ENABLED)
                        .build())
                .addDestinations(
                    PrimaryProductDataSource.Destination.newBuilder()
                        .setDestination(DestinationEnum.SHOPPING_ADS)
                        .setState(PrimaryProductDataSource.Destination.State.DISABLED)
                        .build())
                .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();
        }
      }

      public static void main(String[] args) throws Exception {
        Config config = Config.load();
        // The displayed datasource name in the Merchant Center UI.
        String displayName = "British Primary Product Data";

        createDataSource(config, displayName);
      }
    }

### PHP

    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;
    use Google\Shopping\Type\Destination\DestinationEnum;

    /**
     * This class demonstrates how to create a primary product datasource for the "en" and "GB"
     * `feedLabel` and `contentLanguage` combination.
     */
    class CreatePrimaryProductDataSourceSample
    {
        /**
         * A helper function to create the parent string for DataSource resources.
         *
         * @param string $accountId The Merchant Center account ID.
         * @return string The parent resource name in the format `accounts/{account_id}`.
         */
        private static function getParent(string $accountId): string
        {
            return sprintf("accounts/%s", $accountId);
        }

        /**
         * Creates a new primary product data source.
         *
         * @param array $config The configuration array containing the account ID.
         * @param string $displayName The display name for the new data source.
         * @return void
         */
        public static function createDataSourceSample(array $config, string $displayName): 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 DataSourcesServiceClient.
            $dataSourcesServiceClient = new DataSourcesServiceClient($options);

            // Constructs the parent resource name from the account ID.
            $parent = self::getParent($config['accountId']);

            // Defines the primary product data source specific settings.
            $primaryProductDataSource = new PrimaryProductDataSource([
                'countries' => ['GB'],
                'content_language' => 'en',
                'feed_label' => 'GB',
                // The destinations do not necessarily have to be explicitly listed in which case the
                // default enabled destinations will be used.
                'destinations' => [
                    new PrimaryProductDataSource\Destination([
                        'destination' => DestinationEnum::FREE_LISTINGS,
                        'state' => PrimaryProductDataSource\Destination\State::ENABLED
                    ]),
                    new PrimaryProductDataSource\Destination([
                        'destination' => DestinationEnum::SHOPPING_ADS,
                        'state' => PrimaryProductDataSource\Destination\State::DISABLED
                    ])
                ]
            ]);

            // Creates the DataSource object.
            $dataSource = new DataSource([
                'display_name' => $displayName,
                'primary_product_data_source' => $primaryProductDataSource
            ]);

            // Prepares the request message to create the data source.
            $request = new CreateDataSourceRequest([
                'parent' => $parent,
                'data_source' => $dataSource
            ]);

            // Calls the API and catches and prints any network failures/errors.
            try {
                print "Sending Create PrimaryProduct DataSource request\n";
                // Issues the create data source request.
                $response = $dataSourcesServiceClient->createDataSource($request);
                print("Created DataSource below\n");
                print($response->serializeToJsonString() . PHP_EOL);
            } catch (ApiException $e) {
                printf("ApiException was thrown: %s\n", $e->getMessage());
            }
        }

        /**
         * Helper to execute the sample.
         *
         * @return void
         */
        public function callSample(): void
        {
            $config = Config::generateConfig();
            // The displayed datasource name in the Merchant Center UI.
            $displayName = "British Primary Product Data";

            self::createDataSourceSample($config, $displayName);
        }
    }

    // Run the script.
    $sample = new CreatePrimaryProductDataSourceSample();
    $sample->callSample();

### Python

    """Sample for creating a primary product data source."""
    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
    # Used for setting the destination type, e.g., FREE_LISTINGS.
    from google.shopping.type import types as merchant_api_types


    def create_primary_product_data_source(
        account_id: str, display_name: str
    ) -> str:
      """Creates a primary product data source for the 'en' language and 'GB' region, targeting specific destinations.

      Args:
          account_id: The Merchant Center account ID.
          display_name: The user-visible name for the new data source in Merchant
            Center.

      Returns:
          The resource name of the newly created data source.
      """

      # Obtains OAuth 2.0 credentials for API authentication.
      credentials = generate_user_credentials.main()

      # Initializes the DataSourcesServiceClient with the obtained credentials.
      client = DataSourcesServiceClient(credentials=credentials)

      # Configures the PrimaryProductDataSource.
      # This section defines the core properties of the product data feed.
      primary_product_data_source = PrimaryProductDataSource()

      # Sets the target countries for this data source.
      primary_product_data_source.countries = ["GB"]
      # Sets the content language for the products.
      primary_product_data_source.content_language = "en"
      # Sets the feed label, often matching the country or language.
      primary_product_data_source.feed_label = "GB"

      # Defines the destinations for this data source and their states.
      # If destinations are not explicitly listed, defaults will be used.

      # Configure Free Listings destination (enabled).
      destination_free_listings = PrimaryProductDataSource.Destination()
      destination_free_listings.destination = (
          merchant_api_types.Destination.DestinationEnum.FREE_LISTINGS
      )
      destination_free_listings.state = (
          PrimaryProductDataSource.Destination.State.ENABLED
      )

      # Configure Shopping Ads destination (disabled).
      destination_shopping_ads = PrimaryProductDataSource.Destination()
      destination_shopping_ads.destination = (
          merchant_api_types.Destination.DestinationEnum.SHOPPING_ADS
      )
      destination_shopping_ads.state = (
          PrimaryProductDataSource.Destination.State.DISABLED
      )

      primary_product_data_source.destinations = [
          destination_free_listings,
          destination_shopping_ads,
      ]

      # Assembles the DataSource object.
      data_source = DataSource()
      data_source.display_name = display_name
      data_source.primary_product_data_source = primary_product_data_source

      # Constructs the parent resource name format for Data Source operations.
      parent = f"accounts/{account_id}"

      # Prepares the CreateDataSourceRequest.
      # This request includes the parent account and the data source configuration.
      request = CreateDataSourceRequest(parent=parent, data_source=data_source)

      try:
        # Executes the API call to create the data source.
        print("Sending Create PrimaryProduct DataSource request")
        response = client.create_data_source(request=request)
        # Confirms creation and prints the new data source's name.
        print("Created DataSource Name below")
        print(response)
        return response.name
      except RuntimeError as e:
        # Handles any errors encountered during the API request.
        print(e)
        raise


    if __name__ == "__main__":
      # Fetches the Merchant Center account ID from the configuration file.
      # This ID is essential for constructing the 'parent' resource path
      # required by the API.
      merchant_account_id = configuration.Configuration().read_merchant_info()
      # Sets the desired display name for the data source in Merchant Center.
      datasource_display_name = "British Primary Product Data"

      # Calls the function to create the data source.
      create_primary_product_data_source(
          merchant_account_id, datasource_display_name
      )

### cURL

    curl -X POST \
    "https://merchantapi.googleapis.com/datasources/v1/accounts/{ACCOUNT_ID}/dataSources" \
    -H "Authorization: Bearer {API_TOKEN}" \
    -H "Content-Type: application/json" \
    -d '{
          "displayName": "British Primary Product Data",
          "primaryProductDataSource": {
            "countries": ["GB"],
            "contentLanguage": "en",
            "feedLabel": "GB",
            "destinations": [
              {
                "destination": "FREE_LISTINGS",
                "state": "ENABLED"
              },
              {
                "destination": "SHOPPING_ADS",
                "state": "DISABLED"
              }
            ]
          }
        }'

> [!NOTE]
> **Note:** The `destinations` field in the data source sets the default for all products uploaded through this data source. You can override this default setting for individual products by using the `includedDestinations` and `excludedDestinations` attributes in the [products](https://developers.google.com/merchant/api/reference/rest/products_v1/accounts.products) resource.

## Create a supplemental API data source and link it to a primary data source

Supplemental data sources enable you to provide additional product data that
complements your primary data sources.

### Step 1: Create the supplemental API data source

Create a supplemental data source using
[`dataSources.create`](https://developers.google.com/merchant/api/reference/rest/datasources_v1/accounts.dataSources/create).
If you want your supplemental data source to be applicable to any primary data
source, you can omit `feedLabel` and `contentLanguage`. To target primary data
sources with matching configurations, specify `feedLabel` and `contentLanguage`.

#### Supplemental data source recommendations

- **Support for any label and language**: You can create supplemental data sources to support any label and language or targeted to specific ones.
- **Linking flexibility** : A primary data source can be linked with supplemental data sources, regardless if the primary data source targets a specific label and language or not. Note that supplemental data sources don't target any label or language. Matching occurs during processing based on the product's specific `feedLabel` and `contentLanguage`.
- **Store data source names for future use**: After creating your supplemental data sources, store their names in your local database to refer to them directly in future API calls.

    POST https://merchantapi.googleapis.com/datasources/v1/accounts/{ACCOUNT_ID}/dataSources

    {
      "displayName": "My API Supplemental Source",
      "supplementalProductDataSource": {}
    }

This returns the newly-created supplemental `DataSource` resource. Note its
`name` (which includes the `dataSourceId`).

    {
      "name": "accounts/{ACCOUNT_ID}/dataSources/{SUPPLEMENTAL_DATASOURCE_ID}",
      "dataSourceId": "{SUPPLEMENTAL_DATASOURCE_ID}",
      "displayName": "My API Supplemental Source",
      "supplementalProductDataSource": {},
      "input": "API"
    }

The following code samples show how to create a supplemental product data source
without setting the `feedLabel` and `contentLanguage` fields.

### Java

    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.SupplementalProductDataSource;
    import shopping.merchant.samples.utils.Authenticator;
    import shopping.merchant.samples.utils.Config;

    /**
     * This class demonstrates how to create a Supplemental product datasource all `feedLabel` and
     * `contentLanguage` combinations. This works only for API supplemental feeds.
     */
    public class CreateSupplementalProductDataSourceMultipleLanguagesSample {

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

        try (DataSourcesServiceClient dataSourcesServiceClient =
            DataSourcesServiceClient.create(dataSourcesServiceSettings)) {

          CreateDataSourceRequest request =
              CreateDataSourceRequest.newBuilder()
                  .setParent(parent)
                  .setDataSource(
                      DataSource.newBuilder()
                          .setDisplayName(displayName)
                          .setSupplementalProductDataSource(
                              SupplementalProductDataSource.newBuilder().build())
                          .build())
                  .build();

          System.out.println("Sending create SupplementalProduct 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);
          return null; // Necessary to satisfy the compiler as we're not returning a
          // String on failure.
        }
      }

      public static void main(String[] args) throws Exception {
        Config config = Config.load();
        // The displayed data source name in the Merchant Center UI.
        String displayName = "Supplemental API Product Data Multiple Languages";

        createDataSource(config, displayName);
      }
    }

### PHP

    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\SupplementalProductDataSource;

    /**
     * Class to demonstrate creating a Supplemental product datasource for all
     * `feedLabel` and `contentLanguage` combinations. This works only for API
     * supplemental feeds.
     */
    class CreateSupplementalProductDataSourceMultipleLanguagesSample
    {
        /**
         * Creates a DataSource.
         *
         * @param int $merchantId The Merchant Center Account ID.
         * @param string $displayName The display name of the data source.
         * @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);

            // Creates the data source.
            $dataSource = (new DataSource())
                ->setDisplayName($displayName)
                ->setSupplementalProductDataSource(new SupplementalProductDataSource());

            // Creates the request.
            $request = (new CreateDataSourceRequest())
                ->setParent($parent)
                ->setDataSource($dataSource);

            print('Sending create SupplementalProduct DataSource request' . PHP_EOL);

            // Calls the API and catches and prints any network failures/errors.
            try {
                $response = $dataSourcesServiceClient->createDataSource($request);
                print('Created DataSource Name below' . PHP_EOL);
                print($response->getName() . PHP_EOL);
                return $response->getName();
            } catch (ApiException $ex) {
                print('Call failed with message: ' . $ex->getMessage() . PHP_EOL);
                return '';
            }
        }

        // 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 = 'Supplemental API Product Data Multiple Languages';

            self::createDataSource($merchantId, $displayName);
        }
    }


    $sample = new CreateSupplementalProductDataSourceMultipleLanguagesSample();
    $sample->callSample();

### Python

    from examples.authentication import configuration
    from examples.authentication import generate_user_credentials
    from google.shopping import merchant_datasources_v1

    _ACCOUNT = configuration.Configuration().read_merchant_info()
    _PARENT = f"accounts/{_ACCOUNT}"


    def create_supplemental_product_data_source_multiple_languages():
      """Creates a `DataSource` resource."""

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

      # Creates a client.
      client = merchant_datasources_v1.DataSourcesServiceClient(
          credentials=credentials
      )

      # Creates a SupplementalProductDataSource.
      supplemental_datasource = (
          merchant_datasources_v1.SupplementalProductDataSource()
      )

      # Creates a DataSource and populates its attributes.
      data_source = merchant_datasources_v1.DataSource()
      data_source.display_name = (
          "Example Multiple Languages Supplemental DataSource"
      )
      data_source.supplemental_product_data_source = supplemental_datasource

      # Creates the request.
      request = merchant_datasources_v1.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_supplemental_product_data_source_multiple_languages()

### cURL

    curl -X POST \
    "https://merchantapi.googleapis.com/datasources/v1/accounts/{ACCOUNT_ID}/dataSources" \
    -H "Authorization: Bearer {API_TOKEN}" \
    -H "Content-Type: application/json" \
    -d '{
          "displayName": "Supplemental API Product Data Multiple Languages",
          "supplementalProductDataSource": {}
        }'

### Step 2: Link the supplemental data source to a primary data source

Update your primary data source to link to the newly-created supplemental data
source. You can achieve this by modifying the `defaultRule` of the
[`PrimaryProductDataSource`](https://developers.google.com/merchant/api/reference/rest/datasources_v1/accounts.dataSources#PrimaryProductDataSource)
with the
[`dataSources.patch`](https://developers.google.com/merchant/api/reference/rest/datasources_v1/accounts.dataSources/patch)
method.

> [!NOTE]
> **Note:** It is possible to create a `PrimaryProductDataSource` and connect it to an existing `supplementalProductDataSource` in one step by providing `defaultRule` in the `PrimaryProductDataSource` creation request.

The `takeFromDataSources` list in the `defaultRule` specifies the order of
precedence. Attributes are taken from the first data source in the list that
provides them. The `self` shorthand points to the primary data source itself.

> [!WARNING]
> **Warning:** The update (patch) and create call replaces the entire default rule setup. It doesn't work as an addition or append. If `self` is missing from the list of `take_from_data_sources`, the API will ignore attributes from the primary data source itself.

The following examples show the default rule setting which first takes data
from the primary data source and if the attribute is not available there, it
takes the attribute from the supplemental source.

    PATCH https://merchantapi.googleapis.com/datasources/v1/accounts/{ACCOUNT_ID}/dataSources/{PRIMARY_DATASOURCE_ID}?updateMask=primaryProductDataSource.defaultRule

    {
      "name": "accounts/{ACCOUNT_ID}/dataSources/{PRIMARY_DATASOURCE_ID}",
      "primaryProductDataSource": {
        "defaultRule": {
          "takeFromDataSources": [
            {
              "self": true
            },
            {
              "supplementalDataSourceName": "accounts/{ACCOUNT_ID}/dataSources/{SUPPLEMENTAL_DATASOURCE_ID}"
            }
          ]
        }
      }
    }

A successful request returns the updated primary `DataSource` resource.

    {
      "name": "accounts/{ACCOUNT_ID}/dataSources/{PRIMARY_DATASOURCE_ID}",
      "dataSourceId": "{PRIMARY_DATASOURCE_ID}",
      "displayName": "My API Primary Product Source",
      "primaryProductDataSource": {
        "countries": [
          "US",
          "GB",
          "DE"
        ],
        "defaultRule": {
          "takeFromDataSources": [
            {
              "self": true
            },
            {
              "supplementalDataSourceName": "accounts/{ACCOUNT_ID}/dataSources/{SUPPLEMENTAL_DATASOURCE_ID}"
            }
          ]
        }
      },
      "input": "API"
    }

The following code samples show how to connect a supplemental data source to the
primary data source.

### Java

    import shopping.merchant.samples.datasources.v1.UpdateDataSourceSample;
    import shopping.merchant.samples.utils.Config;

    /**
     * This class demonstrates how to add supplemental DataSources to the primary DataSource's default
     * rule.
     */
    public class AddSupplementalDataSourceToPrimaryDataSourceSample {

      public static void addSupplementalDataSourceToPrimaryDataSource(
          Config config,
          String primaryDataSourceName,
          String firstSupplementalDataSourceName,
          String secondSupplementalDataSourceName)
          throws Exception {

        // Update the primary DataSource's default rule to include both supplemental feeds.
        UpdateDataSourceSample updateDatasource = new UpdateDataSourceSample();
        updateDatasource.updateDataSource(
            config,
            primaryDataSourceName,
            firstSupplementalDataSourceName,
            secondSupplementalDataSourceName);
      }

      public static void main(String[] args) throws Exception {
        Config config = Config.load();
        // The names of the primary and supplemental datasources.
        String primaryDataSourceName = "accounts/{account_id}/dataSources/{datasource_id}";
        String firstSupplementalDataSourceName = "accounts/{account_id}/dataSources/{datasource_id}";
        String secondSupplementalDataSourceName = "accounts/{account_id}/dataSources/{datasource_id}";

        addSupplementalDataSourceToPrimaryDataSource(
            config,
            primaryDataSourceName,
            firstSupplementalDataSourceName,
            secondSupplementalDataSourceName);
      }
    }

### cURL

    curl -X PATCH \
    "https://merchantapi.googleapis.com/datasources/v1/accounts/{ACCOUNT_ID}/dataSources/{PRIMARY_DATASOURCE_ID}?updateMask=primaryProductDataSource.defaultRule" \
    -H "Authorization: Bearer {API_TOKEN}" \
    -H "Content-Type: application/json" \
    -d '{
          "name": "accounts/{ACCOUNT_ID}/dataSources/{PRIMARY_DATASOURCE_ID}",
          "primaryProductDataSource": {
            "defaultRule": {
              "takeFromDataSources": [
                {
                  "self": true
                },
                {
                  "supplementalDataSourceName": "accounts/{ACCOUNT_ID}/dataSources/{SUPPLEMENTAL_DATASOURCE_ID_1}"
                },
                {
                  "supplementalDataSourceName": "accounts/{ACCOUNT_ID}/dataSources/{SUPPLEMENTAL_DATASOURCE_ID_2}"
                }
              ]
            }
          }
        }'

## Update a data source

You can update properties of an existing data source, such as its `displayName`.
Use the
[`dataSources.patch`](https://developers.google.com/merchant/api/reference/rest/datasources_v1/accounts.dataSources/patch)
method and specify the fields to update in the `updateMask`.

    PATCH https://merchantapi.googleapis.com/datasources/v1/accounts/{ACCOUNT_ID}/dataSources/{DATASOURCE_ID}?updateMask=displayName

    {
      "name": "accounts/{ACCOUNT_ID}/dataSources/{DATASOURCE_ID}",
      "displayName": "Updated API Primary Source Name"
    }

A successful request returns the updated `DataSource` resource.

    {
      "name": "accounts/{ACCOUNT_ID}/dataSources/{DATASOURCE_ID}",
      "dataSourceId": "{DATASOURCE_ID}",
      "displayName": "Updated API Primary Source Name",
      "primaryProductDataSource": {
        "feedLabel": "US",
        "contentLanguage": "en",
        "countries": ["US"]
      },
      "input": "API"
    }

The following code samples show how to use the `patch` method to update a data
source.

### Java

    import com.google.api.gax.core.FixedCredentialsProvider;
    import com.google.auth.oauth2.GoogleCredentials;
    import com.google.protobuf.FieldMask;
    import com.google.shopping.merchant.datasources.v1.DataSource;
    import com.google.shopping.merchant.datasources.v1.DataSourceName;
    import com.google.shopping.merchant.datasources.v1.DataSourceReference;
    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 com.google.shopping.merchant.datasources.v1.PrimaryProductDataSource.DefaultRule;
    import com.google.shopping.merchant.datasources.v1.UpdateDataSourceRequest;
    import shopping.merchant.samples.utils.Authenticator;
    import shopping.merchant.samples.utils.Config;

    /**
     * This class demonstrates how to update a datasource to change its name in the MC UI. It also
     * demonstrates how to update a primary datasource to add supplemental datasources to its default
     * rule (https://support.google.com/merchants/answer/7450276).
     */
    public class UpdateDataSourceSample {

      public static String updateDataSource(Config config, String displayName, String dataSourceId)
          throws Exception {
        GoogleCredentials credential = new Authenticator().authenticate();

        DataSourcesServiceSettings dataSourcesServiceSettings =
            DataSourcesServiceSettings.newBuilder()
                .setCredentialsProvider(FixedCredentialsProvider.create(credential))
                .build();

        // Creates datasource name to identify datasource.
        String name =
            DataSourceName.newBuilder()
                .setAccount(config.getAccountId().toString())
                .setDatasource(dataSourceId)
                .build()
                .toString();

        DataSource dataSource =
            DataSource.newBuilder()
                // Update the datasource to have the new display name
                .setDisplayName(displayName)
                .setName(name)
                .build();

        FieldMask fieldMask = FieldMask.newBuilder().addPaths("display_name").build();

        try (DataSourcesServiceClient dataSourcesServiceClient =
            DataSourcesServiceClient.create(dataSourcesServiceSettings)) {

          UpdateDataSourceRequest request =
              UpdateDataSourceRequest.newBuilder()
                  .setDataSource(dataSource)
                  .setUpdateMask(fieldMask)
                  .build();

          System.out.println("Sending Update DataSource request");
          DataSource response = dataSourcesServiceClient.updateDataSource(request);
          System.out.println("Updated DataSource Name below");
          System.out.println(response.getName());
          return response.getName();
        } catch (Exception e) {
          System.out.println(e);
          System.exit(1);
          return null;
        }
      }

      public String updateDataSource(
          Config config,
          String primaryDataSourceName,
          String firstSupplementalDataSourceName,
          String secondSupplementalDataSourceName)
          throws Exception {
        GoogleCredentials credential = new Authenticator().authenticate();

        DataSourcesServiceSettings dataSourcesServiceSettings =
            DataSourcesServiceSettings.newBuilder()
                .setCredentialsProvider(FixedCredentialsProvider.create(credential))
                .build();

        // Setting self to 'true' refers to the primary datasource itself.
        DataSourceReference dataSourceReferenceSelf =
            DataSourceReference.newBuilder().setSelf(true).build();
        DataSourceReference firstSupplementalDataSourceReference =
            DataSourceReference.newBuilder()
                .setSupplementalDataSourceName(firstSupplementalDataSourceName)
                .build();
        DataSourceReference secondSupplementalDataSourceReference =
            DataSourceReference.newBuilder()
                .setSupplementalDataSourceName(secondSupplementalDataSourceName)
                .build();

        // The attributes will first be taken from the primary DataSource.
        // Then the first supplemental DataSource if the attribute is not in the primary DataSource
        // And finally the second supplemental DataSource if not in the first two DataSources.
        // Note that CustomRules could change the behavior of how updates are applied.
        DefaultRule defaultRule =
            DefaultRule.newBuilder()
                .addTakeFromDataSources(dataSourceReferenceSelf)
                .addTakeFromDataSources(firstSupplementalDataSourceReference)
                .addTakeFromDataSources(secondSupplementalDataSourceReference)
                .build();

        // The type of data that this datasource will receive.
        PrimaryProductDataSource primaryProductDataSource =
            PrimaryProductDataSource.newBuilder().setDefaultRule(defaultRule).build();

        DataSource dataSource =
            DataSource.newBuilder()
                // Update the primary datasource to have the default rule datasources in the correct
                // order.
                .setPrimaryProductDataSource(primaryProductDataSource)
                .setName(primaryDataSourceName)
                .build();

        // The '.' signifies a nested field.
        FieldMask fieldMask =
            FieldMask.newBuilder().addPaths("primary_product_data_source.default_rule").build();

        try (DataSourcesServiceClient dataSourcesServiceClient =
            DataSourcesServiceClient.create(dataSourcesServiceSettings)) {

          UpdateDataSourceRequest request =
              UpdateDataSourceRequest.newBuilder()
                  .setDataSource(dataSource)
                  .setUpdateMask(fieldMask)
                  .build();

          System.out.println("Sending Update DataSource request");
          DataSource response = dataSourcesServiceClient.updateDataSource(request);
          System.out.println("Updated DataSource Name below");
          System.out.println(response.getName());
          return response.getName();
        } catch (Exception e) {
          System.out.println(e);
          System.exit(1);
          return null;
        }
      }

      public static void main(String[] args) throws Exception {
        Config config = Config.load();
        // The updated displayed datasource name in the Merchant Center UI.
        String displayName = "Great Britain Primary Product Data";

        // The ID of the datasource to update
        String dataSourceId = "11111111"; // Replace with your datasource ID.

        updateDataSource(config, displayName, dataSourceId);
      }
    }

### PHP

    use Google\ApiCore\ApiException;
    use Google\Protobuf\FieldMask;
    use Google\Shopping\Merchant\DataSources\V1\Client\DataSourcesServiceClient;
    use Google\Shopping\Merchant\DataSources\V1\DataSource;
    use Google\Shopping\Merchant\DataSources\V1\UpdateDataSourceRequest;

    /**
     * Class to demonstrate updating a datasource to change its name in the MC UI.
     */
    class UpdateDataSourceSample
    {
        // ENSURE you fill in the datasource ID for the sample to work.
        private const DATASOURCE_ID = 'INSERT_DATASOURCE_ID';

        /**
         * Updates a DataSource.
         *
         * @param int $merchantId The Merchant Center Account ID.
         * @param string $displayName The new display name of the data source.
         * @param string $dataSourceId The data source ID.
         * @return string The name of the updated data source.
         */
        public function updateDataSource(int $merchantId, string $displayName, string $dataSourceId): 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);

            // Creates the data source name.
            $name = sprintf('accounts/%s/dataSources/%s', $merchantId, $dataSourceId);

            // Creates the data source.
            $dataSource = (new DataSource())
                ->setDisplayName($displayName)
                ->setName($name);

            // Creates a FieldMask to specify which fields to update.
            $updateMask = new FieldMask([
                'paths' => ['display_name']
            ]);

            // Creates the request.
            $request = (new UpdateDataSourceRequest())
                ->setDataSource($dataSource)
                ->setUpdateMask($updateMask);

            print('Sending Update DataSource request' . PHP_EOL);

            // Calls the API and catches and prints any network failures/errors.
            try {
                $response = $dataSourcesServiceClient->updateDataSource($request);
                print('Updated DataSource Name below' . PHP_EOL);
                print($response->getName() . PHP_EOL);
                return $response->getName();
            } catch (ApiException $ex) {
                print('Call failed with message: ' . $ex->getMessage() . PHP_EOL);
                return '';
            }
        }

        // Helper to execute the sample.
        public function callSample(): void
        {
            $config = Config::generateConfig();
            // The Merchant Center Account ID.
            $merchantId = $config['accountId'];

            // The updated displayed datasource name in the Merchant Center UI.
            $displayName = 'new name';

            self::updateDataSource($merchantId, $displayName, self::DATASOURCE_ID);
        }
    }

    $sample = new UpdateDataSourceSample();
    $sample->callSample();

### Python

    from examples.authentication import configuration
    from examples.authentication import generate_user_credentials
    from google.protobuf import field_mask_pb2
    from google.shopping import merchant_datasources_v1

    # ENSURE you fill in the datasource ID for the sample to
    # work.
    _ACCOUNT = configuration.Configuration().read_merchant_info()
    # An ID automatically assigned to the datasource after creation by Google.
    _DATASOURCE = "[INSERT_DATASOURCE_HERE]"
    _NAME = f"accounts/{_ACCOUNT}/dataSources/{_DATASOURCE}"


    def update_data_source():
      """Updates the specified `DataSource` resource."""

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

      # Creates a client.
      client = merchant_datasources_v1.DataSourcesServiceClient(
          credentials=credentials
      )

      # Creates a DataSource and populates its attributes.
      data_source = merchant_datasources_v1.DataSource()
      data_source.name = _NAME  # To identify the data source to update.
      data_source.display_name = "Example DataSource 2"

      # Sets field mask to include only the fields you want to update.
      field_mask = field_mask_pb2.FieldMask(paths=["display_name"])

      # Creates the request.
      request = merchant_datasources_v1.UpdateDataSourceRequest(
          data_source=data_source, update_mask=field_mask
      )

      # Makes the request and catch and print any error messages.
      try:
        client.update_data_source(request=request)
        print("Update successful")
      except RuntimeError as e:
        print("Update failed")
        print(e)


    if __name__ == "__main__":
      update_data_source()

### cURL

    curl -X PATCH \
    "https://merchantapi.googleapis.com/datasources/v1/accounts/{ACCOUNT_ID}/dataSources/{DATASOURCE_ID}?updateMask=displayName" \
    -H "Authorization: Bearer {API_TOKEN}" \
    -H "Content-Type: application/json" \
    -d '{
          "name": "accounts/{ACCOUNT_ID}/dataSources/{DATASOURCE_ID}",
          "displayName": "Updated API Primary Source Name"
        }'

## Delete a data source

To remove a data source from your Merchant Center account, use the
[`dataSources.delete`](https://developers.google.com/merchant/api/reference/rest/datasources_v1/accounts.dataSources/delete)
method. If a supplemental data source is linked to any primary data source, you
won't be able to delete it until you remove all links to it.

> [!NOTE]
> **Note:** After creating a data source, there might be a few seconds delay before you can delete it.

    DELETE https://merchantapi.googleapis.com/datasources/v1/accounts/{ACCOUNT_ID}/dataSources/{DATASOURCE_ID}

A successful deletion returns an empty response.

The following code samples show how to use the `delete` method to delete a data
source.

### Java

    import com.google.api.gax.core.FixedCredentialsProvider;
    import com.google.auth.oauth2.GoogleCredentials;
    import com.google.shopping.merchant.datasources.v1.DataSourceName;
    import com.google.shopping.merchant.datasources.v1.DataSourcesServiceClient;
    import com.google.shopping.merchant.datasources.v1.DataSourcesServiceSettings;
    import com.google.shopping.merchant.datasources.v1.DeleteDataSourceRequest;
    import shopping.merchant.samples.utils.Authenticator;
    import shopping.merchant.samples.utils.Config;

    /** This class demonstrates how to delete a datasource. */
    public class DeleteDataSourceSample {

      public static void deleteDataSource(Config config, String dataSourceId) throws Exception {
        GoogleCredentials credential = new Authenticator().authenticate();

        DataSourcesServiceSettings dataSourcesServiceSettings =
            DataSourcesServiceSettings.newBuilder()
                .setCredentialsProvider(FixedCredentialsProvider.create(credential))
                .build();

        String name =
            DataSourceName.newBuilder()
                .setAccount(config.getAccountId().toString())
                .setDatasource(dataSourceId)
                .build()
                .toString();

        try (DataSourcesServiceClient dataSourcesServiceClient =
            DataSourcesServiceClient.create(dataSourcesServiceSettings)) {
          DeleteDataSourceRequest request = DeleteDataSourceRequest.newBuilder().setName(name).build();

          System.out.println("Sending deleteDataSource request");
          // Delete works for any datasource type.
          // If Type "Supplemental", delete will only work if it's not linked to any primary feed.
          // If a link exists and the Type is "Supplemental", you will need to remove the supplemental
          // feed from the default and/or custom rule(s) of any primary feed(s) that references it. Then
          // retry the delete.

          dataSourcesServiceClient.deleteDataSource(request); // No response returned on success.
          System.out.println(
              "Delete successful, note that it may take a few minutes for the delete to update in"
                  + " the system.");
        }
      }

      public static void main(String[] args) throws Exception {
        Config config = Config.load();
        // An ID automatically assigned to the datasource after creation by Google.
        String dataSourceId = "1111111111"; // Replace with your datasource ID.

        deleteDataSource(config, dataSourceId);
      }
    }

### PHP

    use Google\ApiCore\ApiException;
    use Google\Shopping\Merchant\DataSources\V1\Client\DataSourcesServiceClient;
    use Google\Shopping\Merchant\DataSources\V1\DeleteDataSourceRequest;

    /**
     * Class to demonstrate deleting a datasource.
     */
    class DeleteDataSourceSample
    {
        // ENSURE you fill in the datasource ID for the sample to work.
        private const DATASOURCE_ID = 'INSERT_DATASOURCE_ID';

        /**
         * Deletes a DataSource.
         *
         * @param int $merchantId The Merchant Center Account ID.
         * @param string $dataSourceId The data source ID.
         */
        public function deleteDataSource(int $merchantId, string $dataSourceId): 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.
            $dataSourcesServiceClient = new DataSourcesServiceClient($options);

            // Creates the data source name.
            $name = sprintf('accounts/%s/dataSources/%s', $merchantId, $dataSourceId);

            // Creates the request.
            $request = (new DeleteDataSourceRequest())
                ->setName($name);

            print('Sending deleteDataSource request' . PHP_EOL);

            // Calls the API and catches and prints any network failures/errors.
            try {
                $dataSourcesServiceClient->deleteDataSource($request);
                print('Delete successful, note that it may take a few minutes for the delete to update in the system.' . PHP_EOL);
            } catch (ApiException $ex) {
                print('Call failed with message: ' . $ex->getMessage() . PHP_EOL);
            }
        }

        // Helper to execute the sample.
        public function callSample(): void
        {
            $config = Config::generateConfig();
            // The Merchant Center Account ID.
            $merchantId = $config['accountId'];

            self::deleteDataSource($merchantId, self::DATASOURCE_ID);
        }
    }

    $sample = new DeleteDataSourceSample();
    $sample->callSample();

### Python

    from examples.authentication import configuration
    from examples.authentication import generate_user_credentials
    from google.shopping import merchant_datasources_v1


    def delete_data_source(account_id: str, datasource_id: str):
      """Deletes the specified `DataSource` resource.

      Delete works for any datasource type.
      If Type "Supplemental", delete will only work if it's not linked to any
      primary feed. If a link exists and the Type is "Supplemental", you will need
      to remove the supplemental feed from the default and/or custom rule(s) of any
      primary feed(s) that references it. Then retry the delete.

      Args:
        account_id: The Merchant Center account ID.
        datasource_id: The ID of the data source to delete.
      """

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

      # Creates a client.
      client = merchant_datasources_v1.DataSourcesServiceClient(
          credentials=credentials
      )

      name = f"accounts/{account_id}/dataSources/{datasource_id}"

      # Creates the request.
      request = merchant_datasources_v1.DeleteDataSourceRequest(name=name)

      # Makes the request and catches and prints any error messages.
      try:
        # No response is returned on request.
        client.delete_data_source(request=request)
        print("Deletion successful")
      except RuntimeError as e:
        print("Deletion failed")
        print(e)
        raise


    if __name__ == "__main__":
      # Retrieves the Merchant Center account ID from the configuration file.
      merchant_account_id = configuration.Configuration().read_merchant_info()
      # ENSURE you fill in the datasource ID for the sample to
      # work.
      # An ID automatically assigned to the datasource after creation by Google.
      target_datasource = "[INSERT_DATASOURCE_HERE]"

      delete_data_source(merchant_account_id, target_datasource)

### cURL

    curl -X DELETE \
    "https://merchantapi.googleapis.com/datasources/v1/accounts/{ACCOUNT_ID}/dataSources/{DATASOURCE_ID}" \
    -H "Authorization: Bearer {API_TOKEN}" \