# Install and test your Connector

A private Connector installs the same way as a public one. Only the place you find it differs. For general installation of a public Connector, follow [Deploy a Connector](/connect/getting-started.md#deploy-a-connector). The part that needs care is proving that the installation works: a Deployment can report success while the resource its `postDeploy` script should have created doesn't exist.

Zen Electron's Deployment says it succeeded, but no email arrives. By the end of this page, you can tell in one request whether the Connector is wired up, and you have seen an Order reach it.

[Choose where it runs and how to adopt it](/learning-integrate-with-commercetools/integration-essentials/choose-where-it-runs.md#the-connect-lifecycle) describes Creators and Clients as tasks, not people. On the previous page you were the Creator. Here you're the Client: you install the Connector that you published and configure it for one Project.

## Choose an install route

| Route | Environments it offers | Fits |
| --- | --- | --- |
| Connect CLI | Sandbox, production, and preview | Trial Projects, scripted installs, and repeated test cycles |
| Connect API | Sandbox, production, and preview | Automation and CI pipelines |
| Merchant Center | Preview (a Connector requested for preview) and production (a published Connector) | Non-trial Projects, and people who install without scripting |

The Merchant Center has no sandbox install. If your Project is a trial, production isn't available either, so install a published Connector to sandbox with the CLI or the API.

For production, use a non-trial Project and a published Connector. [Production](/connect/deployment-behavior-and-environments.md#production) describes the extra step for a first production publish.

[Connect workflow](/connect/connect-workflow.md#run-lifecycle-tasks-with-the-cli-api-or-merchant-center) maps each task to its command, API call, and Merchant Center screen.

## Choose the Region and environment

Deploy in the Region that hosts your Project. [Create a Deployment](/connect/getting-started.md#create-a-deployment) allows a different Region but recommends the same one for performance. [Hosts and authorization](/connect/hosts-and-authorization.md#hosts) lists the supported Google Cloud and AWS Regions, and Connect added [AWS Regions](/connect/releases/2026-03-23-connect-is-now-available-in-aws-regions) on 23 March 2026. If the ConnectorStaged sets `supportedRegions`, the Deployment's Region must be one of them, or the request fails with [`DeploymentUnsupportedRegion`](/connect/errors.md#deploymentunsupportedregion). You set `europe-west1.gcp` on the previous page.

> The [CLI reference](/connect/cli.md#commercetools-connect-deployment-create) lists only the Google Cloud Regions for `--region`. Run `commercetools connect deployment create --help` to see the values your installed CLI accepts before you deploy to an AWS Region.

Then choose the environment. A ConnectorStaged can use only `preview`, as on the previous page. A published Connector uses `sandbox`, the default, or `production` in a Project that isn't a trial. This module uses `sandbox` for Zen Electron's test installation. [Environments](/connect/deployment-behavior-and-environments.md#environments) defines each type.

A `sandbox` Deployment scales to zero when idle, so the first event after an idle period can miss the acknowledgment deadline and be redelivered, as [the event contract](/learning-integrate-with-commercetools/deploy-and-build-connectors/implement-and-test-the-event-app.md#the-contract-youre-implementing) explains. If one Order produces two confirmation log lines on sandbox, check for a cold start before you debug the handler.

## Install with the Connect CLI

Reuse the `CONFIG` array from the previous page:

```bash
commercetools connect deployment create 
  --connector-key zen-order-confirmation 
  --key zen-order-confirmation-sandbox 
  --region europe-west1.gcp 
  --type sandbox 
  "${CONFIG[@]}"
```

The CLI's API Client needs the `manage_connectors_deployments` and `manage_api_clients` scopes. [Authorization](/connect/hosts-and-authorization.md#authorization) describes both. Without `manage_api_clients`, the request fails with `403`, because Connect can't generate the Connector's API Client.

A Deployment can take several minutes. Check its status until it's `Deployed` or `Failed`:

```bash
commercetools connect deployment describe --key zen-order-confirmation-sandbox
```

## Install with the Connect API

The CLI calls [Create Deployment](/connect/deployments.md#create-deployment). Deployments are scoped to a Project in the path. Use the token and variables from the previous page, including the `CONFIGURATIONS` array:

```bash
jq -n --argjson configurations "$CONFIGURATIONS" '{
  key: "zen-order-confirmation-sandbox",
  type: "sandbox",
  connector: { key: "zen-order-confirmation" },
  region: "europe-west1.gcp",
  configurations: $configurations
}' | curl -sS --fail-with-body -X POST "$CONNECT_URL/$CTP_PROJECT_KEY/deployments" 
  -H "Authorization: Bearer $TOKEN" 
  -H "Content-Type: application/json" 
  -d @- | jq '{key, type, status}'
```

[DeploymentDraft](/connect/deployments.md#deploymentdraft) defines each field. Two points matter for this Connector:

- **`connector`**: omit `staged: true` to reference the published Connector instead of the ConnectorStaged. The CLI has no flag for `version`, so the status check below shows which version was deployed.
- **`configurations`**: `applicationName` must match `deployAs[].name` in `connect.yaml`.

Poll the status:

```bash
curl -sS --fail-with-body "$CONNECT_URL/$CTP_PROJECT_KEY/deployments/key=zen-order-confirmation-sandbox" 
  -H "Authorization: Bearer $TOKEN" | jq '{status, connector: .connector.version}'
```

## Install from the Merchant Center

For a non-trial Project, or for a preview, you can install without scripting. Follow [Install an Organization Connector](/merchant-center/connect.md#install-an-organization-connector) with these choices for Zen Electron's Connector:

- **Connector**: select **Zen Electron order confirmation** on the **Organization connectors** tab, and use **Deploy on Production** for the published Connector.
- **Projects**: on production, choose the specific Project that you're testing in.
- **Fields**: one for each key in your `connect.yaml`: `CTP_REGION` and the eight secured keys. Use the values from the `CONFIG` array. The deployment step also displays the scopes that `inheritAs` requests for the generated API Client, so nobody enters commercetools credentials.

The **Installations** tab shows the installation status. [Access the Connect marketplace](/merchant-center/connect.md#access-the-connect-marketplace) describes who can open the **Connect** tab.

## Verify the resource, not the status

When the Deployment is `Deployed`, the application is running. That doesn't prove that `postDeploy` created the Subscription. A `postDeploy` script that exits with an error can still produce a "Post-deployment setup succeeded" message, and the script's error output might not appear in the Deployment logs. A rejected environment variable, such as the [Google Cloud destination validator](/learning-integrate-with-commercetools/deploy-and-build-connectors/start-from-the-email-template.md#adjust-the-destination-validator-for-google-cloud), can cause exactly that.

Check the resource that the script is supposed to create instead. Query the Subscription by its key with the Platform API. This needs a token with `view_subscriptions` or `manage_subscriptions`. The token from the previous page has both Connect and Platform scopes if you created the CLI's API Client as described in [Start from the email template](/learning-integrate-with-commercetools/deploy-and-build-connectors/start-from-the-email-template.md#create-an-api-client-for-the-cli):

```bash
curl -sS --fail-with-body -G 
  "https://api.$CTP_REGION.commercetools.com/$CTP_PROJECT_KEY/subscriptions" 
  -H "Authorization: Bearer $TOKEN" 
  --data-urlencode 'where=key="ct-connect-email-delivery-subscription"' 
  | jq '.results[] | {key, status, destination: .destination.type, messages}'
```

A working installation returns one Subscription:

```json title="Expected result"
{
  "key": "ct-connect-email-delivery-subscription",
  "status": "Healthy",
  "destination": "GoogleCloudPubSub",
  "messages": [
    {
      "resourceTypeId": "order",
      "types": ["OrderCreated", "OrderImported"]
    }
  ]
}
```

Read the result as follows:

- **No result**: `postDeploy` didn't create the Subscription, whatever the Deployment says. Check the [destination validator change](/learning-integrate-with-commercetools/deploy-and-build-connectors/start-from-the-email-template.md#adjust-the-destination-validator-for-google-cloud) and the `inheritAs` scopes in `connect.yaml`, then redeploy.
- **`status` other than `Healthy`**: the Subscription exists, but delivery has a problem. Look up the value in [SubscriptionHealthStatus](/search.md?urn=ctp:api:type:SubscriptionHealthStatus) to see whether delivery is still being retried. [Operate a Deployment](/learning-integrate-with-commercetools/deploy-and-build-connectors/operate-a-deployment.md#check-subscription-health) covers what to do.
- **`messages` with Customer types**: the Deployment runs a tag from before [Implement and test the event app to the contract](/learning-integrate-with-commercetools/deploy-and-build-connectors/implement-and-test-the-event-app.md). Check `connector.version` on the Deployment.
- **`destination` is `SNS`**: the Project is in an AWS Region. The template doesn't decode the SNS envelope, as noted in [Implement and test the event app to the contract](/learning-integrate-with-commercetools/deploy-and-build-connectors/implement-and-test-the-event-app.md).

The `commercetools-connect` skill's [lifecycle-scripts reference](https://github.com/commercetools/commercetools-ai-plugins/blob/main/skills/commercetools-connect/references/lifecycle-scripts.md) states the same rule: verify registration by querying the resource, not by `status: "Deployed"`. For this symptom, start with the resource rather than `deployment logs`, because the logs might not contain the script's output.

## Trigger an Order

Import an Order to make the platform emit an `OrderImported` Message, which the Connector handles as a confirmation. [Create Order by Import](/api/projects/orders-import.md#create-order-by-import) needs the `manage_orders` scope and creates an Order without a Cart:

Before running this example, use the Merchant Center to create a Product with a Product Variant whose SKU is `ZE-MON-4K`, or choose the SKU of an existing Product Variant in your Project. Order Import resolves `variant.sku` against a Product Variant; the SKU in the request does not create one. If you prepare the Product through the API instead, that setup needs `manage_products` in addition to the `manage_orders` scope used for the import. Set `SKU` to the actual Variant SKU before running the request:

```bash
ORDER_NUMBER="ZE-$(date +%s)"
SKU="ZE-MON-4K" # Replace with the SKU of a Product Variant in your Project.

curl -sS --fail-with-body -X POST 
  "https://api.$CTP_REGION.commercetools.com/$CTP_PROJECT_KEY/orders/import" 
  -H "Authorization: Bearer $TOKEN" 
  -H "Content-Type: application/json" 
  -d "{
    \"orderNumber\": \"$ORDER_NUMBER\",
    \"customerEmail\": \"learner@example.com\",
    \"totalPrice\": { \"currencyCode\": \"AUD\", \"centAmount\": 4900 },
    \"lineItems\": [
      {
        \"name\": { \"en-US\": \"Zen Electron 4K monitor\" },
        \"variant\": { \"sku\": \"$SKU\" },
        \"quantity\": 1,
        \"price\": { \"value\": { \"currencyCode\": \"AUD\", \"centAmount\": 4900 } }
      }
    ]
  }" | jq '{id, orderNumber}'
```

The [Create Order by Import](/api/projects/orders-import.md#create-order-by-import) reference defines the fields. In this example, note the following:

- **`orderNumber`** is generated per run, because repeating a number fails the import.
- **`customerEmail`** is the recipient. Without it and without a `customerId`, the template skips the Order.
- **`name` has an `en-US` key**, because the template reads line item names from that locale only.

If you prefer an agent to make this call, you can use a [self-hosted Commerce MCP](/learning-integrate-with-commercetools/dev-tooling/mcp/self-hosted-commerce-mcp.md) server with your own API Client. If you also use the `commercetools-ai-plugins` plugin, give your server a name other than `commerce-mcp`. The plugin defines a server with that name, and the clash disables your tools.

## Find the work in the logs

Read the Deployment's logs for the `mail-sender` application:

```bash
commercetools connect deployment logs 
  --key zen-order-confirmation-sandbox 
  --application mail-sender
```

Look for the two lines that [Implement and test the event app to the contract](/learning-integrate-with-commercetools/deploy-and-build-connectors/implement-and-test-the-event-app.md) added, for the Order you imported:

```text
Email provider stub: email not sent {"sender":"orders@example.com","templateId":"order-confirmation","lineItemCount":1}
Order confirmation handed to email provider {"messageType":"OrderImported","resourceId":"<order-id>","sequenceNumber":1}
```

The exact formatting depends on the log view. The command pages its output and waits at a `y/n` prompt for the next page, which can look like a hang. In the Merchant Center, the same logs are on the installation's **App logs** tab.

If no line appears within a few minutes:

- **Wait a minute after a new Deployment.** Deliveries in the first minute can be rejected with `401` while Connect sets up push authentication. Pub/Sub retries them, and they then succeed.
- **Check for a cold start.** On sandbox, the first Message after an idle period can arrive late.
- **Check the Subscription again.** If it's missing or unhealthy, the Message never reached the application.

## Worked example: install Zen Electron's Connector

1. Install `zen-order-confirmation` to sandbox with `deployment create` and wait for `Deployed`.
2. Query the Subscription by key: one result, `Healthy`, `GoogleCloudPubSub`, and the two Order Message types.
3. Import an Order with a new order number.
4. Find one `Order confirmation handed to email provider` line with the imported Order's ID.

One Order produced one stubbed send. Zen Electron has proved the full path, from Order to Subscription to Connector, without trusting the Deployment status.

This exercise tests an `event` application and logs a stubbed provider call; it doesn't test actual email delivery or cover `service` and `job` applications. If you administer a Connector with those application types, follow [Test applications locally](/connect/test-applications-locally.md) for service, event, and job endpoint tests before publishing. Test each application against its own contract rather than treating this event-only check as a general installation test.

Keep this Deployment. The next page operates it.

## Key takeaways

- Installing your own private Connector is the same Client task as installing a public one.
- The Merchant Center offers preview and production installs. Use the CLI or the API for sandbox, which is the route for trial Projects.
- Deploy in the Project's Region, which Connect recommends, and within the Connector's `supportedRegions`. Connect supports Google Cloud and AWS Regions.
- A Deployment can report success when `postDeploy` failed. Prove the installation by querying the resource it creates, such as the Subscription, by key.
- Trigger the Connector with a real platform event, such as an imported Order, and confirm the work in the Deployment logs.
- Expect delays right after deployment and after a sandbox cold start before you debug.

## Related pages

- [Area overview page with navigation](/learning-integrate-with-commercetools.md)
- [Previous page: Stage, preview, and publish privately](/learning-integrate-with-commercetools/deploy-and-build-connectors/stage-preview-and-publish-privately.md)
- [Next page: Operate a Deployment](/learning-integrate-with-commercetools/deploy-and-build-connectors/operate-a-deployment.md)
- [Search documentation and API specs](/search.md)