---
title: Enhance
description: "Enhance is the most complete control-panel integration in RackHelm: it provisions real websites and subscriptions, suspends and terminates them, powers the customer's **Sites** screen, and has a bulk importer for bringing an existing Enhance estate into billing. This article covers…"
url: "https://rackhelm.com/documentation/enhance-integration/"
updated: "2026-09-24"
category: "Integrations: Control Panels"
---

# Enhance

Enhance is the most complete control-panel integration in RackHelm: it provisions real websites and subscriptions, suspends and terminates them, powers the customer's **Sites** screen, and has a bulk importer for bringing an existing Enhance estate into billing. This article covers the connection, the product binding, the importer and the optional cPGuard security panel.

## Before you start

- The `edit_integrations` permission to configure the panel. See [Roles & Permissions](/docs/roles-and-permissions/).
- Your Enhance control-plane URL, reachable from RackHelm over the public internet with a certificate that validates.
- An Enhance API token with reseller-level rights: it must be able to list and create customers, assign plans and create, suspend and delete websites.
- Your Enhance **organisation ID** — the reseller org the token belongs to. Provisioning fails without it.

## Add the connection

1. Open **System → Integrations** and press **Configure** on the **Enhance** card.
2. Set **Base URL** to your Enhance origin, for example `https://panel.example.com`. Do not append a path.
3. Paste the token into **API Token**.
4. Enter your reseller organisation UUID in **Org ID**, under the **Organization** heading.
5. Press **Save**, then **Test API**.

![The Enhance panel form showing Base URL, API Token, HTTP Timeout, Verify SSL, an Organization section with Org ID, and the cPGuard block](/wp-content/uploads/rackhelm-docs/integrations-core-panel-edit-enhance.png)
Enhance adds an **Org ID** to the standard panel form. Without it, provisioning stops before it starts.

### Fields

| Field | Rule | Notes |
| --- | --- | --- |
| **Name** | Optional, max 120 characters | Defaults to "Enhance". |
| **Active** | Checkbox | Required for Enhance to appear as an Integration Type on products. |
| **Base URL** | Required, http/https, publicly resolvable | Re-validated every time a client is built, not only on save. |
| **API Token** | Optional on edit | Blank keeps the stored token. Sent as `Authorization: Bearer`. Stored encrypted. |
| **HTTP Timeout (sec)** | Integer, minimum 1 (form minimum 5) | Used by the **Test API** button; live calls use a fixed 30-second timeout. |
| **Verify SSL** | Yes / No | Stored but not read; TLS is always verified. |
| **Org ID** | Optional in validation, max 190 characters — but required in practice | Your reseller organisation UUID. Provisioning raises "Missing Enhance panel credentials (base_url, api_token, org_id)" without it. |
| **cPGuard API Key** | Optional | See [cPGuard](#cpguard) below. |
| **Verify cPGuard SSL Certificate** | Checkbox, on by default | Untick for a self-signed certificate on port 9098. |

**Test API** requests the API root with your bearer token and reports OK for any 2xx or 3xx response. Re-type the token first — leaving the box blank sends the literal word `KEEP`, which Enhance's tester does not substitute.

## Bind a product to Enhance

Edit the product under **Catalogue → Catalogue & Groups**, open the **Provisioning** tab and choose **Enhance**.

| Field | What it is for |
| --- | --- |
| **Panel** | Which saved Enhance connection to provision against. |
| **Package / Plan ID** | **Required.** The numeric Enhance plan ID assigned to each new customer. A non-numeric or missing value fails the order with "Missing plan/package id in integration config." |
| **Site Template ID** | Optional, stored with the product. |
| **Region / Cluster** | Optional, stored with the product. |
| **AutoSSL** | Enabled (default) or Disabled. Stored with the product. |
| **Suspend after (days past due)** | Stored and clamped to −90…365, default 1. Not read by the suspension schedule. |
| **Terminate after (days after suspend)** | Stored and clamped to 0…365, default 7. Not read by the termination schedule. |
| **Provisioning Notes (internal)** | Staff-only free text. |

> **Warning:** Every Enhance order must carry a domain. The driver looks for a `DomainName` value on the order item first, then a saved `DomainName` variable on the product. If neither exists the order fails with "Missing DomainName". Add a `DomainName` custom field to the product and show it on the order page.

## What happens on provision

1. RackHelm checks the panel is answering, then resolves the domain and the plan ID.
2. It looks for an existing integration account linking this customer to this Enhance panel. If there is none, it creates an Enhance customer named after the user and stores the link.
3. It assigns the plan to that customer, which creates a subscription.
4. It creates the website under the customer's own sub-organisation, retrying for up to 40 attempts one second apart while Enhance settles the new subscription.
5. The website UUID is written to the order item, with the org, customer, subscription, plan and primary domain recorded alongside it, and the item is marked provisioned.

**Suspend** and **unsuspend** act on the website. **Terminate** is deliberately thorough: it deletes the website, then the subscription, and if that customer has no subscriptions left it deletes the Enhance customer and removes the local account link — so a cancelled customer stops consuming a licence slot. A resource already gone at Enhance (HTTP 404) is treated as success. **Renewal** is billing-only; nothing is sent to Enhance.

## The Enhance importer

If you already run Enhance, the importer creates RackHelm orders for websites that exist on the panel but not yet in billing. Open **Import Data → Enhance Importer**, or go directly to `/admin/panels/import/enhance`.

> **Note:** The sidebar link is gated on a permission that does not exist in RackHelm, so in practice only Super Admin sees it. An Administrator holding `edit_integrations` can still open the screen by URL.

The screen lists websites from your main organisation and from every customer organisation beneath it, minus any domain RackHelm already bills through an Enhance product. For each import you choose:

| Field | What it does |
| --- | --- |
| **Assign To User** | The RackHelm customer every selected site is billed to. One user per import run. |
| **Matching Product/Package** | The product to attach. Only products already bound to an Enhance integration are listed. |
| **Billing Cycle** | The cycle for the new orders. |
| **Next Renewal Date** | Per site. Pre-filled with one year from today and used as both the order due date and the item's expiry. |

![The Enhance importer listing discovered domains with tick boxes, subscription IDs and a renewal date picker](/wp-content/uploads/rackhelm-docs/integrations-core-enhance-import.png)
Sites already billed in RackHelm are filtered out, so re-running the importer is safe.

Each imported site becomes an active order with one item marked **provisioned** — the importer never calls Enhance to create anything. The unit price comes from the product's price for the chosen billing cycle (renewal price first, then the cycle price, then the product's own price). The whole run is wrapped in a transaction, so a failure imports nothing.

