Skip to documentation

Exchange will be rebuilt separately and is unavailable through the API or CLI. Availability in this release

Workflow guides

Markdown

Exchange is excluded from this API/CLI release. Any historical Exchange API or CLI example in this guide is unavailable; native portal behavior is outside this exclusion. See current release scope.

Importing existing Hosting

The portal and API record an existing Plesk hosting environment with its proven aliases, databases, mailboxes and subdomains as one local import. Nothing is ordered or changed at Plesk. Import neither reads nor resets passwords, writes DNS, nor starts an invoice or subscription.

Every action requires a human internal administrator with current passkey verification. API review and result inspection use admin:read; saving and billing investigation use admin:write. A service key cannot obtain these rights. The account in the URL or --account is the administration context. The separate selection.account_id is the explicitly confirmed target company.

Without complete stored Plesk server configuration, review and import capabilities are disabled (hosting_provider_configuration_required). The portal then points to server administration. Configuration presence does not prove supplier reachability. Missing or unreadable server credentials produce a controlled 503 before any supplier request. Original receipts remain retrievable independently of the supplier.

In the portal

Open Hosting → Import. Choose the exact company, configured Plesk server, suitable portal product and public primary domain name. Supply separately verified customer coverage. A supplier expiry date does not prove payment or a customer agreement.

An existing exact server-customer binding can prove company ownership. Without that binding, explicitly confirm the observed Plesk customer ID and record the source and outcome of external ownership evidence. A matching name or email address is insufficient. Review shows whether this evidence is complete; import cannot be confirmed without proven product ownership.

Check server, product, owner and all counts. Type the displayed modern company ID and acknowledge unresolved billing. Import creates all local parts and name claims together. A local failure rolls back the entire import. A blocked Plesk hosting environment remains blocked locally. Mailboxes are not activated and their observed status remains part of the receipt.

Registration and DNS remain independent. An existing owned registration can be linked. A missing registration or one belonging to another company remains unlinked; only the public domain name is used. Import transfers no registration, DNS zone or Hosting product from another company. Adding a new alias later still requires an owned domain.

After a lost response, preserve the original selection and intent UUID. Choose Find original import. This is a GET without a supplier request. The browser stores only the intent UUID under the original administrator, login identity and context. A missing result does not prove that the original request stopped: send no new import and create no replacement UUID. The portal does not automatically resend the import. Cancelling passkey verification before the first submission leaves the selection editable.

Supplier evidence

The selected server must return exactly one hosting subscription with the specified name, including its ID, GUID, owner, primary website and complete child collections. The primary website ID may differ from the subscription ID. Every alias, database and subdomain must demonstrably belong to this environment. An incomplete or ambiguous collection is rejected, including an empty XML envelope without an explicit result. Limits are 1,000 results per collection and 2 MiB per response, without redirects.

The selected product must describe the exact server-bound plan and the same effective quotas. Managed current and historical plan revisions are checked against their original GUID and contract. The older fallback requires exactly the same plan name, provider ID and quotas on this server. Extra websites, multiple base/add-on plans or different quotas first require a suitable product representation; import does not reduce or replace permissions. Installed applications have not been investigated and are not claimed as adopted configuration.

XML readers use the existing configured server and the official Plesk subscription structure, database filters and subdomain structure. Local tests do not prove that a specific production environment has already been imported or changed.

Typed CLI

Use your human administrator login. selection.json contains the object inside selection from the API example below, without the outer wrapper. The domain is the canonical ASCII/xn-- name. The new review file is created privately; existing files and symlinks are rejected. Windows reads input only through trusted stdin (--from-file -).

binadit admin hosting imports inspect --account 1 --from-file selection.json --file hosting-review.json
binadit admin hosting imports commit --account 1 --from-file hosting-review.json --confirm-company 42 --acknowledge-unresolved-billing --dry-run
binadit admin hosting imports commit --account 1 --from-file hosting-review.json --confirm-company 42 --acknowledge-unresolved-billing --yes --no-input

The Rust CLI creates new reviews with schema binadit-hosting-import/v2. It additionally stores the public personal original_principal_id from /me, obtained with the same token as inspection. An import POST uses only that original connection; immediately before sending, the CLI checks the current principal with the token actually used. The original private review file and durable submission marker are checked again before submission and before displaying results. The marker contains only fixed public intent metadata and the opaque server review version, not ownership notes. The explicit private review can contain your investigation note.

Old review files without a proven original principal are not adopted for an import POST in Rust. The GET recovery action below remains available even for such an original review file, within current server permissions and the same administrator and identity version. After signing in again, this read action can inspect the original result; it grants no new write permissions. Do not change a stored principal or key to bypass a refusal.

Normal commit rereads the current review and compares version, provider ID/GUID/owner, counts and original context. Before the actual POST, an exclusive private marker containing only intent metadata is durably recorded. A subsequent normal commit with that marker sends nothing. This marker is retained even after a successful response; use GET recovery for the original result:

binadit admin hosting imports commit --account 1 --from-file hosting-review.json --confirm-company 42 --acknowledge-unresolved-billing --recover --confirm-intent ORIGINAL_INTENT_UUID

