This guide explains how to migrate your integration from the `datafeeds` and
`datafeedstatuses` services of the Content API for Shopping to the
Data Sources sub-API in Merchant API. The new Data Sources sub-API
provides more direct control over your data pipelines and simplifies data
sources management.

For more information on the new features, see the
[Manage your data sources](https://developers.google.com/merchant/api/guides/data-sources/overview) guide.

## Key differences

Compared to Content API for Shopping, Merchant API offers several advantages:

- **Explicit data source creation.** The API no longer automatically creates a
  "Content API" data source on your first product insertion. In Merchant API
  , you explicitly create data sources before you can upload products to them.
  This gives you more control over the organization and management of your
  product data pipelines from the start.

- **Support for multiple API data sources.** In the Content API for Shopping,
  you were limited to a single, automatically created "Content API" data
  source. With Merchant API you can create and manage multiple data sources
  of the `API` input type.

- **Data sources without label and language.** The Merchant API lets you
  create a primary data source without specifying a `feedLabel` and
  `contentLanguage`. This type of data source accepts products in any
  combination of `feedLabel` and `contentLanguage`, which simplifies product
  uploads for integrations that don't require separate data sources for
  different regions.

- **Simplified data targets.** Each data source now corresponds to a single
  target, defined by a unique combination of `feedLabel` and
  `contentLanguage`. Multi-data target feeds are deprecated in Merchant API.

- **Dedicated file upload status.** Merchant API represents the status of
  file-based data sources using a separate, read-only `fileUploads` resource.
  To retrieve the status of a file upload, use the `fileUploads.get` method
  with the `latest` alias.

- **New data source types.** The `DataSource` resource supports more
  verticals, including promotions, local inventory, and regional inventory,
  providing a unified way to manage all your data pipelines.

- **Automated data sources.** With Merchant API, you can now enable or
  disable the
  [Automated data sources](https://support.google.com/merchants/answer/12158480)
  feature for your account using the `autofeedSettings.updateAutofeedSettings`
  method in the Accounts sub-API. For more information, see
  [Configure Autofeed settings](https://developers.google.com/merchant/api/guides/data-sources/manage-various-data-sources#autofeed-settings).

### Choose your data source strategy

You have three options for managing your data sources:

- **Create a single Merchant API data source for any feed label and
  language.** Use this option to simplify your management by having a
  single data source that accepts products with *any* `feedLabel` and
  `contentLanguage`. In the old Content API setup, you define rules for
  specific labels and languages through separate data sources, and you insert
  products into the data source having the corresponding targeted rules. If
  you choose this option, we recommend migrating all your products to the new
  data source and removing your Content API data sources once all your
  products are migrated.

- **Create new Merchant API data sources for each label and language.**
  Use this option if you need to support new `feedLabel` and
  `contentLanguage` combinations (and prefer to keep strict separation
  between them) or if you use the data source rules setup which relies on
  specific `feedLabel` and `contentLanguage`. You will need to create a
  separate data source for every pair of `feedLabel` and `contentLanguage`
  you use. You can combine Merchant API data sources with the data sources
  created with Content API for Shopping.

> [!IMPORTANT]
> **Important:** When choosing any of the preceding options to create a new data source, you might need to migrate existing rules. Rule migrations can't be executed through the API and you must perform them manually in the Merchant Center UI, which might take some time to complete for advanced accounts where rules are applied directly to many individual sub-accounts.

- **Keep existing Content API data sources.** You can continue to use data sources created with the Content API for Shopping, as they are compatible with the Merchant API. You can find their resource names using [`dataSources.list`](https://developers.google.com/merchant/api/reference/rest/datasources_v1/accounts.dataSources/list) or within Merchant Center UI. Content API primary data sources only support the specific `feedLabel` and `contentLanguage` they were created with. Content API data sources are shown in Merchant Center with "Content API" source even if products are inserted using Merchant API. You can combine them with new Merchant API data sources that also target specific `feedLabel` and `contentLanguage` pairs.

We recommend backfilling your local products database, by storing the names of
all the primary data sources once for each of your products to avoid repeated
[`dataSources.list`](https://developers.google.com/merchant/api/reference/rest/datasources_v1/accounts.dataSources/list)
calls.

> [!WARNING]
> **Warning:** If you use data source rules, to prevent accidental ["offer stealing"](https://developers.google.com/merchant/api/guides/compatibility/products#data-source-guidelines-during-migration) (moving a product to the wrong data source), we recommend using [`products.get`](https://developers.google.com/merchant/api/reference/rest/products_v1/accounts.products/get) to identify the specific data source associated with a product before performing write operations.

## Requests

The following table compares the request URL formats between the Content API for
Shopping and the Merchant API.

| Request description | Content API for Shopping | Merchant API |
|---|---|---|
| Create a data source | `POST https://shoppingcontent.googleapis.com/content/v2.1/{MERCHANT_ID}/datafeeds` | `POST https://merchantapi.googleapis.com/v1/accounts/{ACCOUNT_ID}/dataSources` |
| Get a data source | `GET https://shoppingcontent.googleapis.com/content/v2.1/{MERCHANT_ID}/datafeeds/{DATAFEED_ID}` | `GET https://merchantapi.googleapis.com/v1/accounts/{ACCOUNT_ID}/dataSources/{DATASOURCE_ID}` |
| List data sources | `GET https://shoppingcontent.googleapis.com/content/v2.1/{MERCHANT_ID}/datafeeds` | `GET https://merchantapi.googleapis.com/v1/accounts/{ACCOUNT_ID}/dataSources` |
| Update a data source | `PUT https://shoppingcontent.googleapis.com/content/v2.1/{MERCHANT_ID}/datafeeds/{DATAFEED_ID}` | `PATCH https://merchantapi.googleapis.com/v1/accounts/{ACCOUNT_ID}/dataSources/{DATASOURCE_ID}` |
| Delete a data source | `DELETE https://shoppingcontent.googleapis.com/content/v2.1/{MERCHANT_ID}/datafeeds/{DATAFEED_ID}` | `DELETE https://merchantapi.googleapis.com/v1/accounts/{ACCOUNT_ID}/dataSources/{DATASOURCE_ID}` |
| Fetch a data source | `POST https://shoppingcontent.googleapis.com/content/v2.1/{MERCHANT_ID}/datafeeds/{DATAFEED_ID}/fetchNow` | `POST https://merchantapi.googleapis.com/v1/accounts/{ACCOUNT_ID}/dataSources/{DATASOURCE_ID}:fetch` |
| Get data source status | `GET https://shoppingcontent.googleapis.com/content/v2.1/{MERCHANT_ID}/datafeedstatuses/{DATAFEED_ID}` | `GET https://merchantapi.googleapis.com/v1/accounts/{ACCOUNT_ID}/dataSources/{DATASOURCE_ID}/fileUploads/latest` |
| List data source statuses | `GET https://shoppingcontent.googleapis.com/content/v2.1/{MERCHANT_ID}/datafeedstatuses` | Not available. Use `dataSources.list` and `fileUploads.get` for each file-based data source. |

## Identifiers

The Merchant API uses a string-based resource name as the identifier.

| Identifier description | Content API for Shopping | Merchant API |
|---|---|---|
| Data source identifier | `datafeedId` (numeric) | `name` (string, format: `accounts/{account}/dataSources/{datasource}`) |

## Methods

This table compares the methods from the Content API for Shopping `datafeeds`
and `datafeedstatuses` services to their equivalents in the Merchant API.

| Content API for Shopping method | Merchant API method | Availability and notes |
|---|---|---|
| `datafeeds.custombatch` | Not available | Use individual API calls instead. |
| `datafeeds.delete` | `dataSources.delete` | Available. |
| `datafeeds.fetchnow` | `dataSources.fetch` | Available. This method now only works for data sources with a file input. |
| `datafeeds.get` | `dataSources.get` | Available. |
| `datafeeds.insert` | `dataSources.create` | Available. |
| `datafeeds.list` | `dataSources.list` | Available. |
| `datafeeds.update` | `dataSources.update` | Available. Uses `PATCH` semantics instead of `PUT`. |
| `datafeedstatuses.custombatch` | Not available | Use individual API calls instead. See [Send multiple requests at once](https://developers.google.com/merchant/api/guides/send-multiple-requests) for more details. |
| `datafeedstatuses.get` | `fileUploads.get` | Available for file-based data sources. Use the `latest` alias to get the status of the most recent upload. For other data source types, status information is part of the `DataSource` resource. |
| `datafeedstatuses.list` | Not available | To get the status of multiple data sources, first list all data sources with `dataSources.list`. Then call `fileUploads.get` with the `latest` alias for each file-based data source. |

## Detailed field changes

This table shows the field-level changes between the `Datafeed` and
`DatafeedStatus` resources in the Content API for Shopping and the `DataSource`
and `FileUpload` resources in the Merchant API.

| Content API for Shopping | Merchant API | Description |
|---|---|---|
| `Datafeed` | `DataSource` | The main resource for data source configuration. |
| `id` | `name` | The resource identifier. Changed from a numeric ID to a string resource name. |
| `name` | `displayName` | The user-facing name of the data source. |
| `attributeLanguage` | `primaryProductDataSource.contentLanguage` | The two-letter ISO 639-1 language code of the items in the data source. |
| `fileName` | `fileInput.fileName` | The name of the uploaded file. This field is now nested under `fileInput`. |
| `fetchSchedule` | `fileInput.fetchSettings` | The schedule for fetching a file-based data source. This is now nested under `fileInput`. |
| `fetchSchedule.paused` | `fileInput.fetchSettings.enabled` | The logic is inverted. `paused: true` is equivalent to `enabled: false`. |
| `format` | Not available | The `fileEncoding`, `columnDelimiter`, and `quotingMode` fields are removed. These are now auto-detected. |
| `targets` | `primaryProductDataSource.feedLabel`, `primaryProductDataSource.contentLanguage`, `primaryProductDataSource.countries` | The repeated `targets` field is removed. Each data source now has a single target defined by these fields, reflecting the deprecation of multi-data-target feeds. |
| `DatafeedStatus` | `FileUpload` | The status of a file upload is now a separate, read-only resource. |
| `datafeedId` | `name` | The identifier for the file upload, referencing its parent data source. |
| `processingStatus` | `processingState` | The processing status of the upload. The string values (`success`, `failure`, `in progress`) are replaced by an enum (`SUCCEEDED`, `FAILED`, `IN_PROGRESS`). |
| `errors`, `warnings` | `issues` | Errors and warnings are merged into a single `issues` list. Each issue has a `severity` field (`ERROR` or `WARNING`). |
| `lastUploadDate` | `uploadTime` | The timestamp of the last upload. The format changed from a string to a `Timestamp` object. |
| `country`, `language`, `feedLabel` | Not applicable | These fields are no longer on the status resource. They are part of the `DataSource` resource. |
| `targets[].included_destinations`, `targets[].excluded_destinations` | `primaryProductDataSource.destinations` | The two separate lists for included and excluded destinations are replaced by a single `destinations` list. Each item in the new list is an object that specifies the destination and its state (`ENABLED` or `DISABLED`), providing a more explicit configuration. |