> This page is for Developers.

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://zuora.ferndocs.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://zuora.ferndocs.com/_mcp/server.

# Compare and deploy the product catalog of a tenant to a target tenant

POST https://rest.test.zuora.com/deployment-manager/deployments/tenant/product_catalog
Content-Type: multipart/form-data

Compare and deploy the product catalog of a tenant to a target tenant.


Reference: https://zuora.ferndocs.com/developers/api-reference/zuora-api/deployment-manager/metadata-deployment/compare-deploy-tenant-product-catalog

## Authentication

- `Authorization` header (bearer token, required) — Use `Bearer {{token}}` in the `Authorization` header for authentication.

## Servers

- `https://rest.test.zuora.com` (US Developer & Central Sandbox (incl. Test Drive), default)
- `https://rest.sandbox.na.zuora.com` (US API Sandbox Cloud 1)
- `https://rest.apisandbox.zuora.com` (US API Sandbox Cloud 2)
- `https://rest.na.zuora.com` (US Production Cloud 1)
- `https://rest.zuora.com` (US Production Cloud 2)
- `https://rest.test.eu.zuora.com` (EU Developer & Central Sandbox)
- `https://rest.sandbox.eu.zuora.com` (EU API Sandbox)
- `https://rest.eu.zuora.com` (EU Production)
- `https://rest.test.ap.zuora.com` (APAC Developer & Central Sandbox)
- `https://rest.ap.zuora.com` (APAC Production)

## Request

### Headers

