Upload a Deploy

POST /v1/applications/{uuid}/deploys

Upload a new version of a static app as a .zip of built files (with index.html at the publish-dir root). The archive is staged and a build job is enqueued; the build runs asynchronously in the background. Send multipart/form-data with a single file field.

Request (multipart/form-data)

file file (.zip)
Required. A .zip of your site — source (Ngris builds it) or built files. Max size is plan-limited (default 100 MB).
version string
Optional display label (max 64 chars), e.g. v2.1.0. When unset the display falls back to the git commit short SHA (git deploys) or v{n} (uploads).

Per-app environment variables are injected into the build; watch it live via the build log.

Response (202 Accepted)

uuid string
The new deploy's identifier.
trigger_type string
upload.
status string
queued — poll the list until it reaches ready.

Errors

400 / 413
Missing/non-zip file (400) or over the size limit (413).
403 / 507
Storage quota exceeded (403) or object storage not configured (507).
Request
curl -X POST "https://api.ngris.com/v1/applications/a1b2c3d4-…/deploys" \ -H "X-API-KEY: <your_api_key>" \ -F "file=@dist.zip"
Response — 202 Accepted
{ "uuid": "d3e4f5…", "application_id": 12, "trigger_type": "upload", "status": "queued", "git_sha": null, "created_at": "2026-07-28T12:10:00Z" }

List Deploys

GET /v1/applications/{uuid}/deploys

List an app's deploys, newest first (up to 100). Poll this after an upload or a git push to watch a build progress.

Deploy fields

uuid string
Deploy identifier (used to activate + fetch the build log).
version int
Monotonic version number.
display_version string
The label to show: your version_label if set, else the git commit short SHA (git), else v{version}.
version_label string | null
The optional label you set on the deploy.
preview_url string
Shareable, read-only preview URL for a ready/superseded deploy — independent of which version is live.
trigger_type string
upload, git_manual, or git_push.
status string
queuedprocessingready (or failed); a replaced live version becomes superseded. Managed backends add the finer states buildingimage_readyrolling_out.
rollbackable bool
true when this deploy can be activated / rolled back to — it is a terminal, built version (ready/superseded), not pruned, and not already the live version.
pruned bool
true once the retention policy has deleted this deploy's build artifact (static bundle or OCI image). The row survives for history, but it can no longer be rolled back to.
size_bytes / file_count int
Total bytes and file count (set once built).
git_sha string | null
The deployed commit (git deploys).
image_ref string | null
Managed / fullstack apps: the immutable, digest-pinned image the deploy runs (enables instant rollback). null for static deploys.
error string | null
Build failure reason when status = failed — or read the full build log.
Retention window. Only the newest N terminal deploys stay rollbackable (the deploy_max_rollback_versions entitlement, per plan). Older deploys are pruned — their artifacts are deleted and rollbackable is false. The live version is always kept.
Response — 200 OK
{ "deploys": [ { "uuid": "d3e4f5…", "version": 2, "display_version": "v2.1.0", "version_label": "v2.1.0", "preview_url": "https://d3e4f5….ngris.app", "trigger_type": "git_push", "status": "ready", "rollbackable": false, "pruned": false, "size_bytes": 1048576, "file_count": 42, "git_sha": "9fce…", "created_at": "2026-07-28T12:12:00Z" }, { "uuid": "c2d3e4…", "version": 1, "display_version": "9fceab1", "trigger_type": "upload", "status": "superseded", "rollbackable": true, "pruned": false, "created_at": "2026-07-28T12:10:00Z" } ] }

Activate (Restart / Rollout / Rollback)

POST /v1/applications/{uuid}/deploys/{deploy_uuid}/activate

Promote a built deploy to live, roll back to an earlier version, or restart the current one. For static apps this is an atomic pointer flip; for managed / fullstack apps it re-rolls the pod onto that deploy's digest-pinned image. A pruned version can't be rolled back to (409).

See the full reference on the dedicated page: Activate (Restart / Rollout / Rollback).

Request
curl -X POST \ "https://api.ngris.com/v1/applications/a1b2c3d4-…/deploys/c2d3e4…/activate" \ -H "X-API-KEY: <your_api_key>"
Response — 200 OK
{ "status": "ok", "current_deploy_id": 455 } // static { "status": "rolling_out", "deploy_id": 455 } // managed / fullstack

Redeploy

POST /v1/applications/{uuid}/redeploy

Rebuild and re-ship the application from the last uploaded source — no re-upload needed. The most recent deploy's staged archive is reused as the source, a fresh deploy is created, and a build job is enqueued (a static bundle rebuild, or a signed image rebuild for managed / fullstack apps). Useful to pick up a changed environment variable or a base-image refresh without re-sending the archive.

This is for upload-sourced apps. Git apps redeploy by pushing to the connected branch (or via the push-to-deploy webhook) — calling this on a git app returns 409.

Response (202 Accepted)

deploy object
The newly created deploy (uuid, version, status: "queued", …). Poll list deploys or the build log for progress.
status string
queued.

Errors

409
A git app (push to redeploy instead), or the app has no prior deploy to rebuild from.
503
Object storage is not configured on this deployment.
Request
curl -X POST \ "https://api.ngris.com/v1/applications/a1b2c3d4-…/redeploy" \ -H "X-API-KEY: <your_api_key>"
Response — 202 Accepted
{ "deploy": { "uuid": "e5f6a7b8-…", "version": 12, "status": "queued" }, "status": "queued" }