--recover reads only GET imports/{originalIntentUUID}. It sends no POST and does not reread Plesk, even if the original review has expired. A 404 or unclear response unlocks no new import. Preserve review file, UUID and key and investigate the original operation. The outcome is checked against company, server, product, supplier identity and complete child counts before display. No supplier responses or ownership notes appear in the submission marker or output.

Separate billing investigation uses:

binadit admin hosting imports billing get SUBSCRIPTION_ID --account 1 --output json
binadit admin hosting imports billing confirm SUBSCRIPTION_ID --account 1 --version CURRENT_BILLING_ETAG --confirm-subscription SUBSCRIPTION_ID --from-file investigation.json

investigation.json contains only investigation_note and acknowledge_external_billing_unchanged: true. Read the boundary under Existing billing before making this decision.

API and advanced CLI

Under /api/v1/accounts/{context}/admin/hosting:

Method and path Use
POST imports/inspect Read-only review of {selection, reviewed_at?}; no operation or idempotency key required
POST imports Import the reviewed environment locally; If-Match and permanent Idempotency-Key required
GET imports/{intent} Read this administrator's originally confirmed result, login identity, context and API channel
GET subscriptions/{subscription}/import-billing Current billing review and ETag
POST subscriptions/{subscription}/actions/confirm-no-portal-billing Record an explicit investigation with the current billing ETag

Example inspect.json (numbers are examples):

{
  "selection": {
    "server_id": 8,
    "account_id": 42,
    "product_id": 9,
    "domain": "example.com",
    "owner_evidence": "verified_mapping",
    "confirmed_provider_owner_id": null,
    "owner_review_note": null,
    "coverage_until": "2026-11-30"
  }
}

For reviewed external ownership evidence, use owner_evidence: "reviewed_external_evidence", the exact positive confirmed_provider_owner_id and a non-secret owner_review_note of 20–1,000 characters. The server checks that the customer ID matches the current Plesk owner and does not already belong to another local company.

The commit body contains the exact returned selection, one original UUID in intent_id, reviewed_at in UNIX seconds, snapshot_version, confirm_account_id and acknowledge_unresolved_billing: true. Send the same snapshot_version as If-Match. dry_run: true performs a current review but imports nothing and reserves no API operation.

The review is valid for ten minutes. The server rereads the supplier before storage and also compares current company, server, product and domain bindings after SQL waiting. A different version requires a new review; do not change an original request to bypass an unclear outcome.

The generic CLI can call this account-bound contract. Keep input with private file permissions; on Windows, use trusted stdin with --from-file -. These examples use the generic API command syntax; for daily use, see the typed commands above:

binadit api /admin/hosting/imports/inspect --method POST --from-file inspect.json --account 1 --yes --output json
binadit api /admin/hosting/imports --method POST --from-file commit.json --version SNAPSHOT_VERSION --idempotency-key ORIGINAL_KEY --account 1 --yes --dry-run
binadit api /admin/hosting/imports --method POST --from-file commit.json --version SNAPSHOT_VERSION --idempotency-key ORIGINAL_KEY --account 1 --yes
binadit api /admin/hosting/imports/ORIGINAL_INTENT_UUID --account 1 --output json

After uncertainty, use only the final GET and original API operation. Preserve body, UUID and key. A CLI confirmation cannot replace missing server rights, current passkey verification or a release setting.

Existing billing

Import starts with billing_review_state: "unresolved". Cancellation, resumption and permanent deletion remain blocked until existing agreements have been investigated separately. Merely lacking a local WeFact mirror proves nothing.

If investigation shows that this portal should manage no automatic billing agreement, explicitly record the source and outcome. This neither terminates, pays nor moves an external agreement. An active, uncertain or not-yet-expired local agreement blocks that declaration. A mirror with status terminated is compatible only if its external ID is positive and the termination date is known and strictly before today. A wrong company binding is not silently ignored.

Confirmation contains confirm_subscription_id, investigation_note (10–1,000 characters), acknowledge_external_billing_unchanged: true and the current billing ETag in If-Match. A separate permanent Idempotency-Key is required; dry_run remains available. An audited declaration receives reviewed_no_portal_agreement and a server-bound proof. A changed source identity, company binding, new open order/task or tampered declaration blocks it again. Never manually attach an old mirror ID to a newly imported product.

FTP, mailbox and panel passwords are not made available through import. A missing or unreadable secret produces a controlled 409; this is no reason to display an arbitrary old customer password or automatically reset a password.

Contract for AI agents

Review exact provider identity, quota, company ownership and customer coverage. Keep administration context distinct from the target company. Freeze the complete commit body, signed snapshot, original intent UUID and idempotency key. Typed commit --recover is GET-only; a durable private marker blocks another normal POST. Preview performs reads only. After an ambiguous response, use original-intent GET and original-operation inspection; do not allocate a replacement import. Supplier credentials, DNS, registration and external billing remain unchanged. Treat unresolved billing, unknown credentials and unproven collections as explicit states, never as successful empty or paid results. Renewal, cancellation and deletion require their own current authorization and financial proof.