Skip to main content

Apps API

The Apps API allows you to manage apps in Quave ONE. You can create, retrieve, and delete apps.

Make sure to read the Get Started document to understand how the API works.

Note: All endpoints in this API accept only the user token.

List App Presets​

GET /api/public/v1/app-presets returns the non-database presets accepted by app creation, including FUNCTION and JOB. MCP exposes the same result through list-app-presets. Functions and Jobs use dedicated UI creation flows but remain available in API discovery.

Each entry includes name, label, hasVersions, versions, and, where applicable, defaultDockerPresetVersion, isCustom, isFunction, isJob, and requiresDockerfile. The Dockerfile flag applies to source builds, not pre-built images. Jobs do not require a port. Managed database/service presets remain in GET /api/public/v1/database-presets.

Create App​

To create a new app, send a POST request to the /api/public/v1/app endpoint. Provide the required fields in the request body.

Below are the required fields:

FieldTypeDescription
nameStringThe name of the app.
accountIdStringThe ID of the account to create the app in.
portNumberThe port number the app listens on. Required for non-Job apps.

Optional fields:

FieldTypeDescription
dockerPresetStringThe Docker preset to use. Default is CUSTOM. For app presets, possible values are: NEXT_JS, REMIX, VITE, VUE_JS, EXPRESS, NODE_JS_INSTALL_START, NODE_JS_INSTALL_BUILD_START, ANGULAR, METEOR_JS, CUSTOM, FUNCTION, JOB. For managed databases, first call GET /api/public/v1/database-presets and use one of the returned values, currently MONGODB, POSTGRESQL, MYSQL, REDIS, COUCHDB, RABBITMQ, or CLICKHOUSE.
dockerPresetVersionStringThe version for the chosen Docker preset (optional). For example: METEOR_JS_3_5, NEXT_JS_NODE_JS_22, EXPRESS_NODE_JS_20, etc.
useImageBooleanWhether to use a Docker image.
gitNamespaceStringThe Git namespace (required for GitHub deployments).
gitRepoStringThe Git repository name (required for GitHub deployments).
gitInstallationIdStringThe Git installation ID (required for GitHub deployments).
imageStringThe Docker image to use (if useImage is true).
buildArgsStringDocker build arguments.
contextDirStringThe context directory for the Docker build (default is "./").
dockerfilePathStringThe path to the Dockerfile. Defaults to Dockerfile when dockerPreset is CUSTOM and customDockerfileContent is omitted.
customDockerfileContentStringThe custom Dockerfile content.
isCliDeploymentBooleanWhether this is a CLI deployment.
jobConfigObjectJob command, timeout, TTL, retry, and concurrency settings. Only for dockerPreset: "JOB". See Job Runs API.

Startup commands are environment-level runtime configuration, so the Apps API does not accept startupConfig. Create the app first, then set the initial override with POST /api/public/v1/app-env, or update an existing environment with PUT /api/public/v1/app-env. See Startup Command Overrides.

Example:

curl -X POST \
-H 'Authorization: YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"name": "My New App",
"accountId": "5f7b1b7b7b7b7b7b7b7b7b7b",
"port": 3000,
"gitNamespace": "my-org",
"gitRepo": "my-app",
"gitInstallationId": "12345678"
}' \
https://api.quave.cloud/api/public/v1/app

Example Response:

{
"appId": "5f7b1b7b7b7b7b7b7b7b7b7b"
}

The response contains the appId of the newly created app.

Databases & Services Apps​

The public API can create Databases & Services apps for automatic DevOps presets. These include databases, caches, and brokers. The endpoint and appType=db name are kept for API compatibility. Currently supported presets: MONGODB, POSTGRESQL, MYSQL, REDIS, COUCHDB, RABBITMQ, and CLICKHOUSE.

Call GET /api/public/v1/database-presets before POST /api/public/v1/app to read the available dockerPresetVersion values, the default version, the connection protocol, and the per-preset disk and replica limits. CouchDB is currently single-node only, so create its environments with containers set to 1.

Solutions​

Curated solutions use the same normal App and App Environment creation flow as the dashboard. List the available catalog for an account with GET /api/public/v1/solutions?accountId=ACCOUNT_ID, then create the chosen solutionSlug with POST /api/public/v1/solutions.

The list response exposes only safe catalog metadata: required inputs and the component graph. It never exposes solution secrets or internal deployment values. Creation requires account-admin permission and returns the created component app and environment IDs. OAuth creation requires both quave:write:config and quave:write:deploy because it provisions compute.

