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:
| Field | Type | Description |
|---|---|---|
name | String | The name of the app. |
accountId | String | The ID of the account to create the app in. |
port | Number | The port number the app listens on. Required for non-Job apps. |
Optional fields:
| Field | Type | Description |
|---|---|---|
dockerPreset | String | The 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. |
dockerPresetVersion | String | The version for the chosen Docker preset (optional). For example: METEOR_JS_3_5, NEXT_JS_NODE_JS_22, EXPRESS_NODE_JS_20, etc. |
useImage | Boolean | Whether to use a Docker image. |
gitNamespace | String | The Git namespace (required for GitHub deployments). |
gitRepo | String | The Git repository name (required for GitHub deployments). |
gitInstallationId | String | The Git installation ID (required for GitHub deployments). |
image | String | The Docker image to use (if useImage is true). |
buildArgs | String | Docker build arguments. |
contextDir | String | The context directory for the Docker build (default is "./"). |
dockerfilePath | String | The path to the Dockerfile. Defaults to Dockerfile when dockerPreset is CUSTOM and customDockerfileContent is omitted. |
customDockerfileContent | String | The custom Dockerfile content. |
isCliDeployment | Boolean | Whether this is a CLI deployment. |
jobConfig | Object | Job 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. 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.
Personal Codex installation mode
For Warren, inputs.warrenAuthenticationMode accepts API_KEY (the default for
new and legacy installations) or PERSONAL_CODEX. Personal mode does not require
llmProviderKeyId, warrenPrimaryModel, or warrenSecondaryModel, and does not
resolve or deploy an AI Provider Key. The GitHub credential, Sandbox entitlement,
region and immutable runtime checks still apply. Normal infrastructure charges
are unchanged.
Personal mode requires the signed-in installation owner to be a current account administrator, without internal-operator bypass. Resume with the original mode and owner. Connect, check, disconnect and recover the personal sign-in in the Warren section of Solutions; OAuth files are never returned by this API. An installation or successful sign-in does not itself grant a shared Warren operator token permission to dispatch against that subscription: managed personal run execution remains gated on its separate owner-bound runtime integration.
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.
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 service principal's approved sandbox image revisions;
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:
| Field | Type | Description |
|---|---|---|
appId | String | The app ID. |
name | String | The name of the app. |
slug | String | The slug of the app. |
gitProvider | String | The Git provider. |
gitNamespace | String | The Git namespace. |
gitRepo | String | The Git repository name. |
gitInstallationId | String | The Git installation ID. |
dockerPreset | String | The Docker preset. |
contextDir | String | The context directory. |
customDockerfileContentInUse | Boolean | Whether to use custom Dockerfile content. |
dockerfilePath | String | The path to the Dockerfile. |
useSSL | Boolean | Whether to use SSL. |
useTCP | Boolean | Whether to use TCP. |
useImage | Boolean | Whether to use a Docker image. |
port | Number | The port number the app listens on. |
builder | String | The builder to use. |
isCliDeployment | Boolean | Whether 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
| Field | Type | Required | Description |
|---|---|---|---|
appId | String | Yes | The ID of the app to update. |
dockerfilePath | String | No | Path to Dockerfile. Defaults to Dockerfile when changing dockerPreset to CUSTOM and customDockerfileContent is omitted. Cannot be used with customDockerfileContent. |
customDockerfileContent | String | No | Custom Dockerfile content. Cannot be used with dockerfilePath. |
dockerPreset | String | No | Docker preset (e.g., CUSTOM, NODE, METEOR, PYTHON). |
port | Number | No | Application port (e.g., 3000, 8080). |
builder | String | No | Build tool (e.g., DOCKER, NIXPACKS). |
contextDir | String | No | Docker context directory (e.g., ./). |
buildArgs | String | No | Docker build arguments. |
useImage | Boolean | No | Switch deployment source. true deploys a pre-built image; false builds from source using Dockerfile or preset settings. |
image | String | No | Docker image URL. Provide useImage: true in the same request when switching an existing source-built app to image deployments. |
healthCheckPath | String | No | HTTP health check path. Set to empty string to clear. |
healthCheckPort | Number | No | Health check port. If not specified, uses the app port. |
healthCheckHeaders | Object | No | Custom headers for health checks. Set to empty object to clear. |
imagePullAccountSecretId | String | No | ID of a Container Registry credential for pulling the runtime image. Empty string clears. See Credentials API. |
buildPullAccountSecretId | String | No | ID of a Container Registry credential for pulling the base image during builds. Empty string clears. See Credentials API. |
jobConfig | Object | No | Job defaults such as command, timeout, TTL, retry, and concurrency. Only for Job apps. |
applyImmediately | Boolean | No | If 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=trueto deploy immediately. useImagecontrols whether regular apps deploy a pre-built image or build from source. SetuseImage=falsewith source-build settings such asdockerfilePathto move an app off image deployments.dockerfilePathandcustomDockerfileContentare mutually exclusive. ForCUSTOMsource builds, omitteddockerfilePathdefaults toDockerfile.jobConfigcan 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:
| Field | Type | Description |
|---|---|---|
appId | String | The app ID. |
name | String | The app name. |
slug | String | The app slug. |
gitProvider | String | The Git provider (e.g., "GITHUB"). |
gitNamespace | String | The Git namespace/organization. |
gitRepo | String | The Git repository name. |
dockerPreset | String | The Docker preset used (e.g., "METEOR", "NODE", "PYTHON"). |
template | String | The template used (optional). |
createdAt | Date | When the app was created. |
updatedAt | Date | When the app was last updated. |
isCurrent | Boolean | Whether this app belongs to the user's currently selected account. |
Query Parameters:
| Parameter | Type | Description | Required |
|---|---|---|---|
accountId | String | Filter 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:
| Field | Type | Description |
|---|---|---|
appEnvId | String | The app environment ID. |
appId | String | The app ID this environment belongs to. |
name | String | The environment name. |
slug | String | The environment slug. |
region | String | The deployment region (e.g., "us-east-1"). |
gitBranch | String | The Git branch used for this environment. |
deploymentName | String | The Kubernetes deployment name. |
cliEnvName | String | The CLI environment name. |
hosts | Array<String> | List of hostnames/domains for this environment. |
status | String | The current status (e.g., "running", "stopped"). |
resources | Object | Resource allocation for this environment. |
resources.containers | Number | Number of container replicas. |
resources.zClouds | Number | zCloud allocation per container. |
resources.cpu | Number | CPU allocation in zCPU units. |
resources.memory | Number | Memory allocation in MB. |
createdAt | Date | When the environment was created. |
updatedAt | Date | When 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 theGET /app-envendpoint with thedecrypt=truequery parameter (requires admin permission). See the App Envs API documentation for details.
Query Parameters:
| Parameter | Type | Description | Required |
|---|---|---|---|
accountId | String | Filter environments by account ID. If not provided, uses current account. | No |
appId | String | Filter 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.