- `Zuora-Entity-Ids` (string, optional) — An entity ID. If you have [Zuora Multi-entity](https://knowledgecenter.zuora.com/BB_Introducing_Z_Business/Multi-entity) enabled and the OAuth token is valid for more than one entity, you must use this header to specify which entity to perform the operation in. If the OAuth token is only valid for a single entity, or you do not have Zuora Multi-entity enabled, you do not need to set this header.

### Body (multipart/form-data)

This endpoint expects a multipart form.

- `name` (string, required) — Deployment's name.
- `description` (string, required) — Deployment's description.
- `sendEmail` (boolean, required) — Specifies if an email should be sent.
- `emails` (string, optional) — If sendEmail parameter is set to true, comma separated values of emails can be specified. Example email1@test.com,email2@test.com.
- `comments` (string, optional) — Content of the email to be sent.
- `inActiveProducts` (boolean, required) — Specifies if inactive products needs to be migrated.
- `activeProducts` (boolean, required) — Specifies if active products needs to be migrated.
- `activeRatePlans` (boolean, required) — Specifies if active rate plans needs to be migrated.
- `inActiveRatePlans` (boolean, required) — Specifies if inactive active rate plans needs to be migrated.
- `compareField` (enum, required) — Specifies the compare field to be using during migration.
- `sourceTenantId` (string, required) — Specifies the source tenant id.

## Response

### 200

OK

- `id` (string, optional) — ID of the Deployment Manager migration process
- `status` (enum, optional) — Status of the Deployment Manager migration process
  - Allowed values: `DEPLOYING`, `REVERTING`, `PARTIALLY-REVERTED`, `FAILED`, `ROLLBACK-FAILED`, `REVERTED`, `COMPARING`, `SUBMITTED`, `SKIPPED`, `IDENTICAL`, `COMPARE-DONE`, `COMPARE-FAILED`, `CANCELLED`

## Examples

**Request**

```json
{
  "activeProducts": true,
  "activeRatePlans": true,
  "compareField": "name",
  "description": "Product Catalog tenant - 01",
  "inActiveProducts": false,
  "inActiveRatePlans": true,
  "name": "Tenant01PC",
  "sendEmail": true,
  "sourceTenantId": "83e7e56d-0e02-4b4d-91f6-cc77f322c40b"
}
```

**Response**

```json
{
  "id": "8039d54b-da6f-4d80-88d5-06220c42861f",
  "status": "DEPLOYING"
}
```

**SDK Code**

```python Metadata Deployment_CompareDeployTenantProductCatalog_example
import requests

url = "https://rest.test.zuora.com/deployment-manager/deployments/tenant/product_catalog"

payload = "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"activeProducts\"\r\n\r\ntrue\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"activeRatePlans\"\r\n\r\ntrue\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"comments\"\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"compareField\"\r\n\r\nname\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"description\"\r\n\r\nProduct Catalog tenant - 01\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"emails\"\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"inActiveProducts\"\r\n\r\nfalse\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"inActiveRatePlans\"\r\n\r\ntrue\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"name\"\r\n\r\nTenant01PC\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"sendEmail\"\r\n\r\ntrue\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"sourceTenantId\"\r\n\r\n83e7e56d-0e02-4b4d-91f6-cc77f322c40b\r\n-----011000010111000001101001--\r\n"
headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "multipart/form-data; boundary=---011000010111000001101001"
}

response = requests.post(url, data=payload, headers=headers)

print(response.json())
```

```javascript Metadata Deployment_CompareDeployTenantProductCatalog_example
const url = 'https://rest.test.zuora.com/deployment-manager/deployments/tenant/product_catalog';
const form = new FormData();
form.append('activeProducts', 'true');
form.append('activeRatePlans', 'true');
form.append('comments', '');
form.append('compareField', 'name');
form.append('description', 'Product Catalog tenant - 01');
form.append('emails', '');
form.append('inActiveProducts', 'false');
form.append('inActiveRatePlans', 'true');
form.append('name', 'Tenant01PC');
form.append('sendEmail', 'true');
form.append('sourceTenantId', '83e7e56d-0e02-4b4d-91f6-cc77f322c40b');

const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};

options.body = form;

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go Metadata Deployment_CompareDeployTenantProductCatalog_example
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://rest.test.zuora.com/deployment-manager/deployments/tenant/product_catalog"

	payload := strings.NewReader("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"activeProducts\"\r\n\r\ntrue\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"activeRatePlans\"\r\n\r\ntrue\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"comments\"\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"compareField\"\r\n\r\nname\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"description\"\r\n\r\nProduct Catalog tenant - 01\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"emails\"\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"inActiveProducts\"\r\n\r\nfalse\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"inActiveRatePlans\"\r\n\r\ntrue\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"name\"\r\n\r\nTenant01PC\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"sendEmail\"\r\n\r\ntrue\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"sourceTenantId\"\r\n\r\n83e7e56d-0e02-4b4d-91f6-cc77f322c40b\r\n-----011000010111000001101001--\r\n")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("Authorization", "Bearer <token>")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby Metadata Deployment_CompareDeployTenantProductCatalog_example
require 'uri'
require 'net/http'

url = URI("https://rest.test.zuora.com/deployment-manager/deployments/tenant/product_catalog")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request.body = "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"activeProducts\"\r\n\r\ntrue\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"activeRatePlans\"\r\n\r\ntrue\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"comments\"\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"compareField\"\r\n\r\nname\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"description\"\r\n\r\nProduct Catalog tenant - 01\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"emails\"\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"inActiveProducts\"\r\n\r\nfalse\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"inActiveRatePlans\"\r\n\r\ntrue\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"name\"\r\n\r\nTenant01PC\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"sendEmail\"\r\n\r\ntrue\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"sourceTenantId\"\r\n\r\n83e7e56d-0e02-4b4d-91f6-cc77f322c40b\r\n-----011000010111000001101001--\r\n"

response = http.request(request)
puts response.read_body
```

```java Metadata Deployment_CompareDeployTenantProductCatalog_example
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://rest.test.zuora.com/deployment-manager/deployments/tenant/product_catalog")
  .header("Authorization", "Bearer <token>")
  .body("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"activeProducts\"\r\n\r\ntrue\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"activeRatePlans\"\r\n\r\ntrue\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"comments\"\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"compareField\"\r\n\r\nname\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"description\"\r\n\r\nProduct Catalog tenant - 01\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"emails\"\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"inActiveProducts\"\r\n\r\nfalse\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"inActiveRatePlans\"\r\n\r\ntrue\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"name\"\r\n\r\nTenant01PC\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"sendEmail\"\r\n\r\ntrue\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"sourceTenantId\"\r\n\r\n83e7e56d-0e02-4b4d-91f6-cc77f322c40b\r\n-----011000010111000001101001--\r\n")
  .asString();
```

```php Metadata Deployment_CompareDeployTenantProductCatalog_example
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://rest.test.zuora.com/deployment-manager/deployments/tenant/product_catalog', [
  'multipart' => [
    [
        'name' => 'activeProducts',
        'contents' => 'true'
    ],
    [
        'name' => 'activeRatePlans',
        'contents' => 'true'
    ],
    [
        'name' => 'compareField',
        'contents' => 'name'
    ],
    [
        'name' => 'description',
        'contents' => 'Product Catalog tenant - 01'
    ],
    [
        'name' => 'inActiveProducts',
        'contents' => 'false'
    ],
    [
        'name' => 'inActiveRatePlans',
        'contents' => 'true'
    ],
    [
        'name' => 'name',
        'contents' => 'Tenant01PC'
    ],
    [
        'name' => 'sendEmail',
        'contents' => 'true'
    ],
    [
        'name' => 'sourceTenantId',
        'contents' => '83e7e56d-0e02-4b4d-91f6-cc77f322c40b'
    ]
  ]
  'headers' => [
    'Authorization' => 'Bearer <token>',
  ],
]);

echo $response->getBody();
```

```csharp Metadata Deployment_CompareDeployTenantProductCatalog_example
using RestSharp;

var client = new RestClient("https://rest.test.zuora.com/deployment-manager/deployments/tenant/product_catalog");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <token>");
request.AddParameter("undefined", "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"activeProducts\"\r\n\r\ntrue\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"activeRatePlans\"\r\n\r\ntrue\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"comments\"\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"compareField\"\r\n\r\nname\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"description\"\r\n\r\nProduct Catalog tenant - 01\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"emails\"\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"inActiveProducts\"\r\n\r\nfalse\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"inActiveRatePlans\"\r\n\r\ntrue\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"name\"\r\n\r\nTenant01PC\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"sendEmail\"\r\n\r\ntrue\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"sourceTenantId\"\r\n\r\n83e7e56d-0e02-4b4d-91f6-cc77f322c40b\r\n-----011000010111000001101001--\r\n", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift Metadata Deployment_CompareDeployTenantProductCatalog_example
import Foundation

let headers = ["Authorization": "Bearer <token>"]
let parameters = [
  [
    "name": "activeProducts",
    "value": "true"
  ],
  [
    "name": "activeRatePlans",
    "value": "true"
  ],
  [
    "name": "comments",
    "value": 
  ],
  [
    "name": "compareField",
    "value": "name"
  ],
  [
    "name": "description",
    "value": "Product Catalog tenant - 01"
  ],
  [
    "name": "emails",
    "value": 
  ],
  [
    "name": "inActiveProducts",
    "value": "false"
  ],
  [
    "name": "inActiveRatePlans",
    "value": "true"
  ],
  [
    "name": "name",
    "value": "Tenant01PC"
  ],
  [
    "name": "sendEmail",
    "value": "true"
  ],
  [
    "name": "sourceTenantId",
    "value": "83e7e56d-0e02-4b4d-91f6-cc77f322c40b"
  ]
]

let boundary = "---011000010111000001101001"

var body = ""
var error: NSError? = nil
for param in parameters {
  let paramName = param["name"]!
  body += "--\(boundary)\r\n"
  body += "Content-Disposition:form-data; name=\"\(paramName)\""
  if let filename = param["fileName"] {
    let contentType = param["content-type"]!
    let fileContent = String(contentsOfFile: filename, encoding: String.Encoding.utf8)
    if (error != nil) {
      print(error as Any)
    }
    body += "; filename=\"\(filename)\"\r\n"
    body += "Content-Type: \(contentType)\r\n\r\n"
    body += fileContent
  } else if let paramValue = param["value"] {
    body += "\r\n\r\n\(paramValue)"
  }
}

let request = NSMutableURLRequest(url: NSURL(string: "https://rest.test.zuora.com/deployment-manager/deployments/tenant/product_catalog")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```