Warren additionally requires the account Sandbox entitlement and a region whose Agent Sandbox add-on and public gateway are ready. It runs its agents through the regular Agent Sandboxes API with the Quave ONE token you give as inputs.quaveOneApiToken, like any other client. Use a user token of a member who can create sandboxes in the account; MCP keys are not accepted on direct API calls. Quave ONE rejects the installation before creating components when either prerequisite is missing. An unsupported inputs.warrenImage returns HTTP 400 with an actionable validation message before contacting GHCR or creating resources. Choose ghcr.io/quavedev/warren with latest, a numeric Quave version, or an immutable sha256 digest. The short forms latest, 0.21.0.1 and sha256:<digest> are accepted too, and Quave ONE stores the full ghcr.io/quavedev/warren reference.

curl -X POST \
-H 'Authorization: YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"accountId": "5f7b1b7b7b7b7b7b7b7b7b7b",
"solutionSlug": "headscale-stack",
"appName": "Team VPN",
"region": "us-5"
}' \
https://api.quave.cloud/api/public/v1/solutions

Some solutions have an explicit post-provisioning step when a third-party credential cannot safely exist until one component is ready. Follow the returned postInstallNote before treating every component as connected.

If a multi-component creation fails partway through, the error response returns an installationId. Fix the reported condition and repeat the same request with that ID to create only the missing components; the components already created remain normal App/AppEnv resources.

Creation is synchronous and can take several minutes. If the connection drops before you get a response (for example, a 502 or 504 from a proxy), do not start over with a new name. Repeat the same request:

  • Without an installationId, a 409 response returns the installationId of the unfinished installation for that account, solution, app name, environment and region. Repeat the request with it.
  • While that installation is still running, the same request returns 409 "Solution installation already in progress". Wait and repeat it.
  • If the server running the installation stops, the installation becomes FAILED within about five minutes and the same request resumes it.

You can also send your own installationId in the first request so a retry never depends on reading a response.

Deleting a component's App or environment updates its installation. When the last component is deleted, the installation is removed, so the same name can be installed again. If other components remain, the installation becomes FAILED and repeating the request with its installationId recreates the deleted component.

For an existing completed Warren installation, repeat its account, name, region, environment, provider selection and installation ID with an explicit inputs.warrenImage to request an in-place image upgrade. This updates both the control environment and the app's Warren agent sandbox templates (a new revision each); it preserves credentials, project/run data, resource sizes and network/lifetime policy. Omit warrenImage for a no-op retry. Let current runs finish first. Inspect the returned control environment's deployment status before dispatching another run; request acceptance is not proof that deployment has completed.

Example: Create a Job app​

curl -X POST \
-H 'Authorization: YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"name": "Rails migrations",
"accountId": "5f7b1b7b7b7b7b7b7b7b7b7b",
"dockerPreset": "JOB",
"useImage": true,
"image": "ghcr.io/acme/my-rails-app:2026-06-19",
"jobConfig": {
"command": "bin/rails db:migrate",
"shell": true,
"timeoutSeconds": 1800,
"ttlSecondsAfterFinished": 21600,
"backoffLimit": 0
},
"isCliDeployment": true
}' \
https://api.quave.cloud/api/public/v1/app

Job apps are finite workloads. They do not create hosts or HTTP probes by default. Run them through the Job Runs API. For the full usage guide, see Jobs. For all four creatable types, see App Types.

Get App​

To retrieve an app, send a GET request to the /api/public/v1/app endpoint. You need to provide the appId as a query parameter.

Example:

curl -X GET \
-H 'Authorization: YOUR_TOKEN' \
https://api.quave.cloud/api/public/v1/app?appId=5f7b1b7b7b7b7b7b7b7b7b7b

Example Response:

{
"appId": "5f7b1b7b7b7b7b7b7b7b7b7b",
"name": "My App",
"slug": "my-app",
"gitProvider": "GITHUB",
"gitNamespace": "my-org",
"gitRepo": "my-app",
"gitInstallationId": "12345678",
"dockerPreset": "NODE",
"contextDir": "./",
"customDockerfileContentInUse": false,
"dockerfilePath": "Dockerfile",
"useSSL": true,
"useTCP": false,
"useImage": false,
"port": 3000,
"builder": "DOCKER",
"isCliDeployment": false
}

The response contains various fields describing the app configuration. Below is a description of the fields:

