# Apps

> Run a web app from a git repository or a container image, as replicas in the regions you choose, behind your own domains.

Source: https://www.coritan.com/docs/apps/

In the dashboard:

- /dashboard/apps: https://www.coritan.com/dashboard/apps

Apps runs a web service from its source. Point an app at a git repository and we build an image from the commit you deploy, or give it a container image that is already built. Each deployment runs as *replicas*, identical copies of the app, in the regions you choose, and visitors reach them through the app's domains.

Use it for a website, an API or any other service that answers HTTP and keeps its data somewhere else, such as a database or [Object Storage](/docs/object-storage/). A replica keeps nothing on its disk from one deployment to the next.

## What an app includes

- A *source*: a git repository and branch, or a container image. You choose it when you create the app, and it cannot change later.
- For a git app, settings for the build: the directory in the repository, a Dockerfile or the commands to install, build and start.
- A *size*, which sets the memory, CPU and disk of each replica.
- The regions it runs in, and how many replicas run in each.
- Environment variables, each for the build, the running app or both.
- A *platform name*, `<name>.<app domain>`, and up to 20 custom domains, each with a certificate.
- For a git app, a push webhook that deploys each push to the app's branch.
- A history of deployments. You can roll back to any of them that went live.

[How Apps works](/docs/apps/how-apps-work/) explains how these fit together.

## What you can do

Set up an app:

- [Create an app](/docs/apps/create-an-app/) from a repository or an image
- [Set environment variables](/docs/apps/environment-variables/) for the build and the running app
- [Add a custom domain](/docs/apps/custom-domains/) and verify it with a TXT record
- [Deploy on every push](/docs/apps/push-webhook/) with the push webhook

Ship and run it:

- [Deploy an app](/docs/apps/deploy-an-app/): a branch, a commit or an image, a redeploy, or cancelling a deployment
- [Read a deployment and its build log](/docs/apps/read-a-deployment/)
- [Roll back to an earlier deployment](/docs/apps/roll-back-a-deployment/)
- [Change or delete an app](/docs/apps/app-settings/)

Look things up and fix problems:

- [App and deployment fields](/docs/apps/fields/)
- [Apps limits](/docs/apps/limits/)
- [Troubleshoot Apps](/docs/apps/troubleshooting/)

## Find your apps in the dashboard

