Skip to content

Apps API

Container App Platform. Deploy and manage container apps with scaling controls, scale-to-zero, persistent storage, and HTTPS with automated certificate management.

Endpoints

MethodPathDescription
GET/v1/apps/plansList app plans
GET/v1/apps/regionsList app regions
GET/v1/appsList apps
POST/v1/appsCreate app
GET/v1/apps/{app_id}Get app
PATCH/v1/apps/{app_id}Update app
DELETE/v1/apps/{app_id}Delete app
POST/v1/apps/{app_id}/deploy/imageDeploy from image
POST/v1/apps/{app_id}/startStart app
POST/v1/apps/{app_id}/stopStop app
POST/v1/apps/{app_id}/restartRestart app
GET/v1/apps/{app_id}/logsGet app logs

GET /v1/apps/plans

List app plans

Get available App Platform plans with CPU, memory, storage, and pricing information.

Response example:

json
[
  {
    "id": "app-starter",
    "name": "Starter",
    "description": "For small production workloads",
    "cpu_cores": 1.0,
    "memory_mb": 1024,
    "disk_gb": 10,
    "max_instances": 2,
    "max_apps_per_customer": 5,
    "max_custom_domains": 3,
    "bandwidth_gb_included": 100,
    "price_monthly": 99.0,
    "hourly_rate": 0.15,
    "currency": "NOK",
    "features": {}
  }
]

Example:

bash
curl https://api.wayscloud.services/v1/apps/plans \
  -H "X-API-Key: wayscloud_api_abc12_YOUR_SECRET"

Response:

json
[
  {
    "id": "app-starter",
    "name": "Starter",
    "description": "For small production workloads",
    "cpu_cores": 1.0,
    "memory_mb": 1024,
    "disk_gb": 10,
    "max_instances": 2,
    "max_apps_per_customer": 5,
    "max_custom_domains": 3,
    "bandwidth_gb_included": 100,
    "price_monthly": 99.0,
    "hourly_rate": 0.15,
    "currency": "NOK",
    "features": {}
  }
]

GET /v1/apps/regions

List app regions

Get available regions for App Platform with availability status.

Response example:

json
[
  {
    "code": "no",
    "name": "Norge",
    "country_code": "NO",
    "app_platform_available": true
  }
]

Example:

bash
curl https://api.wayscloud.services/v1/apps/regions \
  -H "X-API-Key: wayscloud_api_abc12_YOUR_SECRET"

Response:

json
[
  {
    "code": "no",
    "name": "Norge",
    "country_code": "NO",
    "app_platform_available": true
  }
]

GET /v1/apps

List apps

Get a paginated list of all apps for the authenticated account.

Response:

FieldTypeDescription
appsarray
totalinteger
pageinteger
page_sizeinteger

Example:

bash
curl https://api.wayscloud.services/v1/apps \
  -H "X-API-Key: wayscloud_api_abc12_YOUR_SECRET"

Response:

json
{
  "apps": [
    {
      "id": "app_01jxr4m8k2w9n5v3q7b6t1y0z",
      "name": "invoice-api-prod",
      "slug": "invoice-api-prod",
      "short_id": "q7b6t1y0",
      "region": "no",
      "plan_id": "app-starter",
      "plan_name": "Starter",
      "status": "running",
      "default_url": "invoice-api-prod-q7b6t1y0.apps.wayscloud.services",
      "instance_count": 1,
      "running_instances": 1,
      "max_instances": 2,
      "domain_count": 0,
      "scale_to_zero_enabled": false,
      "is_scaled_to_zero": false,
      "created_at": "2026-03-15T09:30:00Z",
      "last_deployed_at": "2026-04-10T14:22:00Z",
      "plan_max_apps": 5,
      "plan_max_domains": 3
    }
  ],
  "total": 1,
  "page": 1,
  "page_size": 20
}

POST /v1/apps

Create app

Create a new container app. Only name is required — all other fields have sensible defaults.

Request Body:

FieldTypeDescription
namestringRequired. Display name for the app
slugstringURL slug. Auto-generated from name if omitted. Lowercase letters, numbers, and hyphens only.
regionstringRegion code (from GET /v1/apps/regions)
planstringPlan ID (from GET /v1/apps/plans). Uses account default if omitted.
portintegerPort the app listens on
health_check_pathstringHealth check endpoint path
env_varsobjectEnvironment variables as key-value pairs

Response:

FieldTypeDescription
idstring
namestring
slugstring
short_idstring
regionstring
plan_idstring
plan_namestring
statusstringValues: creating, building, deploying, running, stopped, stopping, error, failed, deleting
status_messagestring
default_urlstring
portinteger
health_check_pathstring
min_instancesinteger
max_instancesinteger
scale_to_zero_enabledboolean
idle_timeout_minutesinteger
is_scaled_to_zeroboolean
active_revision_idstring
active_deployment_idstring
last_deployed_atstring
active_imagestringCurrently deployed container image URI
created_atstring
updated_atstring
volumeobjectPersistent volume metadata. Null if no volume attached.

Example:

bash
curl -X POST https://api.wayscloud.services/v1/apps \
  -H "X-API-Key: wayscloud_api_abc12_YOUR_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "invoice-api-prod",
  "region": "no",
  "plan": "app-starter",
  "port": 3000,
  "env_vars": {
    "NODE_ENV": "production"
  }
}'

Response:

json
{
  "id": "app_01jxr4m8k2w9n5v3q7b6t1y0z",
  "name": "invoice-api-prod",
  "slug": "invoice-api-prod",
  "short_id": "q7b6t1y0",
  "region": "no",
  "plan_id": "app-starter",
  "plan_name": "Starter",
  "status": "running",
  "status_message": null,
  "default_url": "invoice-api-prod-q7b6t1y0.apps.wayscloud.services",
  "port": 3000,
  "health_check_path": "/health",
  "min_instances": 1,
  "max_instances": 2,
  "scale_to_zero_enabled": false,
  "idle_timeout_minutes": 15,
  "is_scaled_to_zero": false,
  "active_revision_id": "rev_01jxr5n4p8m2w7k3q9b6t0y1z",
  "active_deployment_id": "dep_01jxr5n4p8m2w7k3q9b6t0y1z",
  "last_deployed_at": "2026-04-10T14:22:00Z",
  "active_image": "ghcr.io/acme-corp/invoice-api:v2.4.1",
  "created_at": "2026-03-15T09:30:00Z",
  "updated_at": "2026-04-10T14:22:00Z",
  "volume": null
}

GET /v1/apps/

Get app

Get full details of a specific app including configuration, deployment status, and scaling settings.

Response:

FieldTypeDescription
idstring
namestring
slugstring
short_idstring
regionstring
plan_idstring
plan_namestring
statusstringValues: creating, building, deploying, running, stopped, stopping, error, failed, deleting
status_messagestring
default_urlstring
portinteger
health_check_pathstring
min_instancesinteger
max_instancesinteger
scale_to_zero_enabledboolean
idle_timeout_minutesinteger
is_scaled_to_zeroboolean
active_revision_idstring
active_deployment_idstring
last_deployed_atstring
active_imagestringCurrently deployed container image URI
created_atstring
updated_atstring
volumeobjectPersistent volume metadata. Null if no volume attached.

Example:

bash
curl https://api.wayscloud.services/v1/apps/{app_id} \
  -H "X-API-Key: wayscloud_api_abc12_YOUR_SECRET"

Response:

json
{
  "id": "app_01jxr4m8k2w9n5v3q7b6t1y0z",
  "name": "invoice-api-prod",
  "slug": "invoice-api-prod",
  "short_id": "q7b6t1y0",
  "region": "no",
  "plan_id": "app-starter",
  "plan_name": "Starter",
  "status": "running",
  "status_message": null,
  "default_url": "invoice-api-prod-q7b6t1y0.apps.wayscloud.services",
  "port": 3000,
  "health_check_path": "/health",
  "min_instances": 1,
  "max_instances": 2,
  "scale_to_zero_enabled": false,
  "idle_timeout_minutes": 15,
  "is_scaled_to_zero": false,
  "active_revision_id": "rev_01jxr5n4p8m2w7k3q9b6t0y1z",
  "active_deployment_id": "dep_01jxr5n4p8m2w7k3q9b6t0y1z",
  "last_deployed_at": "2026-04-10T14:22:00Z",
  "active_image": "ghcr.io/acme-corp/invoice-api:v2.4.1",
  "created_at": "2026-03-15T09:30:00Z",
  "updated_at": "2026-04-10T14:22:00Z",
  "volume": null
}

PATCH /v1/apps/

Update app

Update app configuration. All fields are optional — only provided fields are updated.

Mutable fields: name, port, health_check_path, min_instances, max_instances, env_vars, scale_to_zero_enabled, idle_timeout_minutes

Not mutable: plan, region, slug cannot be changed after creation.

Warning: Providing env_vars replaces the entire environment variable set for the app. To add a single variable, first GET the current app, merge your changes, then PATCH with the full set.

Request Body:

FieldTypeDescription
namestring
portinteger
health_check_pathstring
min_instancesintegerMinimum instances. Set to 0 to allow scale-to-zero.
max_instancesinteger
env_varsobjectReplaces the entire environment variable set. Not a merge — omitted variables are removed.
scale_to_zero_enabledbooleanEnable scale-to-zero when app is idle
idle_timeout_minutesintegerMinutes of inactivity before scaling to zero

Response:

FieldTypeDescription
idstring
namestring
slugstring
short_idstring
regionstring
plan_idstring
plan_namestring
statusstringValues: creating, building, deploying, running, stopped, stopping, error, failed, deleting
status_messagestring
default_urlstring
portinteger
health_check_pathstring
min_instancesinteger
max_instancesinteger
scale_to_zero_enabledboolean
idle_timeout_minutesinteger
is_scaled_to_zeroboolean
active_revision_idstring
active_deployment_idstring
last_deployed_atstring
active_imagestringCurrently deployed container image URI
created_atstring
updated_atstring
volumeobjectPersistent volume metadata. Null if no volume attached.

Example:

bash
curl -X PATCH https://api.wayscloud.services/v1/apps/{app_id} \
  -H "X-API-Key: wayscloud_api_abc12_YOUR_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
  "port": 3000,
  "min_instances": 1,
  "max_instances": 3,
  "env_vars": {
    "NODE_ENV": "production",
    "LOG_LEVEL": "info"
  }
}'

Response:

json
{
  "id": "app_01jxr4m8k2w9n5v3q7b6t1y0z",
  "name": "invoice-api-prod",
  "slug": "invoice-api-prod",
  "short_id": "q7b6t1y0",
  "region": "no",
  "plan_id": "app-starter",
  "plan_name": "Starter",
  "status": "running",
  "status_message": null,
  "default_url": "invoice-api-prod-q7b6t1y0.apps.wayscloud.services",
  "port": 3000,
  "health_check_path": "/health",
  "min_instances": 1,
  "max_instances": 2,
  "scale_to_zero_enabled": false,
  "idle_timeout_minutes": 15,
  "is_scaled_to_zero": false,
  "active_revision_id": "rev_01jxr5n4p8m2w7k3q9b6t0y1z",
  "active_deployment_id": "dep_01jxr5n4p8m2w7k3q9b6t0y1z",
  "last_deployed_at": "2026-04-10T14:22:00Z",
  "active_image": "ghcr.io/acme-corp/invoice-api:v2.4.1",
  "created_at": "2026-03-15T09:30:00Z",
  "updated_at": "2026-04-10T14:22:00Z",
  "volume": null
}

DELETE /v1/apps/

Delete app

Soft-delete an app. The app is marked as deleted and permanent cleanup happens asynchronously according to platform retention policies.