FieldTypeDescription
appIdStringThe app ID.
nameStringThe name of the app.
slugStringThe slug of the app.
gitProviderStringThe Git provider.
gitNamespaceStringThe Git namespace.
gitRepoStringThe Git repository name.
gitInstallationIdStringThe Git installation ID.
dockerPresetStringThe Docker preset.
contextDirStringThe context directory.
customDockerfileContentInUseBooleanWhether to use custom Dockerfile content.
dockerfilePathStringThe path to the Dockerfile.
useSSLBooleanWhether to use SSL.
useTCPBooleanWhether to use TCP.
useImageBooleanWhether to use a Docker image.
portNumberThe port number the app listens on.
builderStringThe builder to use.
isCliDeploymentBooleanWhether this is a CLI deployment.

Update App​

App-to-Function conversion and rollback may change only dockerPreset while preserving the image/source mode and build settings. Function source-mode changes remain restricted. Protected custom-domain conversion requires the operator update described in Function limitations.

Updates app-level configuration including deployment source (build from source vs pre-built image), Docker settings, port, build configuration, and health checks. Changes affect all environments of the app (creates pending changes). Use applyImmediately to deploy immediately.

Endpoint: PATCH /api/public/v1/app

Request Body​

FieldTypeRequiredDescription
appIdStringYesThe ID of the app to update.
dockerfilePathStringNoPath to Dockerfile. Defaults to Dockerfile when changing dockerPreset to CUSTOM and customDockerfileContent is omitted. Cannot be used with customDockerfileContent.
customDockerfileContentStringNoCustom Dockerfile content. Cannot be used with dockerfilePath.
dockerPresetStringNoDocker preset (e.g., CUSTOM, NODE, METEOR, PYTHON).
portNumberNoApplication port (e.g., 3000, 8080).
builderStringNoBuild tool (e.g., DOCKER, NIXPACKS).
contextDirStringNoDocker context directory (e.g., ./).
buildArgsStringNoDocker build arguments.
useImageBooleanNoSwitch deployment source. true deploys a pre-built image; false builds from source using Dockerfile or preset settings.
imageStringNoDocker image URL. Provide useImage: true in the same request when switching an existing source-built app to image deployments.
healthCheckPathStringNoHTTP health check path. Set to empty string to clear.
healthCheckPortNumberNoHealth check port. If not specified, uses the app port.
healthCheckHeadersObjectNoCustom headers for health checks. Set to empty object to clear.
imagePullAccountSecretIdStringNoID of a Container Registry credential for pulling the runtime image. Empty string clears. See Credentials API.
buildPullAccountSecretIdStringNoID of a Container Registry credential for pulling the base image during builds. Empty string clears. See Credentials API.
jobConfigObjectNoJob defaults such as command, timeout, TTL, retry, and concurrency. Only for Job apps.
applyImmediatelyBooleanNoIf true, deploy changes immediately. Default: false.

Example: Switch an image app to build from source​

curl -X PATCH \
-H 'Authorization: YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"appId": "5f7b1b7b7b7b7b7b7b7b7b7b",
"useImage": false,
"dockerPreset": "CUSTOM",
"dockerfilePath": "Dockerfile"
}' \
https://api.quave.cloud/api/public/v1/app

Example: Switch a source-built app to image deployments​

curl -X PATCH \
-H 'Authorization: YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"appId": "5f7b1b7b7b7b7b7b7b7b7b7b",
"useImage": true,
"image": "ghcr.io/acme/my-api:latest"
}' \
https://api.quave.cloud/api/public/v1/app

Example: Update app port​

curl -X PATCH \
-H 'Authorization: YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"appId": "5f7b1b7b7b7b7b7b7b7b7b7b",
"port": 8080,
"applyImmediately": true
}' \
https://api.quave.cloud/api/public/v1/app

Example Response​

{
"appId": "5f7b1b7b7b7b7b7b7b7b7b7b",
"name": "my-api",
"dockerPreset": "NODE",
"port": 8080,
"environmentsAffected": 2
}

Notes​

  • Pending Changes: By default, changes are added to pending changes for each environment. Set applyImmediately=true to deploy immediately.
  • useImage controls whether regular apps deploy a pre-built image or build from source. Set useImage=false with source-build settings such as dockerfilePath to move an app off image deployments.
  • dockerfilePath and customDockerfileContent are mutually exclusive. For CUSTOM source builds, omitted dockerfilePath defaults to Dockerfile.
  • jobConfig can only be set on Job apps. App-level changes create pending deploy changes for the affected Job environments. Default JobRuns keep using the previously applied Job config snapshot until those changes are applied.
  • Environment-level overrides live on App Environments, and per-run overrides are snapshotted into JobRuns.

Delete App​

