Deployments API
The deployment resource
Section titled “The deployment resource”{"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.
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"}}after=0while :; 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 2donePOST /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.