Select **Apps** under **Products** in the sidebar to open [the list of your apps](https://www.coritan.com/dashboard/apps). Its header shows how many apps you have out of your limit, such as `3 of 20 apps`, and **New app…** creates one ([Create an app](/docs/apps/create-an-app/)). Each row shows:

**App**
: The app's name, and its platform address or `No platform address yet`.

**Status**
: **Live** while a deployment serves the app, with how many of its replicas are healthy, such as `3 of 4 replicas healthy`. **Not live** when nothing serves it, which includes an app whose first build is on its way. **Suspended** when we have suspended it.

**Regions**
: Its regions, or `Every region`, and how many replicas run in each.

**Last deployment**
: The deployment that serves the app: its commit message, or what started it, with its short commit and when it was created. `Nothing live yet` when no deployment serves it.

The search box finds apps by name, name on the platform, address, repository or image. The filters **All**, **Live**, **Not live** and **Suspended** show how many apps each one holds. The button at the end of a live app's row opens its address in a new tab.

Select a row to open the app. Its header shows the app's state, its address with a copy button, its regions and replicas, and where its code comes from, such as `example/web-shop on main`. On this page the state can also be a deployment on its way, such as **Building**, or **Failed** when nothing is live and the newest deployment failed, or **Not deployed**. **Deploy…** and **Redeploy…** start a deployment ([Deploy an app](/docs/apps/deploy-an-app/)), and the menu beside them has **Open app**, **Copy address** and **Copy app ID**. Four tabs hold the rest:

**Deployments**
: The app's deployments, newest first, and each one's own page ([Read a deployment and its build log](/docs/apps/read-a-deployment/)).

**Domains**
: The platform address and the custom domains ([Add a custom domain](/docs/apps/custom-domains/)).

**Environment**
: The environment variables ([Set environment variables](/docs/apps/environment-variables/)).

**Settings**
: The app's settings, its push webhook, and deleting it ([Change or delete an app](/docs/apps/app-settings/)).

## How Apps is billed

An app is not a service on your account. It has no plan, it does not appear on an invoice, and it does not use your credit. [Billing](/docs/billing/) covers the services that are billed.

## Limits and availability

- Apps can be turned off for the whole platform. While it is off, the sidebar has no **Apps**, the Apps pages show `Page not found`, and every Apps request answers `404` with `{"detail": "Not Found"}`, whoever sends it.
- Visitors reach an app only through its domains. A replica has no public address of its own.
- Each region runs the number of replicas you set. The number does not grow or shrink with traffic.
- A new deployment starts on new replicas, so files an app writes to its disk do not carry over.
- You can read a deployment's build log. What the app writes while it runs is not shown.
- Your account and each organization can have a set number of apps. The **Apps** list shows the limit and how many you have, and so does `GET /api/v1/client/apps/regions`.

[Apps limits](/docs/apps/limits/) lists every limit.

## Apps for an organization

An organization can own apps too. Its apps use the same requests under `/api/v1/orgs/{org_slug}/apps`, with the same bodies, answers and errors as your own apps under `/api/v1/client/apps`. Any member of the organization can read them. Only an owner or an admin can create, change, deploy or delete one, and any other member gets `403` with `Admin access required`. [Organization roles and permissions](/docs/organizations/roles-and-permissions/) describes the roles.

Deleting an organization's app also needs the app's name typed to confirm it. From a staff console session, it needs a step-up in the last 10 minutes as well ([Confirm it is you](/docs/organizations/staff-console/sign-in/#confirm-it-is-you)). Each change a member makes to an organization's app goes into [the organization's audit log](/docs/organizations/audit-log/), which names the member. The log leaves out deployments that a push starts.

In the dashboard, an organization's apps are on its **Apps** tab: [Run apps for an organization](/docs/apps/organization-apps/).

## With the API

Every Apps request takes your access token as `Authorization: Bearer $CORITAN_TOKEN` ([Authentication](/docs/api/authentication/)). Your own apps are under `/api/v1/client/apps`. An organization's apps are under `/api/v1/orgs/{org_slug}/apps`, and take the token of one of its members. An app that belongs to someone else answers `404` with `App not found`, as an app that does not exist does.

### List apps

[`GET /api/v1/client/apps`](/docs/api/reference/client/apps/#op-get-api-v1-client-apps) lists your apps, newest first, each with its current deployment and replica counts:

```bash
curl "https://api.coritan.com/api/v1/client/apps?status=active&limit=20" \
  -H "Authorization: Bearer $CORITAN_TOKEN"
```

```json
{
  "apps": [
    {
      "uuid": "3c9e2f4a-8b1d-4f6e-a2c7-5d8b9e0f1a21",
      "name": "Web shop",
      "slug": "web-shop",
      "status": "active",
      "owner": {"type": "user"},
      "source_type": "git",
      "repo_url": "https://github.com/example/web-shop",
      "repo_branch": "main",
      "repo_subdir": null,
      "repo_token_set": true,
      "repo_token_hint": "x9Qa",
      "image_ref": null,
      "framework": null,
      "install_command": null,
      "build_command": null,
      "start_command": null,
      "dockerfile_path": null,
      "port": 3000,
      "health_check_path": "/healthz",
      "instance_size": "small",
      "memory_mb": 512,
      "cpu_percent": 100,
      "disk_mb": 2048,
      "regions": ["fra", "iad"],
      "min_replicas": 2,
      "max_replicas": 2,
      "url": "https://web-shop.apps.example.net",
      "platform_hostname": "web-shop.apps.example.net",
      "domains_count": 2,
      "current_deployment": {
        "uuid": "8c4e1a7d-2f9b-4d6e-b3a8-6e1f9c2d5a10",
        "status": "ready",
        "source": "git",
        "trigger": "push",
        "git_ref": "main",
        "git_sha": "9f2c1e7b4a6d8e0f1a2b3c4d5e6f708192a3b4c5",
        "is_current": true
      },
      "replicas": {"healthy": 4, "unhealthy": 0, "starting": 0, "total": 4},
      "webhook": {
        "url": "https://api.coritan.com/api/v1/apps/hooks/3c9e2f4a-8b1d-4f6e-a2c7-5d8b9e0f1a21",
        "secret_set": true,
        "secret_hint": "f0a9"
      },
      "created_at": "2026-09-20T09:12:00Z",
      "updated_at": "2026-09-26T10:05:00Z"
    }
  ],
  "total": 1,
  "limit": 20,
  "offset": 0
}
```

`status` is `active` or `suspended`, and leaving it out lists both. `limit` takes 1–100 (50 when left out), and `offset` skips that many apps. `total` counts every app the filter matches. The example shortens `current_deployment`, which carries every field of a deployment. [App and deployment fields](/docs/apps/fields/) describes each field.

The examples on these pages use `apps.example.net` for the platform's app domain. `base_domain` in the regions answer below gives the real one.

### Get one app

[`GET /api/v1/client/apps/{app_uuid}`](/docs/api/reference/client/apps/#op-get-api-v1-client-apps-app-uuid) returns the app with more beside it:

`app`
: The app, as in the list.

`domains`
: Its platform name first, then its custom domains ([Add a custom domain](/docs/apps/custom-domains/)).

`deployments` and `deployments_total`
: The five newest deployments, and how many the app has in all ([Deploy an app](/docs/apps/deploy-an-app/#list-deployments)).

`replicas`
: The replicas of the deployment that serves the app, without the ones that failed ([Read a deployment](/docs/apps/read-a-deployment/#replicas)).

```bash
curl https://api.coritan.com/api/v1/client/apps/3c9e2f4a-8b1d-4f6e-a2c7-5d8b9e0f1a21 \
  -H "Authorization: Bearer $CORITAN_TOKEN"
```

### Regions, sizes and limits

[`GET /api/v1/client/apps/regions`](/docs/api/reference/client/apps/#op-get-api-v1-client-apps-regions) says what you can choose when you create an app:

```bash
curl https://api.coritan.com/api/v1/client/apps/regions \
  -H "Authorization: Bearer $CORITAN_TOKEN"
```

```json
{
  "regions": [
    {"code": "fra", "name": "Frankfurt", "country_code": "DE"},
    {"code": "iad", "name": "Ashburn", "country_code": "US"}
  ],
  "sizes": [
    {"name": "small", "memory_mb": 512, "cpu_percent": 100, "disk_mb": 2048},
    {"name": "medium", "memory_mb": 1024, "cpu_percent": 200, "disk_mb": 4096},
    {"name": "large", "memory_mb": 2048, "cpu_percent": 400, "disk_mb": 8192}
  ],
  "base_domain": "apps.example.net",
  "limits": {
    "apps": 20,
    "apps_used": 3,
    "min_replicas": 5,
    "max_replicas": 10,
    "regions": 20,
    "custom_domains": 20,
    "env_vars": 200
  }
}
```

`regions` lists the regions that can run apps now. `base_domain` is the domain every platform name ends in, or `null` when the platform gives apps no platform name. In `limits`, `apps` is how many apps you may have, where `0` means no limit, and `apps_used` is how many you have. `min_replicas` and `max_replicas` are the most you can set for each, and the rest are the most regions, custom domains and variables one app can have.

The same three requests under `/api/v1/orgs/{org_slug}/apps` read an organization's apps, and there `limits.apps_used` counts the organization's apps. The [organization apps reference](/docs/api/reference/organizations/organization-apps/#op-get-api-v1-orgs-org-slug-apps) lists them.

## API

- `GET /api/v1/client/apps`: List apps (https://www.coritan.com/docs/api/reference/client/apps/#op-get-api-v1-client-apps)
- `GET /api/v1/client/apps/regions`: Regions (https://www.coritan.com/docs/api/reference/client/apps/#op-get-api-v1-client-apps-regions)
- `GET /api/v1/client/apps/{app_uuid}`: Get one app with its domains, recent deployments and current replicas (https://www.coritan.com/docs/api/reference/client/apps/#op-get-api-v1-client-apps-app-uuid)
- `GET /api/v1/orgs/{org_slug}/apps`: List apps (https://www.coritan.com/docs/api/reference/organizations/organization-apps/#op-get-api-v1-orgs-org-slug-apps)
- `GET /api/v1/orgs/{org_slug}/apps/regions`: Regions (https://www.coritan.com/docs/api/reference/organizations/organization-apps/#op-get-api-v1-orgs-org-slug-apps-regions)
- `GET /api/v1/orgs/{org_slug}/apps/{app_uuid}`: Get one app with its domains, recent deployments and current replicas (https://www.coritan.com/docs/api/reference/organizations/organization-apps/#op-get-api-v1-orgs-org-slug-apps-app-uuid)
