Skip to content

Deployments API

{"id": "01k…", "site_id": "01k…", "number": 42,
"status": "deploying", "phase": "migrate",
"trigger": "api", "strategy": "zero-downtime",
"branch": "main", "commit": "a1b2c3…", "message": "Fix checkout", "author": "Ada",
"release_id": "01k…", "build_id": "01k…", "rolled_back": false,
"url": "https://falak.example.com/sites/01k…/deployments/01k…", "error": null,
"waiting_reason": null, "waiting_since": null,
"created_at": "…", "started_at": "…", "finished_at": null}
Field Values
status queued, waiting, building, deploying, succeeded, failed, cancelled
phase build, fetch, prepare, migrate, activate, restart, healthcheck, rollback, or null
trigger manual, push, api, hook, rollback
strategy zero-downtime, in-place, rolling, canary, blue-green, compose
rolled_back true with status: failed means switched servers were returned to the previous release
waiting_reason, waiting_since Set while waiting, e.g. "Waiting for 2 servers to finish preparing: web-1, web-2"

Terminal statuses: succeeded, failed, cancelled.

POST /api/v1/sites/{site}/deployments — deployments.create

Section titled “POST /api/v1/sites/{site}/deployments — deployments.create”

Body (all optional): {"branch": "main", "commit": "<sha>"}. Without a commit, the branch head is resolved through the git provider. Rate limited to 30/minute.

Terminal window
curl -X POST https://falak.example.com/api/v1/sites/shop/deployments \
-H "Authorization: Bearer $FALAK_TOKEN" -H "Accept: application/json" -H "Content-Type: application/json" \
-d '{"branch": "main", "commit": "a1b2c3d4e5f6"}'

201 {"data": Deployment}. The deployment starts immediately (building), queues behind the site’s running deployment (queued), or waits for servers being prepared (waiting).

While a non-rollback deployment is waiting, every further trigger — this endpoint, the CLI, the UI, push-to-deploy, deploy hooks — updates that deployment (the latest branch/commit wins) and the response is that same deployment. It starts by itself once every preparing server is ready; servers whose preparation failed are skipped with a warning while another server is ready. It fails when the leader’s preparation fails, no server can be prepared, or after FALAK_DEPLOY_WAIT_TIMEOUT_MINUTES (default 30).

GET /api/v1/sites/{site}/deployments — deployments.view

Section titled “GET /api/v1/sites/{site}/deployments — deployments.view”

Paginated, newest first.

GET /api/v1/deployments/{deployment} — deployments.view

Section titled “GET /api/v1/deployments/{deployment} — deployments.view”

The deployment plus targets with their steps:

{"targets": [{"id": "…", "server_id": "…", "server_name": "web-1", "role": "leader", "batch": 0,
"status": "succeeded", "activated": true, "error": null,
"steps": [{"key": "fetch:…", "kind": "fetch", "label": "fetch", "phase": "fetch", "rollback": false, "batch": 0,
"status": "succeeded", "command_id": "…", "exit_code": 0, "error": null,
"started_at": "…", "finished_at": "…", "duration_ms": 812}]}]}
Field Values
targets[].status pending, deploying, succeeded, failed, rolled_back, skipped
steps[].status pending, running, succeeded, failed, skipped

GET /api/v1/deployments/{deployment}/output?after=<seq> — deployments.view

Section titled “GET /api/v1/deployments/{deployment}/output?after=<seq> — deployments.view”

Output lines with seq > after (up to 1000 per page), in order. Poll with after = meta.next until meta.status is terminal. server is null for build and orchestration lines.

{"data": [{"seq": 1812, "at": "…", "server": "web-1", "server_id": "…", "step_id": "…",
"phase": "migrate", "stream": "stdout", "data": "Migrating: …\n"}],
"meta": {"next": 1812, "status": "deploying"}}
Poll until done
after=0
while :; do
r=$(curl -s "https://falak.example.com/api/v1/deployments/$ID/output?after=$after" \
-H "Authorization: Bearer $FALAK_TOKEN" -H "Accept: application/json")
echo "$r" | jq -r '.data[].data' | tr -d '\r'
after=$(echo "$r" | jq '.meta.next'); status=$(echo "$r" | jq -r '.meta.status')
case "$status" in succeeded|failed|cancelled) echo "$status"; break;; esac
sleep 2
done

POST /api/v1/deployments/{deployment}/cancel — deployments.create

Section titled “POST /api/v1/deployments/{deployment}/cancel — deployments.create”

Cancels a deployment that is queued, waiting, or still building (nothing has touched the servers yet). 200 {"data": Deployment}; 422 otherwise.

POST /api/v1/sites/{site}/rollback — deployments.rollback

Section titled “POST /api/v1/sites/{site}/rollback — deployments.rollback”

Body {"release_id": "<ulid>"} (optional; default: the newest retained release before the current one). 201 {"data": Deployment} with trigger: "rollback". 422 (errors.release_id) when the release is current, failed or pruned, or there is nothing to roll back to.

GET /api/v1/sites/{site}/releases — deployments.view

Section titled “GET /api/v1/sites/{site}/releases — deployments.view”

Retained releases, current first:

{"data": [{"id": "01k…", "commit": "…", "branch": "main", "message": "…", "author": "Ada",
"deployment_id": "…", "build_id": "…", "image": null,
"status": "active", "active": true, "can_rollback": false,
"activated_at": "…", "created_at": "…"}]}

status is active or inactive. image is set for Docker sites.