Response:

FieldTypeDescription
successboolean
messagestring

Example:

bash
curl -X DELETE https://api.wayscloud.services/v1/apps/{app_id} \
  -H "X-API-Key: wayscloud_api_abc12_YOUR_SECRET"

Response:

json
{
  "success": true,
  "message": "App started"
}

POST /v1/apps/{app_id}/deploy/image

Deploy from image

Deploy the app from a container image. The deployment is asynchronous — poll GET /v1/apps/{app_id} for status updates.

Supported registries include: registry.wayscloud.services/, ghcr.io/, docker.io/, and Docker Hub shorthand (e.g. nginx:latest, traefik/whoami).

Request Body:

FieldTypeDescription
image_uristringRequired. Container image URI

Response:

FieldTypeDescription
app_idstring
revision_idstring
deployment_idstring
statusstringInitial deployment status (pending)
messagestring
preflight_warningsarrayWarnings from pre-deploy checks

Example:

bash
curl -X POST https://api.wayscloud.services/v1/apps/{app_id}/deploy/image \
  -H "X-API-Key: wayscloud_api_abc12_YOUR_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
  "image_uri": "ghcr.io/acme-corp/invoice-api:v2.4.1"
}'

Response:

json
{
  "app_id": "app_01jxr4m8k2w9n5v3q7b6t1y0z",
  "revision_id": "rev_01jxr6a2b3c4d5e6f7g8h9i0j",
  "deployment_id": "dep_01jxr6a2b3c4d5e6f7g8h9i0j",
  "status": "pending",
  "message": "Deployment started for image ghcr.io/acme-corp/invoice-api:v2.4.1",
  "preflight_warnings": []
}

POST /v1/apps/{app_id}/start

Start app

Start a stopped app or wake it from scale-to-zero state.

Response:

FieldTypeDescription
successboolean
messagestring

Example:

bash
curl -X POST https://api.wayscloud.services/v1/apps/{app_id}/start \
  -H "X-API-Key: wayscloud_api_abc12_YOUR_SECRET"

Response:

json
{
  "success": true,
  "message": "App started"
}

POST /v1/apps/{app_id}/stop

Stop app

Stop all running instances. The app can be restarted later.

Response:

FieldTypeDescription
successboolean
messagestring

Example:

bash
curl -X POST https://api.wayscloud.services/v1/apps/{app_id}/stop \
  -H "X-API-Key: wayscloud_api_abc12_YOUR_SECRET"

Response:

json
{
  "success": true,
  "message": "App started"
}

POST /v1/apps/{app_id}/restart

Restart app

Restart the app by recreating running instances.

Response:

FieldTypeDescription
successboolean
messagestring

Example:

bash
curl -X POST https://api.wayscloud.services/v1/apps/{app_id}/restart \
  -H "X-API-Key: wayscloud_api_abc12_YOUR_SECRET"

Response:

json
{
  "success": true,
  "message": "App started"
}

GET /v1/apps/{app_id}/logs

Get app logs

Returns the most recent container log output (stdout/stderr). This is live container output, not a historical log archive. Logs may be empty for stopped or idle apps. For persistent logging, configure your app to ship logs to an external service.

Response:

FieldTypeDescription
app_idstring
instance_idstring
logsarrayLog entries from container output
has_morebooleanTrue if more log lines are available beyond the requested limit

Example:

bash
curl https://api.wayscloud.services/v1/apps/{app_id}/logs \
  -H "X-API-Key: wayscloud_api_abc12_YOUR_SECRET"

Response:

json
{
  "app_id": "app_01jxr4m8k2w9n5v3q7b6t1y0z",
  "instance_id": null,
  "logs": [
    {
      "timestamp": "2026-04-12T14:22:01Z",
      "message": "Server listening on port 3000",
      "stream": "stdout"
    },
    {
      "timestamp": "2026-04-12T14:22:03Z",
      "message": "Connected to database",
      "stream": "stdout"
    }
  ],
  "has_more": false
}