---
title: "Deploy an App"
method: POST
path: "/v1/apps/{app_id}/deploy"
tags: ["Apps"]
---

# Deploy an App

`POST /v1/apps/{app_id}/deploy`

Queue a build+deploy for an App, creating a new version.

**Full deploy workflow:**
1. `POST /{app_id}/deploy/upload-url` → get a presigned S3 PUT URL
2. Upload your built dist/ zip to that URL
3. Call this endpoint with the returned `bundle_s3_key`
4. Optionally include `source_files` (path→content map) for version diffing
5. Poll `GET /{app_id}/deploys/{deploy_id}` until status is `complete`

**Edit-and-redeploy workflow:**
1. `GET /{app_id}/versions/{version}/download` → download the bundle zip
2. Edit files locally
3. Re-zip and upload via upload-url → deploy (creates a new version)
4. `GET /{app_id}/versions/{old}/diff/{new}` to review changes

Each deploy creates an immutable version record. Use `POST /{app_id}/versions/{n}/restore`
for instant rollback to any previous version.

## Path parameters

- `app_id` string, required

## Request body

- DeployRequest — Deploy a pre-built bundle (CLI path) or trigger a Git-based build.
  - `environment` 'staging' | 'production' — Target environment for this deploy
  - `message` string — Deploy message describing what changed (like a git commit message)
  - `source` 'cli_upload' | 'git' — Deploy source. 'cli_upload' = zip already uploaded to S3. 'git' = Phase 3b.
  - `bundle_s3_key` string, nullable — S3 key of the uploaded source zip (required for source='cli_upload')
  - `source_files` object, nullable — Map of relative path → file content for source-level version diffs
  - `git_commit_sha` string, nullable — Git commit SHA associated with this deploy
  - `git_commit_message` string, nullable — Git commit message associated with this deploy
  - `git_author` string, nullable — Git commit author (name <email>)

## Response `200`

Successful Response

- DeployResponse
  - `app_id` string, required
  - `deploy_id` string, required
  - `status` 'queued' | 'building' | 'complete' | 'failed', required
  - `environment` string, required
  - `message` string, nullable

## Other responses

- `400` — Bad Request
- `401` — Unauthorized
- `403` — Forbidden
- `404` — Not Found
- `422` — Validation Error
- `500` — Internal Server Error

---

[API](https://skmtc.net/mixpeek/apis/mixpeek-api.md) · [All operations](https://skmtc.net/mixpeek/apis/mixpeek-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/mixpeek/mixpeek-api/versions/5d4c905106b4/schema)
