Deploy an app
Deploy a branch, tag or commit of a git app or a new image reference, redeploy to apply changed settings, and cancel a deployment.
In the dashboard
A deployment runs one version of an app. Deploy to ship a new version: a branch, a tag or a commit of a git app, or an image reference for an image app. Redeploy to run the current version again, which applies settings that only a new deployment picks up. Each deployment goes live only once its replicas are healthy, and the current one serves until then (Deployments). In the dashboard, Deploy… and Redeploy… are in the app's header, and the Deployments tab lists every deployment.
Before you begin
Section titled Before you begin- Open the app from Apps in the dashboard.
- The app must be
active. While it is suspended, Deploy… and Redeploy… are turned off, and the API refuses to deploy it. - For an organization's app, you need the owner or admin role in the organization.
- A push webhook can deploy each push to the app's branch for you (Deploy on every push).
Deploy in the dashboard
Section titled Deploy in the dashboard- Open the app and select Deploy….
- In Branch, tag or commit, type what to deploy (Choose what to deploy). It holds the app's branch at first, such as
main. For an image app, the field is Image reference and holds the app's saved image. - Select Deploy.
A message confirms Deployment started., and the new deployment's page opens (Read a deployment and its build log). When the field is refused, the message under it says why. Any other refusal appears in the dialog under Could not start the deployment.
Choose what to deploy
Section titled Choose what to deployA git app builds the version you name:
- The app's branch
- The default. The build takes the newest commit on the branch when it starts.
- Another branch
- Its name, such as
release. The app keeps its own branch for pushes and redeploys. - A tag
- The full name of the tag, such as
refs/tags/v1.4.0. A bare tag name, such asv1.4.0, is looked for as a branch and the build fails. - A commit
- Through the API only, as
git_sha: its full ID, 40 characters (64 in a repository that uses SHA-256), with or without a branch. A shorter ID is ignored, and the build takes the newest commit on the branch instead. The dashboard's Branch, tag or commit field looks for a commit ID as a branch, so the build fails. We fetch the commit by its ID. If the host does not serve commits that way, we fetch the branch, and the build fails when the branch has moved past that commit.
An image app runs its saved image unless you name another reference, such as ghcr.io/example/web:1.5.0. The reference you name runs for this deployment only, and the app keeps its saved image. To change the image the app keeps, change it on the Settings tab (Change or delete an app).
Redeploy
Section titled RedeployA redeploy runs the image of the deployment that serves the app again, with the app's settings as they are now. It applies changes to the variables the running app reads, the size, the regions and the number of replicas.
A redeploy with a rebuild builds the app's branch again, which applies changes to the repository, the branch, the directory, the access token, the build settings and the variables the build reads. For an image app, it deploys the image the app keeps, so after you change an image app's image, redeploy with a rebuild: a plain redeploy runs the image that is running now. An app that has nothing deployed yet always builds or pulls afresh.
To redeploy in the dashboard:
- Select Redeploy… in the app's header. It is there once a deployment serves the app.
- To rebuild, tick Build the branch again. For an image app, the box is Pull the image again.
- Select Redeploy.
A message confirms Redeploy started., and the new deployment's page opens.
After you save a change that only a new deployment applies, a note under the app's header says so: A redeploy applies the saved changes, A new build applies the saved changes, or for an image app The new image is not running yet. Its Redeploy… button opens the same dialog, with the box ticked when the change needs a rebuild. Through the API, the answer to the change says which one it needs (Change settings through the API).
Cancel a deployment
Section titled Cancel a deploymentYou can cancel a deployment that is still queued, building or deploying. Its build stops, its replicas are removed, and its status becomes canceled. The deployment that serves the app goes on serving. A deployment that has finished cannot be cancelled.
- On the Deployments tab, open the menu at the end of the deployment's row and select Cancel deployment…. On the deployment's own page, Cancel deployment… is in its header.
- Select Cancel deployment to confirm, or Keep it to leave it running.
A message confirms Deployment cancelled., and the deployment shows Cancelled.
Read the deployment history
Section titled Read the deployment historyThe Deployments tab lists the app's deployments, newest first, 20 to a page. Its card says how many there are, such as 14 deployments, newest first.
- Deployment
- The first line of the commit message, or what the deployment was, such as
Redeploy,RollbackorBuild of main. Current marks the one that serves the app. Under it are the short commit and the branch or tag, or the image. A failed deployment also shows why it failed. - Status
- Queued, Building, Deploying, Ready, Failed, Cancelled or Superseded (Status words). While a deployment is on its way, the line under it says what it is doing, such as
Starting replicasorWaiting for a builder. The current deployment's line says how many of its replicas are healthy. - Source
- What started it, such as
Push to main,Deploy of mainorRollback, and who, such asYouorThe push webhook. - Created
- When it was created, and how long it took, such as
Took 3 min 12 s, or45 s so farwhile it is on its way.
Select a row to open the deployment's page. The menu at the end of each row has Open deployment, Roll back to this… for a version you can go back to (Roll back to an earlier deployment), Cancel deployment… for one on its way, and Copy deployment ID. While a deployment is on its way, the first page updates on its own.
Result
Section titled ResultThe new deployment is first on the Deployments tab. It moves to Ready and serves the app once its replicas are healthy in every region, or it ends as Failed or Cancelled and the current deployment keeps serving. Read a deployment and its build log shows how to follow it.
Troubleshooting
Section titled TroubleshootingThe app is suspended; it cannot deploy- We suspended the app. Contact support to find out why.
This app builds from git. Deploy a branch or a commit instead- An image reference was sent for a git app. For an image app, the message says it runs an image.
git could not fetch v1.4.0 from https://github.com/example/web-shop.- The branch does not exist. For a tag, give its full name, such as
refs/tags/v1.4.0. For a commit, deploy it through the API withgit_sha. For a private repository, check that the access token can still read it. release has moved past commit 9f2c1e7b4a6d, and github.com does not serve an older commit by its id. Deploy the branch again.- The host would not send the commit by its ID, and the branch no longer ends at it. Deploy the branch, or push a branch that ends at that commit.
The deployment is ready; only a deployment on its way can be canceled- The deployment has finished. To stop serving it, deploy another version or roll back (Roll back to an earlier deployment).
Too many deployments of this app. Wait a few minutes.- The app started 30 deployments in the last 10 minutes. Wait, then deploy again.
Related
Section titled Related- Read a deployment and its build log
- Roll back to an earlier deployment
- Deploy on every push
- How Apps works
With the API
Section titled With the APIEach request takes the app's uuid. For an organization's app, send the same request under /api/v1/orgs/{org_slug}/apps (organization apps reference).
Deploy through the API
Section titled Deploy through the APIPOST /api/v1/client/apps/{app_uuid}/deployments starts a deployment. An empty body deploys the app's branch or its saved image.
git_ref- For a git app. A branch name, or a full ref such as
refs/tags/v1.4.0. The app's branch when left out. git_sha- For a git app. A commit's full ID.
image_ref- For an image app. The image to run this time. The app's saved image when left out.
curl -X POST https://api.coritan.com/api/v1/client/apps/3c9e2f4a-8b1d-4f6e-a2c7-5d8b9e0f1a21/deployments \
-H "Authorization: Bearer $CORITAN_TOKEN" \
-H "Content-Type: application/json" \
-d '{"git_ref": "refs/tags/v1.4.0"}'
It answers 201 with the new deployment:
{
"deployment": {
"uuid": "0b6f3d2e-7a41-4c59-8e1d-2f9a6b3c4d5e",
"status": "queued",
"source": "git",
"trigger": "manual",
"git_ref": "refs/tags/v1.4.0",
"git_sha": null,
"image_ref": null,
"regions": null,
"error": null,
"is_current": false,
"in_flight": true,
"can_rollback": false,
"replicas": {"healthy": 0, "unhealthy": 0, "starting": 0, "total": 0},
"build": {"uuid": "e2a9c4d1-3b5f-4e7a-9c8d-1f2e3a4b5c6d", "status": "queued", "strategy": null, "attempts": 0},
"created_at": "2026-09-26T10:05:00Z"
}
}
The example leaves some fields out. App and deployment fields describes each one. regions stays null until the deployment starts placing replicas.
| Status | detail |
Cause |
|---|---|---|
409 |
{"error": "source_mismatch", "message": "This app runs an image. Deploy an image reference instead"} |
A branch or commit was sent for an image app, or an image for a git app. |
409 |
{"error": "app_not_active", "message": "The app is suspended; it cannot deploy"} |
The app is suspended. |
422 |
Give a branch or commit, or an image reference, not both |
The body held both. |
422 |
{"error": "repository_invalid", "message": "'release..x' is not a branch name git accepts."} |
git_ref, or the app's repository settings, cannot be fetched. |
503 |
{"error": "registry_not_configured", "message": "Builds are not available on this platform yet."} |
The platform cannot build images at the moment. An image app can still deploy. |
429 |
{"error": "rate_limited", "message": "Too many deployments of this app. Wait a few minutes.", "retry_after_seconds": 600} |
The app started 30 deployments in the last 10 minutes. |
Redeploy through the API
Section titled Redeploy through the APIPOST /api/v1/client/apps/{app_uuid}/redeploy runs the current version again. Send {"rebuild": true} to build the branch again, or for an image app to deploy its saved image. The body can be left out.
curl -X POST https://api.coritan.com/api/v1/client/apps/3c9e2f4a-8b1d-4f6e-a2c7-5d8b9e0f1a21/redeploy \
-H "Authorization: Bearer $CORITAN_TOKEN" \
-H "Content-Type: application/json" \
-d '{"rebuild": false}'
It answers 201 with the new deployment, as above. A redeploy that reuses the image has source redeploy and starts as deploying. It refuses a suspended app and counts towards the same limit of 30 deployments in 10 minutes.
Cancel through the API
Section titled Cancel through the APIPOST /api/v1/client/apps/{app_uuid}/deployments/{deployment_uuid}/cancel cancels a deployment on its way, and answers with it, now canceled, and its replicas:
curl -X POST https://api.coritan.com/api/v1/client/apps/3c9e2f4a-8b1d-4f6e-a2c7-5d8b9e0f1a21/deployments/0b6f3d2e-7a41-4c59-8e1d-2f9a6b3c4d5e/cancel \
-H "Authorization: Bearer $CORITAN_TOKEN"
A deployment that has finished answers 409 with The deployment is ready; only a deployment on its way can be canceled, naming its status. One that belongs to another app answers 404 with Deployment not found.
List deployments
Section titled List deploymentsGET /api/v1/client/apps/{app_uuid}/deployments lists the app's deployments, newest first:
curl "https://api.coritan.com/api/v1/client/apps/3c9e2f4a-8b1d-4f6e-a2c7-5d8b9e0f1a21/deployments?limit=20&offset=0" \
-H "Authorization: Bearer $CORITAN_TOKEN"
{
"deployments": [
{"uuid": "0b6f3d2e-7a41-4c59-8e1d-2f9a6b3c4d5e", "status": "ready", "source": "git", "trigger": "manual", "is_current": true},
{"uuid": "8c4e1a7d-2f9b-4d6e-b3a8-6e1f9c2d5a10", "status": "superseded", "source": "git", "trigger": "push", "is_current": false}
],
"total": 14,
"limit": 20,
"offset": 0
}
limit takes 1–100 (20 when left out), offset skips that many deployments, and total counts them all. Each deployment carries every field, shortened here.
API operations on this page
| Method | Path | What it does |
|---|---|---|
GET | /api/v1/client/apps/{app_uuid}/deployments | List an app's deployments, newest first, a page at a time |
POST | /api/v1/client/apps/{app_uuid}/deployments | Create app deployment |
POST | /api/v1/client/apps/{app_uuid}/deployments/{deployment_uuid}/cancel | Cancel a deployment that is still queued, building or deploying |
POST | /api/v1/client/apps/{app_uuid}/redeploy | Redeploy app |
GET | /api/v1/orgs/{org_slug}/apps/{app_uuid}/deployments | List an app's deployments, newest first, a page at a time |
POST | /api/v1/orgs/{org_slug}/apps/{app_uuid}/deployments | Create app deployment |
POST | /api/v1/orgs/{org_slug}/apps/{app_uuid}/deployments/{deployment_uuid}/cancel | Cancel a deployment that is still queued, building or deploying |
POST | /api/v1/orgs/{org_slug}/apps/{app_uuid}/redeploy | Redeploy app |