---
title: "Update app service"
method: PATCH
path: "/api/v1/apps/services/{service_id}"
tags: ["Raff Apps"]
---

# Update app service

`PATCH /api/v1/apps/services/{service_id}`

## Request

- Base URL: `https://api.rafftechnologies.com`
- URL: `https://api.rafftechnologies.com/api/v1/apps/services/{service_id}`
- Auth: API key in header `X-API-Key`

Change an app's settings. Fields you leave out stay as they are. A
change to how a live app runs (size, start command, port, health
check, schedule) rolls out as a new deployment of the current image,
and a change to a failed app deploys it. A paused app keeps the change
and applies it when resumed. Scaling has its own endpoint.

## Path parameters

- `service_id` string, required

## Request body

- UpdateAppServiceRequest: Every field is optional. Leave a field out to keep it.
  - `name` string: Display name (the address does not change)
  - `description` string: Send "" to clear it
  - `tier_id` integer: New size (see `GET /api/v1/apps/tiers`). Apps on a subscription change size through support for now.
  - `start_command` string
  - `http_port` integer: Web and private apps only
  - `health_check_path` string: Must start with `/`
  - `cron_schedule` string: Cron apps only
  - `cron_timezone` string
  - `cron_concurrency` 'forbid' | 'allow' | 'replace'
  - `repo_branch` string: GitHub apps only
  - `repo_root_dir` string
  - `dockerfile_path` string
  - `previews_enabled` boolean: Pull request previews (web apps from GitHub)
  - `redeploy` boolean: Deploy now even when the change alone would not

## Response `200`

App updated. `deployment_id` is set when a deployment started.

- object
  - `success` boolean
  - `service` AppService: An app service on the Raff PaaS — a web service, private service, worker, cron job, or one-off job.
    - `id` string, uuid
    - `service_id` string: Short reference id used in URLs
    - `project_id` string, uuid
    - `name` string: Display name, unique within the project
    - `slug` string: URL label — the name plus a short random suffix
    - `description` string
    - `service_type` 'web' | 'private' | 'worker' | 'cron' | 'job'
    - `source_type` 'git' | 'image' | 'template' | 'compose'
    - `builder` 'buildpacks' | 'dockerfile' | 'image'
    - `repo_full_name` string: GitHub source only (owner/name)
    - `repo_branch` string
    - `repo_root_dir` string
    - `dockerfile_path` string
    - `image_ref` string: Prebuilt image source only
    - `start_command` string
    - `tier_id` integer: Pricing tier ID (see `GET /api/v1/apps/tiers`)
    - `tier_name` string
    - `replicas` integer
    - `autoscaling_enabled` boolean
    - `min_replicas` integer
    - `max_replicas` integer
    - `autoscaling_metric` string
    - `autoscaling_target` integer
    - `scale_to_zero` boolean
    - `http_port` integer
    - `health_check_path` string
    - `cron_schedule` string: Cron services only
    - `cron_timezone` string
    - `cron_concurrency` 'forbid' | 'allow' | 'replace': Cron services only. What happens when a run is due while the last one still runs.
    - `region` string
    - `url` string: Public HTTPS endpoint (web services; automatic TLS)
    - `internal_host` string: In-cluster hostname (private services); reach it on `http_port`
    - `primary_domain` string: The first verified custom domain, if any
    - `status` 'pending' | 'building' | 'deploying' | 'live' | 'paused' | 'suspended' | 'error' | 'deleting' | 'deleted'
    - `status_message` string: When status is error, what went wrong, in plain words.
    - `paused_by_cap` boolean: True when a spend cap paused the service
    - `billing_type` 'payg' | 'subscription'
    - `previews_enabled` boolean: Pull request previews are on (web apps from GitHub)
    - `preview_count` integer
    - `max_previews` integer: Previews this app's size allows
    - `waiting_for_database` boolean: Created with `link_database_id`; the app deploys once the database runs and is linked
    - `github_status` '' | 'disconnected' | 'suspended' | 'no_repo_access' | 'repo_not_found': Empty when Raff can reach the app's repository; otherwise why not (reconnect GitHub in the dashboard)
    - `github_login` string
    - `github_settings_url` string
    - `current_deployment_id` string: Empty until a deployment goes live
    - `current_deployment_number` integer
    - `created_at` string, date-time
    - `updated_at` string, date-time
  - `deployment_id` string, uuid

## Other responses

- `400`: Invalid request parameters
- `401`: Authentication required
- `404`: Resource not found
- `409`: Conflicts with what exists, for example a name already in use

## Changes

- **2026-10-19** `e80a4b1b5024`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/rafftechnologies/apis/raff-api/changes/api/v1/apps/services/:service_id/patch.md)

---

[API](https://skmtc.dev/rafftechnologies/apis/raff-api.md) - [All operations](https://skmtc.dev/rafftechnologies/apis/raff-api/llms.txt) - [OpenAPI document](https://skmtc.dev/rafftechnologies/apis/raff-api/revisions/3d30cde0acb4?raw)
