Create an app with the Apps API
Create an app from a git repository or a container image with the Apps API, choose its size, regions and replicas, and start its first release.
Create an app to run a web service from a git repository or from a container image. Creating it also starts its first release unless you turn that off, so a working app is live once its replicas pass their health check. The app then appears under App Deployment in the dashboard, as a Web service.
The Apps API's create request keeps working for scripts written for Apps. A new app can also be ordered as a deployment, which chooses its locations and scaling from the start (Deploy from a git repository). An order has no size and no plan to choose: it names a source, a name and a location, and takes two optional settings, the largest memory and a monthly budget (Order your code).
Before you begin
Section titled Before you begin- Send your access token as
Authorization: Bearer $CORITAN_TOKEN(Authentication). Apps must be on for the platform (Limits and availability). - For a git app, the repository must be on a public host and reachable over HTTPS. For a private repository, create an access token on your git host that can read it.
- For an image app, the image must be one that anyone can pull, such as a public image on GitHub Container Registry or Docker Hub.
- Make sure the app listens on the port in its
PORTvariable and answers its health check path (What your app must do). - For an organization's app, you need the owner or admin role in the organization.
- You can have a set number of apps. Regions, sizes and limits shows how many you have and may have.
Create the app
Section titled Create the appPOST /api/v1/client/apps creates an app of your own. For an organization's app, send the same body to POST /api/v1/orgs/{org_slug}/apps.
curl -X POST https://api.coritan.com/api/v1/client/apps \
-H "Authorization: Bearer $CORITAN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Web shop",
"source_type": "git",
"repo_url": "https://github.com/example/web-shop",
"repo_branch": "main",
"repo_token": "github_pat_EXAMPLE",
"health_check_path": "/healthz",
"instance_size": "small",
"regions": ["fra", "iad"],
"min_replicas": 2,
"env": [{"key": "DATABASE_URL", "value": "postgres://app:secret@db.example.com/shop"}]
}'
The body takes these fields. Only name is required, and a git app also needs repo_url, an image app image_ref. Whether the app builds from git or runs an image cannot change later.
name- What you call the app, 1–100 characters. You can change it later.
slug- The name on the platform, which the app's platform name
<slug>.<app domain>is made from. Made fromnamewhen left out (Names on the platform). It cannot change after you create the app. source_typegit, the default, orimage.repo_url- For a git app, the repository's HTTPS address, such as
https://github.com/example/web-shop, with no user name, token, query or fragment in it. repo_branch- The branch to build,
mainwhen left out. Pushes to it deploy the app once you set up the push webhook. repo_subdir- Where the app lives inside the repository. Leave it out when the app is at the top.
repo_token- For a private repository. We keep it encrypted, use it only to fetch the code, and never show it again. The app shows its last four characters as
repo_token_hint, so you can tell which token it holds. An image app refuses the repository fields. image_ref- For an image app, a reference such as
ghcr.io/example/web:1.4.0, or one pinned to a digest such asghcr.io/example/web@sha256:…. It must be one anyone can pull, such as an image your CI builds from a Dockerfile and pushes to GitHub Packages or Docker Hub. A git app refuses it. dockerfile_path- Leave it out. Dockerfiles are not built, so a path answers
422withdockerfile_unsupported: build the image in your CI and create an image app instead (Dockerfile? Deploy a container image). install_command,build_commandandstart_command- Commands that replace the framework's defaults, up to 500 characters each (Frameworks we build).
framework- The framework preset to build with, such as
next,sveltekit,fastapiorgo. Leave it out and the build detects it from the files.GET /api/v1/deploy-presetslists the presets. port- A number from 1 to 65535,
3000when left out. Each replica gets the port to listen on in itsPORTvariable, whatever this setting says. health_check_path- The path we request to decide that a replica is healthy,
/when left out. It starts with/, such as/healthz. instance_sizesmall,mediumorlarge,smallwhen left out. It sets the memory, CPU and disk each replica gets (Replicas and regions). The app is billed by what it uses from the moment it is created, and the size becomes its starting memory limit. A larger limit costs nothing until the replicas use it (How App Deployment is billed). A prepaid account that has not added the first deposit gets403with the codedeposit_requiredand nothing is created. When billing by use is not available for the size, nothing is created and the API answers409size_not_offered.regions["*"]for every region that can run apps at the time of each release, the default, or a list of up to 20 region codes.min_replicasandmax_replicas- Replicas in each region, 1–5 for
min_replicas(1 when left out).max_replicastakes up to 10, and one belowmin_replicasis raised to it. To let each region scale with traffic up to its maximum, save the app's locations on its Instances tab afterwards, with a maximum above the minimum (Scale with traffic). env- A list of variables, each with
key,valueand optionallysecretandtarget(Set environment variables with the Apps API). deploytrue, the default, starts the first release.falsecreates the app without one.
It answers 201:
{
"app": {
"uuid": "3c9e2f4a-8b1d-4f6e-a2c7-5d8b9e0f1a21",
"name": "Web shop",
"slug": "web-shop",
"status": "active",
"source_type": "git",
"repo_token_set": true,
"repo_token_hint": "MPLE",
"url": "https://web-shop.apps.example.net"
},
"deployment": {
"uuid": "0b6f3d2e-7a41-4c59-8e1d-2f9a6b3c4d5e",
"status": "queued",
"source": "git",
"trigger": "manual",
"git_ref": "main"
},
"deploy_error": null,
"webhook": {
"url": "https://api.coritan.com/api/v1/apps/hooks/3c9e2f4a-8b1d-4f6e-a2c7-5d8b9e0f1a21",
"secret": "4f1d2c3b5a69788796a5b4c3d2e1f0a94f1d2c3b5a69788796a5b4c3d2e1f0a9"
}
}
The example shortens app and the first release, which the API names deployment. Both carry every field (App and release fields). webhook.secret appears in this answer only, and webhook is null for an image app. deployment is null when you sent "deploy": false, and also when the first release could not start, when deploy_error says why, as in The GitHub App is suspended on example-org. Unsuspend it on GitHub, or connect the repository again..
Names on the platform
Section titled Names on the platformA name on the platform has 3 to 63 lowercase letters, digits and hyphens, and starts and ends with a letter or a digit. It cannot have hyphens in both its third and fourth places, and no other app on the platform can have it. Some words are reserved for the platform, such as api, admin, app, status and www.
When you leave it out, we make one from the app's name, such as web-shop for Web shop. When that one is taken or reserved, we add a hyphen and four random characters, as in web-shop-k3x9.
What happens next
Section titled What happens nextA git app starts with a build of its branch, then starts replicas. An image app starts replicas at once. Follow the first release with Read a release and its build log with the Apps API, or on the app's Releases tab.
A git app also gets a push webhook, and its secret is in the answer to the create request only. Save it if you want pushes to deploy the app (Deploy on every push). You can make a new secret later.
If the first release cannot start, we still create the app and say why in deploy_error. Fix the cause, then deploy it (Deploy an app with the Apps API).
An app is a deployment, and How App Deployment is billed explains how deployments are billed. Its Billing tab in the dashboard, or GET /api/v1/billing/deployments/{app_uuid}, shows how it is billed and what it has cost this month. An app created through the Apps API has no pay as you go or monthly price to choose.
Result
Section titled ResultThe app is in your apps with its platform address, and its first release is on its way unless you turned it off. Once that release is ready, which the dashboard shows as Live, the app is live and answers at https://<name on the platform>.<app domain>.
Troubleshooting
Section titled Troubleshooting| Status | detail |
Cause |
|---|---|---|
403 |
{"error": "deposit_required", "code": "deposit_required", "message": "Billing by use takes credit each hour, and your account has not deposited the minimum. Deposit at least $10, then create the app", "minimum": "10"} |
A prepaid account has not added the first deposit. Add credit, then create the app. An account billed by invoice needs none. |
409 |
{"error": "size_not_offered", "message": "Apps of size large cannot be created now: billing by use is not available for that size. Choose another size"} |
Billing by use is not available for the size. Choose another size. |
409 |
{"error": "slug_taken", "message": "The name web-shop is taken on the platform. Choose another"} |
Another app has the slug you sent. Choose another, or leave it out so that we make one. |
409 |
{"error": "app_limit", "message": "The limit is 20 apps. Delete one before creating another", "limit": 20} |
You have as many apps as you may. Delete one you no longer need (Delete an app). |
422 |
The app name on the platform must be 3 to 63 lowercase letters, digits and hyphens, starting and ending with a letter or digit |
The slug breaks the rules above. |
422 |
www is reserved. Choose another name |
The slug is one the platform keeps for itself. |
422 |
{"message": "These regions cannot run apps: syd", "unavailable": ["syd"], "available": ["fra", "iad"]} |
A region in regions cannot run apps now. Choose from the regions the platform offers, or every region. |
422 |
That is not an image reference Docker can pull, e.g. ghcr.io/you/app:1.2.0 |
image_ref is not an image reference. |
422 |
repo_url is for apps that build from git |
An image app was sent a repository field. |
422 |
{"error": "dockerfile_unsupported", "message": "Dockerfiles are not built on the platform. Build the image in your CI and deploy it as a container image."} |
The body names a dockerfile_path. |
422 |
The health check path must start with / and be a plain URL path |
health_check_path is not a path. |
429 |
{"error": "rate_limited", "message": "Too many apps created in the last hour. Wait a while and try again.", "retry_after_seconds": 3600} |
You created 20 apps in the last hour. |
The repository must be on a public host.orThe repository URL must start with https://.- Give the repository's HTTPS address on a public host.
Put the access token in the app's repository token, not in the URL.- Remove the user name or token from the address and send the token as
repo_token. The image must be on a public registry- The image's host is on a private network. Push the image to a public host, such as GitHub Packages or Docker Hub.
An organization's route also answers 403 with Admin access required for a member who is not an owner or admin. Apps API limits lists the other rate limits.
Related
Section titled RelatedAPI operations on this page
| Method | Path | What it does |
|---|---|---|
POST | /api/v1/client/apps | Create an app and, unless deploy is false, its first release |
POST | /api/v1/orgs/{org_slug}/apps | Create an app and, unless deploy is false, its first release |