WebApp
Web Apps

Register a new web application.

Changed on

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.

post/WebApp/stage

Request

  • Base URL
    https://cpanel-server.tld:2083/execute
  • Auth
    HTTP basic

Query parameters

namestring required
Example:my-app

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

sourcestring required
Example:https://github.com/example/my-app.git

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.

source_type'zip' | 'git' required
Example:git

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.
appdirstring
Example:packages/web

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.

branchstring
Example:main

The Git branch to clone. Only meaningful when source_type is git.

This parameter defaults to the repository's default branch.

mode'production' | 'development'
Example:production

The run mode for server category applications.

This parameter defaults to production.

parentstring domain
Example:shop.example.com

The parent domain to serve the application under. The application's domain becomes <assigned name>.<parent> — 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.

runtime'nodejs'
Example:nodejs

The runtime that backs the application.

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

ssh_key_namestring
Example:github-test

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.

Request body application/x-www-form-urlencoded

sshkeypassstring

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 request

{
  "sshkeypass": "correct-horse-battery-staple"
}

Response

HTTP Request was successful.

apiversioninteger

The version of the API.

funcstring

The name of the method called.

modulestring

The name of the module called.

Example response

{
  "apiversion": 3,
  "func": "stage",
  "module": "WebApp",
  "result": {
    "data": {
      "build_command": "npm run build",
      "category": "server",
      "confidence": "high",
      "container_name": "my-app.bob.01",
      "defaults": {
        "build_command": "npm run build",
        "output_dir": ".next",
        "runtime_tag": "22",
        "startup_command": "npm run start"
      },
      "domain": "my-app.example.com",
      "env": {
        "NODE_ENV": "production"
      },
      "env_editable": true,
      "env_status": "ok",
      "last_deploy": {
        "deploy_id": "dp-20260612-0001",
        "result": "success",
        "timestamp": "2026-06-12T14:03:22.000Z"
      },
      "mode": "production",
      "name": "my-app",
      "package_manager": "npm",
      "runtime": "nodejs",
      "runtime_tag": "22",
      "source": {
        "branch": "main",
        "ssh_key_name": "github-test",
        "type": "git",
        "url": "https://github.com/example/my-app.git"
      },
      "staged": true,
      "startup_command": "npm run start",
      "status": "created",
      "url": "https://my-app.example.com"
    },
    "status": 1
  }
}

Changes