---
title: "Register a new web application."
method: POST
path: "/WebApp/stage"
tags: ["WebApp", "Web Apps"]
---

# Register a new web application.

`POST /WebApp/stage`

## Request

- Base URL: `https://cpanel-server.tld:2083/execute`
- URL: `https://cpanel-server.tld:2083/execute/WebApp/stage`
- Auth: HTTP basic

Web Apps is the recommended feature for deploying new web applications, and this function is the entry point. Prefer it over the older Application Manager (`PassengerApps`) feature for new deployments.

This function registers a new web application from an uploaded
archive or a Git repository. Once the source is placed on disk, it
runs a preflight that inspects the source and detects the
application's framework and category, records them on the
application, and derives suggested configuration defaults. The
detection `confidence` and the suggested `defaults` are returned so
you can pass them to `WebApp::configure`. The application is
registered but **not** deployed — call `WebApp::configure` (optional)
and then `WebApp::deploy` to bring it live.

The preflight never fails the stage: a source with no recognizable
markers is registered with a `none` confidence and generic defaults.

Registering a name that is still **staged** (not yet deployed)
overwrites it: the previously staged application and its source are
replaced, and the response `warnings` array reports that the old
files were overwritten.

Registering a name that is already **deployed** leaves the running
application untouched — its container and live routing are never
disturbed — but the new application cannot reuse the deployed
application's display name, or `WebApp::list` and bare-name
addressing could not tell the two apart. So it is registered under
the next free `<name>-N` (for example, `my-app-2`), and the response
`warnings` array reports the assigned name. **Read the assigned name
from the response `data.name`: you must pass that name (not the one
you requested) to `WebApp::configure` and `WebApp::deploy` to act on
this application**, which stands up as its own separate container.

On failure, the `metadata.error_category` field carries a
machine-readable failure category.

GET is also available, without a request body, for calls that do not
need to unlock a passphrase-protected `ssh_key_name`.

## Query parameters

- `name` string, required
- `source` string, required
- `source_type` 'zip' | 'git', required
- `appdir` string
- `branch` string
- `mode` 'production' | 'development'
- `parent` string, domain
- `runtime` 'nodejs'
- `ssh_key_name` string

## Request body `application/x-www-form-urlencoded`

- object
  - `sshkeypass` string: The one-off passphrase to unlock `ssh_key_name` for this clone only; it is never stored. Required when `ssh_key_name` names a currently passphrase-protected key -- only a modern `OPENSSH PRIVATE KEY`-format encrypted key supports this; a legacy PEM-format encrypted key is still rejected outright. Irrelevant, and ignored, for a key that is not passphrase-protected. **Security note:** This parameter carries a secret and must ride only in the POST request body. The system rejects both a non-`POST` request and a `sshkeypass` key in the URL query string before it reads the passphrase, so it cannot leak into access logs, proxy logs, or browser history. This check does not apply to the `bin/uapi` CLI or LiveAPI Perl/PHP bindings; on the CLI in particular, passing `sshkeypass` inline puts it in `ps` output and shell history, so prefer an interactive or file-based passphrase input there instead.

## Response `200`

HTTP Request was successful.