Deletion first checks Prevent destroy, then stops app-owned sandbox workloads and revokes linked Warren execution credentials. If sandbox termination is still pending or fails, deletion reports a failure and preserves the app/environment for retry; new sandbox allocation remains blocked on an app whose deletion has started. Retry deletion after the runtime finishes stopping. Deleting only a Warren control environment affects its service-principal workloads, not sibling environments or unrelated account apps. Removed parents cannot authenticate historical Warren execution credentials. Revoked principals, terminal sandbox records and immutable revision history remain for audit; they do not authorize new execution.

Allocation ownership is recorded before requesting runtime resources. Deletion stays pending while that request is in flight, even after a worker lease expires. An ambiguous allocation result (for example, a lost connection after submission) remains fenced instead of being redispatched or reported as deleted. If stopping does not converge, contact support for runtime reconciliation; repeatedly retrying deletion does not clear this safety fence. Environment deletion also fences new service-principal work for that environment.

To delete an app, send a DELETE request to the /api/public/v1/app endpoint. You need to provide the appId as a query parameter.

Example:

curl -X DELETE \
-H 'Authorization: YOUR_TOKEN' \
https://api.quave.cloud/api/public/v1/app?appId=5f7b1b7b7b7b7b7b7b7b7b7b

Example Response:

{
"message": "App deleted successfully"
}

Note: Deleting an app requires admin permissions. If any environment in the app has preventDestroy enabled, Quave ONE blocks the app delete because it would also destroy that protected environment. If the app contains automatically provisioned Databases & Services environments, Quave ONE deletes the managed infrastructure resources, including RabbitMQ, while retaining persistent database volumes for the separate PVC cleanup/detach flow.

List Apps​

To list all apps for the authenticated user, send a GET request to the /api/public/v1/apps endpoint.

By default, this endpoint returns apps for the user's current account. You can optionally provide an accountId query parameter to list apps for a specific account.

Example:

# List apps for current account
curl -X GET \
-H 'Authorization: YOUR_TOKEN' \
https://api.quave.cloud/api/public/v1/apps

# List apps for a specific account
curl -X GET \
-H 'Authorization: YOUR_TOKEN' \
https://api.quave.cloud/api/public/v1/apps?accountId=5f7b1b7b7b7b7b7b7b7b7b7b

Example Response:

{
"apps": [
{
"appId": "6a8c2d3e4f5a6b7c8d9e0f1a",
"name": "My Meteor App",
"slug": "my-meteor-app",
"gitProvider": "GITHUB",
"gitNamespace": "quavedev",
"gitRepo": "my-meteor-app",
"dockerPreset": "METEOR",
"template": "METEOR_3",
"createdAt": "2024-01-15T10:30:00.000Z",
"updatedAt": "2024-01-20T14:45:00.000Z",
"isCurrent": true
},
{
"appId": "7b9d3e4f5a6b7c8d9e0f1a2b",
"name": "Node API",
"slug": "node-api",
"gitProvider": "GITHUB",
"gitNamespace": "quavedev",
"gitRepo": "node-api",
"dockerPreset": "NODE",
"createdAt": "2024-01-10T09:15:00.000Z",
"updatedAt": "2024-01-18T11:20:00.000Z",
"isCurrent": true
}
]
}

The response contains an array of apps, where each app has the following fields:

FieldTypeDescription
appIdStringThe app ID.
nameStringThe app name.
slugStringThe app slug.
gitProviderStringThe Git provider (e.g., "GITHUB").
gitNamespaceStringThe Git namespace/organization.
gitRepoStringThe Git repository name.
dockerPresetStringThe Docker preset used (e.g., "METEOR", "NODE", "PYTHON").
templateStringThe template used (optional).
createdAtDateWhen the app was created.
updatedAtDateWhen the app was last updated.
isCurrentBooleanWhether this app belongs to the user's currently selected account.

Query Parameters:

ParameterTypeDescriptionRequired
accountIdStringFilter apps by account ID. If not provided, uses current account.No

Error Responses:

  • 404 - No current account set (when accountId not provided and user has no current account)
  • 401 - User not authenticated

List App Environments​

To list all app environments for the authenticated user, send a GET request to the /api/public/v1/app-envs endpoint.

By default, this endpoint returns app environments for the user's current account. You can optionally filter by accountId or appId.

Example:

# List all app environments for current account
curl -X GET \
-H 'Authorization: YOUR_TOKEN' \
https://api.quave.cloud/api/public/v1/app-envs

