---
title: "Create an app"
method: POST
path: "/api/v1/apps"
tags: ["Apps"]
---

# Create an app

`POST /api/v1/apps`

## Request

- Base URL: `https://app.khotan.com`
- URL: `https://app.khotan.com/api/v1/apps`
- Auth: one of:
  - HTTP bearer
  - API key in header `x-api-key`

Provisions an app synchronously (template repo plus provider project) and responds 201 with the persisted record whether provisioning ends ready or failed; branch on the returned status. Requires an API key whose role includes developer. Pass an idempotencyKey to make retries safe: repeating a create with the same key returns the existing app instead of provisioning a duplicate. Initial environment variables are applied to the provider project before the first deployment. Omit regionPreference to use the default region. Omit domain to put the app's host on the default Khotan-managed namespace; an unavailable domain returns 400 invalid_domain.

## Request body

- object
  - `name` string, required
  - `regionPreference` string, nullable
  - `domain` string, nullable: Khotan-managed domain namespace for the app's host, such as khotan.app or apps.khotan.com. Omit to use the default namespace.
  - `environmentVariables` object[]
    - `key` string, required
    - `value` string, required
  - `database` union
    - object
      - `mode` 'existing', required
      - `databaseId` string, required
    - object
      - `mode` 'create', required
      - `displayName` string, required
      - `regionId` string, required
  - `redis` union
    - object
      - `mode` 'existing', required
      - `databaseId` string, required
    - object
      - `mode` 'create', required
      - `displayName` string, required
      - `primaryRegion` string, required
  - `idempotencyKey` string

## Response `201`

The persisted app record, in ready or failed status.

- object
  - `id` string, required
  - `displayName` string, required
  - `slug` string, required
  - `provider` string, required
  - `source` 'managed' | 'external', required
  - `status` 'creating' | 'ready' | 'failed', required
  - `lifecycle` 'active' | 'suspended', required
  - `regionPreference` string, nullable, required
  - `liveUrl` string, nullable, required
  - `primaryHostname` string, nullable, required
  - `repo` object, nullable, required
    - `provider` string, required
    - `owner` string, required
    - `name` string, required
    - `fullName` string, required
    - `url` string, nullable, required
    - `defaultBranch` string, nullable, required
    - `subdirectory` string, nullable, required
    - `status` 'creating' | 'ready' | 'failed', required
    - `clone` object, required
      - `httpsUrl` string, required
      - `sshUrl` string, required
      - `cliCommand` string, required
  - `currentDeployment` object, nullable, required
    - `status` 'queued' | 'building' | 'ready' | 'failed' | 'canceled', required
    - `target` 'production' | 'preview' | 'staging', required
    - `url` string, nullable, required
    - `gitProvider` string, nullable, required
    - `gitRepo` string, nullable, required
    - `gitBranch` string, nullable, required
    - `gitCommitSha` string, nullable, required
    - `createdAt` string, required
    - `readyAt` string, nullable, required
    - `failedAt` string, nullable, required
    - `failureState` object, nullable, required
      - `code` 'provider_unavailable' | 'provider_rejected' | 'internal_error', required
      - `message` string, required
  - `envChangedAt` string, nullable, required
  - `protected` boolean, required
  - `tags` string[], required
  - `createdAt` string, required
  - `updatedAt` string, required
  - `readyAt` string, nullable, required
  - `failedAt` string, nullable, required
  - `failureState` object, nullable, required
    - `code` 'provider_unavailable' | 'provider_rejected' | 'internal_error', required
    - `message` string, required

## Other responses

- `400`: The request was malformed or failed validation.
- `401`: Authentication is missing or invalid.
- `403`: The caller is not permitted to perform this action.
- `404`: The resource was not found.
- `429`: Too many requests; retry after the indicated delay.

---

[API](https://skmtc.dev/khotan/apis/khotan-api.md) - [All operations](https://skmtc.dev/khotan/apis/khotan-api/llms.txt) - [OpenAPI document](https://skmtc.dev/khotan/apis/khotan-api/revisions/90b512a53e42?raw)