## cPGuard threat alerts

cPGuard is an optional server-security add-on. When you enter a **cPGuard API Key** on a panel connection, the customer's site dashboard gains a CMS threat panel, and staff and customers can trigger component updates and toggle auto-update from it.

- The cPGuard URL is **derived**, not entered: RackHelm takes the panel's base URL host and calls it on port **9098** over HTTPS.
- That derived host is checked against the same public-address rules as any other outbound URL. If it is private or unresolvable, cPGuard silently switches itself off rather than making the call.
- The key is a server-wide secret. It is typed into the `server_config` half of the form but is moved into the encrypted credential block on save, and older audit-log entries containing it are masked when the log is rendered.
- Untick **Verify cPGuard SSL Certificate** only for a self-signed certificate on 9098 — it is a downgrade and it is written to the log when used.

## Webhooks

> **Warning:** RackHelm exposes an Enhance webhook endpoint at `POST /webhooks/enhance`. It requires a `webhook_secret` on the panel connection and verifies an HMAC-SHA256 signature in the `X-Enhance-Signature` header, but it does not act on any event — it validates, logs and returns 204. There is also no field on the Enhance form for the secret. Treat webhooks as not implemented and rely on the provisioning jobs.

## Troubleshooting

| Symptom | Cause and fix |
| --- | --- |
| "Missing Enhance panel credentials (base_url, api_token, org_id)" | One of the three is blank on the connection — almost always **Org ID**. |
| "Missing DomainName" | The order carries no domain. Add a `DomainName` custom field to the product, or set a fixed value on the product. |
| "Missing plan/package id in integration config." | **Package / Plan ID** on the product's **Provisioning** tab is empty or not numeric. |
| "Plan assignment failed: No numeric subscription ID returned." | The plan ID does not exist on your Enhance panel, or the token cannot assign plans. Check the plan in Enhance and the token's rights. |
| "Enhance website creation failed: No UUID/ID returned." | The subscription was created but the website was not, after 40 retries. Check the domain is not already present on the panel and that the plan allows another website. |
| Importer shows "Failed to fetch sites from Enhance" | The connection is wrong or the token lacks customer-listing rights. Test the connection first. |
| Importer lists nothing | Every discovered domain is already billed through an Enhance product, or the token can only see an empty organisation. |
| Threat panel never appears on a site | No cPGuard key on the panel, or the derived `https://host:9098` address is private or unresolvable, which disables the integration. |
| Terminate reports "Subscription delete failed" | The website was removed but the subscription was not; the customer still holds a plan slot. Tidy it in Enhance, then retry. |