- object
  - `apiversion` integer: The version of the API.
  - `func` string: The name of the method called.
  - `module` string: The name of the module called.
  - `result` object
    - `data` object: The newly registered application.
      - `build_command` string, nullable: The application's configured build command, or `null` if it has no build step. Set from the preflight-suggested default detected by this call, and overridable via `configure`.
      - `category` 'static' | 'server' | 'other': The application's category. This determines which lifecycle actions apply. * `static` — The application builds to static files that the web server serves directly. * `server` — The application runs a long-lived server process. * `other` — Any other kind of application.
      - `confidence` 'high' | 'low' | 'none': How confident the preflight detection is. * `high` — Strong framework markers found. * `low` — Partial markers found; verify the defaults before deploying. * `none` — No recognizable markers; the defaults are generic.
      - `container_name` string, nullable: The name of the deployed container backing this application, or `null` while it is only staged. Assigned by the deploy and unique per application instance, so it identifies the exact deployed record even when several applications share a base name.
      - `defaults` object: Suggested configuration values for the detected framework. Pass them to `WebApp::configure` as-is or after user adjustment.
        - `build_command` string, nullable: The suggested build command, or `null` if no build step is needed.
        - `output_dir` string, nullable: The suggested build output directory, or `null` if not applicable.
        - `runtime_tag` string: The suggested runtime version tag.
        - `startup_command` string, nullable: The suggested startup command, or `null` for `static` applications.
      - `deployed` boolean: Whether a deploy has put the application live. This is `true` once the application holds a container or a deploy has completed successfully, and `false` for a freshly staged application or one whose only deploy failed.
      - `domain` string, domain: The domain the application is bound to, composed as the assigned name under the requested `parent` — or under the account's main domain when `parent` was omitted. The domain is not created until the application is deployed.
      - `env` object: The application's environment variables.
      - `env_editable` boolean: Whether the environment may be set for this application. The values are written to the application's own `.env`, which lives in its source tree, so a repository that would publish that file withholds the feature: a `configure` that sets `env` or `env_text` fails with an `error_category` of `env_not_editable`. Derived from the source tree on every call, so it changes as soon as the repository does.
      - `env_status` 'ok' | 'tracked' | 'not_ignored': Why the environment is not editable, or `ok` when it is. `tracked` means the repository tracks `.env`; `not_ignored` means no committed `.gitignore` rule covers it. Both are fixed by the user in the repository, not through this API.
      - `framework` string, nullable: The application's detected or user-selected framework, or `null` if unknown.
      - `last_deploy` object, nullable: Information about the most recent deploy, or `null` if the application has never deployed.
        - `deploy_id` string: The unique identifier of the deploy.
        - `result` 'success' | 'failed': The result of the deploy.
        - `timestamp` string, date-time: When the deploy finished, in ISO 8601 format.
      - `mode` 'production' | 'development', nullable: The application's run mode. Only meaningful for the `server` category; `null` otherwise.
      - `name` string: The application's assigned name (slug), unique across the account. This may differ from the name you requested: if a deployed application already used that name, the application was registered under the next free `<name>-N`. Use this value for `WebApp::configure` and `WebApp::deploy`.
      - `package_manager` 'npm' | 'yarn' | 'pnpm' | 'bun': The package manager the deploy uses to install dependencies and run scripts. It is detected from the source's `packageManager` field, a lockfile, or the default (`npm`).
      - `runtime` string: The application's runtime identifier.
      - `runtime_tag` string: The runtime version tag.
      - `source` object: The application's source information.
        - `branch` string, nullable: The Git branch, or `null` for ZIP sources.
        - `ssh_key_name` string, nullable: The name of the SSH key used for the clone, or `null` when none was selected or the source is not Git.
        - `type` 'zip' | 'git': The source type. * `zip` — An uploaded archive. * `git` — A Git repository.
        - `url` string, nullable: The Git repository URL, or `null` for ZIP sources.
      - `staged` boolean: Whether the application's source is present in the staging area. This is `true` after the source is uploaded or cloned and until the application is deleted.
      - `startup_command` string, nullable: The application's configured startup command, or `null` for a `static` application (which has no running process to start). Set from the preflight-suggested default detected by this call, and overridable via `configure`.
      - `status` 'created' | 'deploying' | 'running' | 'stopped' | 'errored': The application's current status. * `created` — Registered but never deployed. * `deploying` — A deploy is in progress. * `running` — The application is live. * `stopped` — The application is stopped. * `errored` — The last action failed.
      - `url` string, url: The application's live HTTPS URL.
      - `use_existing_domain` integer: Whether the application was confirmed onto a domain the account already used, replacing what that domain served. `0` for an application serving a domain it created itself. See https://go.cpanel.net/docroot2proxy.
    - `errors` string[], nullable: List of errors if the API failed.
    - `messages` string[], nullable: List of messages generated by the API.
    - `metadata` object
      - `error_category` 'limit_exceeded' | 'source_invalid' | 'source_auth_failed' | 'source_host_key_failed' | 'source_credentials_required' | 'source_passphrase_required', nullable: The machine-readable failure category. Only present when `status` is `0`. * `limit_exceeded` — The account reached its application count or memory limit. * `source_invalid` — The source archive or Git repository is missing, unreadable, or invalid. * `source_auth_failed` — The Git repository could not be cloned because SSH access is not set up. * `source_host_key_failed` — The Git repository could not be cloned because the remote server’s SSH host key is not trusted yet. * `source_credentials_required` — The Git repository could not be cloned because the HTTPS clone requires credentials. * `source_passphrase_required` — `ssh_key_name` names a currently passphrase-protected key and `sshkeypass` was missing or incorrect.
    - `status` 0 | 1: - `1` - Success. - `0` - Failed. Check the `errors` field for more details.
    - `warnings` string[], nullable: List of warnings generated by the API. Warnings describe non-critical failures or other problematic conditions noted while running a API.

## Changes

- **2026-09-12** `99adb57e7a5d`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/cpanel/apis/cpanel-uapi/changes/WebApp/stage/post.md)

---

[API](https://skmtc.dev/cpanel/apis/cpanel-uapi.md) - [All operations](https://skmtc.dev/cpanel/apis/cpanel-uapi/llms.txt) - [OpenAPI document](https://skmtc.dev/cpanel/apis/cpanel-uapi/revisions/05239220da37?raw)