# List app environments for a specific account
curl -X GET \
-H 'Authorization: YOUR_TOKEN' \
https://api.quave.cloud/api/public/v1/app-envs?accountId=5f7b1b7b7b7b7b7b7b7b7b7b

# List app environments for a specific app
curl -X GET \
-H 'Authorization: YOUR_TOKEN' \
https://api.quave.cloud/api/public/v1/app-envs?appId=6a8c2d3e4f5a6b7c8d9e0f1a

Example Response:

{
"appEnvs": [
{
"appEnvId": "8c0e4f5a6b7c8d9e0f1a2b3c",
"appId": "6a8c2d3e4f5a6b7c8d9e0f1a",
"name": "Production",
"slug": "production",
"region": "us-east-1",
"gitBranch": "main",
"deploymentName": "my-meteor-app-production",
"cliEnvName": "prod",
"hosts": [
"myapp.example.com",
"www.myapp.example.com"
],
"status": "running",
"resources": {
"containers": 2,
"zClouds": 4,
"cpu": 1000,
"memory": 2048
},
"createdAt": "2024-01-15T10:35:00.000Z",
"updatedAt": "2024-01-20T15:00:00.000Z"
},
{
"appEnvId": "9d1f5a6b7c8d9e0f1a2b3c4d",
"appId": "6a8c2d3e4f5a6b7c8d9e0f1a",
"name": "Beta",
"slug": "beta",
"region": "us-east-1",
"gitBranch": "beta",
"deploymentName": "my-meteor-app-beta",
"cliEnvName": "beta",
"hosts": [
"beta.myapp.example.com"
],
"status": "running",
"resources": {
"containers": 1,
"zClouds": 2,
"cpu": 500,
"memory": 1024
},
"createdAt": "2024-01-15T10:40:00.000Z",
"updatedAt": "2024-01-19T09:30:00.000Z"
}
]
}

The response contains an array of app environments, where each environment has the following fields:

FieldTypeDescription
appEnvIdStringThe app environment ID.
appIdStringThe app ID this environment belongs to.
nameStringThe environment name.
slugStringThe environment slug.
regionStringThe deployment region (e.g., "us-east-1").
gitBranchStringThe Git branch used for this environment.
deploymentNameStringThe Kubernetes deployment name.
cliEnvNameStringThe CLI environment name.
hostsArray<String>List of hostnames/domains for this environment.
statusStringThe current status (e.g., "running", "stopped").
resourcesObjectResource allocation for this environment.
resources.containersNumberNumber of container replicas.
resources.zCloudsNumberzCloud allocation per container.
resources.cpuNumberCPU allocation in zCPU units.
resources.memoryNumberMemory allocation in MB.
createdAtDateWhen the environment was created.
updatedAtDateWhen the environment was last updated.

Security Note: Environment variables (envVars) are not included in this list response for security reasons. To retrieve environment variables for a specific environment, use the GET /app-env endpoint with the decrypt=true query parameter (requires admin permission). See the App Envs API documentation for details.

Query Parameters:

ParameterTypeDescriptionRequired
accountIdStringFilter environments by account ID. If not provided, uses current account.No
appIdStringFilter environments by app ID.No

Error Responses:

  • 404 - No current account set (when accountId not provided and user has no current account)
  • 401 - User not authenticated

Resource Allocation​

The resources object in app environments contains information about the allocated computing resources:

  • containers: The number of container instances (replicas) running for high availability
  • zClouds: Quave ONE's resource unit, representing a standardized allocation of CPU and memory per container
  • cpu: CPU allocation measured in zCPU (Quave ONE CPU units)
  • memory: Memory allocation in megabytes (MB)

These resources determine the performance and scalability of your application environment.

The Warren Solution owner's Personal Codex form can now submit a private coding intent (approved repository, base branch and prompt). The server reserves the existing connection operation and sends a one-time owner grant to its installed Warren control host. Neither the grant nor the private prompt enters browser storage or the shared Warren task metadata. An uncertain create is never repeated; polling recovers only the run ID bound by the original claim. This owner-only Meteor action is not a generic REST/MCP dispatch capability. Live subscription qualification remains required before release.

The same form offers explicit continuation of its last successfully cleaned-up task. The parent receipt must match owner, installation, active principal, connection and private origin, with successful exit and preserved authentication. The frozen base branch is the parent's pushed Warren branch. Shared operators cannot inject a parent, and historical receipts without origin lineage fail closed. The official runner separately verifies the stored Codex thread lineage.

Confirmed deletion of a connection's authentication storage also invalidates its previous continuation receipts before releasing the operation fence. Reconnecting the same installation does not offer deleted Codex threads as resumable tasks.