# Register a new web application.

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 -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.

Endpoint: POST /WebApp/stage
Version: 11.138.0.10
Security: BasicAuth

## Query parameters:

  - `name` (string, required)
    The requested application name (slug). If a deployed application
already uses it, the application is registered under the next free
-N instead; read the assigned name from the response
data.name and use it for WebApp::configure and WebApp::deploy.
    Example: "my-app"

  - `source` (string, required)
    The application's source location. This is required for every
source type:

* When source_type is zip — the path, relative to the user's
  home directory, of a previously uploaded source archive: a ZIP
  or tar file (for example, uploads/my-app.zip or
  uploads/my-app.tar.gz).
* When source_type is git — the Git repository URL to clone
  (for example, https://github.com/example/my-app.git).

Security note: This source is built and run on the server.
Only use uploaded archives or Git repositories from a trusted
origin.

Do not embed credentials (such as a username and password or an
access token) in the Git URL — they are stored in plaintext. To
clone a private repository, use a Git SSH URL that you have an
SSH key configured for.
    Example: "https://github.com/example/my-app.git"

  - `source_type` (string, required)
    The application's source type.

* zip — An archive (ZIP or tar — .tar, .tar.gz/.tgz,
  .tar.bz2, .tar.xz) previously uploaded with
  Fileman::upload_files.
* git — A Git repository.
    Enum: "zip", "git"

  - `appdir` (string)
    The application root, relative to the top of the cloned repository
or extracted archive, for a source whose application does not live
at the top level (for example, packages/web in a monorepo). The
preflight inspects this directory to detect the framework.

This parameter must be a relative path inside the source. When
omitted, it defaults to the source root, unless the manifest is
found in a single top-level subdirectory (as in a repository zip),
in which case that subdirectory is used automatically.
    Example: "packages/web"

  - `branch` (string)
    The Git branch to clone. Only meaningful when source_type is
git.

This parameter defaults to the repository's default branch.
    Example: "main"

  - `mode` (string)
    The run mode for server category applications.

This parameter defaults to production.
    Enum: "production", "development"

  - `parent` (string)
    The parent domain to serve the application under. The application's
domain becomes . — read it back from the
response data.domain rather than composing it, since the assigned
name may differ from the requested name.

This is the parent domain only, not the whole served domain. The
account must own the parent itself; owning only the domain above it is
not sufficient.

Omit this parameter — or pass an empty value — to serve the
application under the account's main domain.
    Example: "shop.example.com"

  - `runtime` (string)
    The runtime that backs the application.

This parameter defaults to the system default runtime
(nodejs).
    Enum: "nodejs"

  - `ssh_key_name` (string)
    The name of one of the account's existing SSH keys (Security's
"Manage SSH Keys") to use for the clone. Only meaningful for a
git@... SSH source URL; invalid with source_type zip, or
with an https:// source.

This lets the clone use a key that has real access to the
repository even when it is not stored under one of ssh's default
identity filenames. When this key is currently passphrase-protected,
also provide sshkeypass.
    Example: "github-test"

## Request fields (application/x-www-form-urlencoded):

  - `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.
    Example: "correct-horse-battery-staple"

## Response 200 fields (application/json):

  - `apiversion` (integer)
    The version of the API.
    Example: 3

  - `func` (string)
    The name of the method called.
    Example: "stage"

  - `module` (string)
    The name of the module called.
    Example: "WebApp"

  - `result` (object)

  - `result.data` (object)
    The newly registered application.

  - `result.data.build_command` (string,null)
    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.
    Example: "npm run build"

  - `result.data.category` (string)
    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.
    Enum: "static", "server", "other"

  - `result.data.confidence` (string)
    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.
    Enum: "high", "low", "none"

  - `result.data.container_name` (string,null)
    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.
    Example: "my-app.bob.01"

  - `result.data.defaults` (object)
    Suggested configuration values for the detected framework. Pass them to WebApp::configure as-is or after user adjustment.

  - `result.data.defaults.build_command` (string,null)
    The suggested build command, or null if no build step is needed.
    Example: "npm run build"

  - `result.data.defaults.output_dir` (string,null)
    The suggested build output directory, or null if not applicable.
    Example: ".next"

  - `result.data.defaults.runtime_tag` (string)
    The suggested runtime version tag.
    Example: "22"

  - `result.data.defaults.startup_command` (string,null)
    The suggested startup command, or null for static applications.
    Example: "npm run start"

  - `result.data.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.

  - `result.data.domain` (string)
    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.
    Example: "my-app.example.com"

  - `result.data.env` (object)
    The application's environment variables.
    Example: {"NODE_ENV":"production"}

  - `result.data.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.
    Example: true

  - `result.data.env_status` (string)
    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.
    Enum: "ok", "tracked", "not_ignored"

  - `result.data.framework` (string,null)
    The application's detected or user-selected framework, or null if unknown.

  - `result.data.last_deploy` (object,null)
    Information about the most recent deploy, or null if the application has never deployed.

  - `result.data.last_deploy.deploy_id` (string)
    The unique identifier of the deploy.
    Example: "dp-20260612-0001"

  - `result.data.last_deploy.result` (string)
    The result of the deploy.
    Enum: "success", "failed"

  - `result.data.last_deploy.timestamp` (string)
    When the deploy finished, in ISO 8601 format.
    Example: "2026-06-12T14:03:22.000Z"

  - `result.data.mode` (string,null)
    The application's run mode. Only meaningful for the server category; null otherwise.
    Enum: "production", "development"

  - `result.data.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 -N. Use this value for
WebApp::configure and WebApp::deploy.
    Example: "my-app"

  - `result.data.package_manager` (string)
    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).
    Enum: "npm", "yarn", "pnpm", "bun"

  - `result.data.runtime` (string)
    The application's runtime identifier.
    Example: "nodejs"

  - `result.data.runtime_tag` (string)
    The runtime version tag.
    Example: "22"

  - `result.data.source` (object)
    The application's source information.

  - `result.data.source.branch` (string,null)
    The Git branch, or null for ZIP sources.
    Example: "main"

  - `result.data.source.ssh_key_name` (string,null)
    The name of the SSH key used for the clone, or null when none was selected or the source is not Git.
    Example: "github-test"

  - `result.data.source.type` (string)
    The source type.

* zip — An uploaded archive.
* git — A Git repository.
    Enum: "zip", "git"

  - `result.data.source.url` (string,null)
    The Git repository URL, or null for ZIP sources.
    Example: "https://github.com/example/my-app.git"

  - `result.data.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.
    Example: true

  - `result.data.startup_command` (string,null)
    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.
    Example: "npm run start"

  - `result.data.status` (string)
    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.
    Enum: "created", "deploying", "running", "stopped", "errored"

  - `result.data.url` (string)
    The application's live HTTPS URL.
    Example: "https://my-app.example.com"

  - `result.data.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.

  - `result.errors` (array,null)
    List of errors if the API failed.

  - `result.messages` (array,null)
    List of messages generated by the API.

  - `result.metadata` (object)

  - `result.metadata.error_category` (string,null)
    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.
    Enum: "limit_exceeded", "source_invalid", "source_auth_failed", "source_host_key_failed", "source_credentials_required", "source_passphrase_required"

  - `result.status` (integer)
    - 1 - Success.
- 0 - Failed. Check the errors field for more details.
    Enum: 0, 1

  - `result.warnings` (array,null)
    List of warnings generated by the API. Warnings describe non-critical failures or other problematic conditions noted while running a API.


