Skip to content

Internal builder API

Authorization: Bearer kbt_… with a builder token:

Builder Token
The control plane host builder FALAK_LOCAL_BUILDER_TOKEN (the installer’s FALAK_BUILDER_TOKEN); serves every organization
builder servers Installed automatically when the server finishes provisioning
External builders Created under Settings → Builders (organization-scoped)

401 for unknown or disabled tokens.

Run a builder
falak-builder serve --url https://falak.example.com --token kbt_… --name build-1
# env: FALAK_URL, FALAK_BUILDER_TOKEN, FALAK_BUILDER_NAME

GET /api/internal/builds/next?wait=<s>&builder=<name>&run=<run id>

Section titled “GET /api/internal/builds/next?wait=<s>&builder=<name>&run=<run id>”

Long-poll (up to 25 s) for the next job this builder is eligible for (organization and build mode). 204 when nothing is queued; 200 with a job:

{"id": "01k…", "mode": "native", "timeout_s": 1800, "runtime": "php",
"repo": {"url": "git@github.com:acme/shop.git", "ref": "main", "commit": "a1b2…",
"deploy_key": "-----BEGIN OPENSSH PRIVATE KEY-----…", "known_hosts": "…"},
"env": {"VITE_APP_NAME": "Shop"},
"native": {"upload": {"url": "https://falak.example.com/api/internal/artifacts/…?expires=…&signature=…",
"headers": {"Content-Type": "application/octet-stream"}}}}
  • run is a random id per falak-builder process. A poll with a new run id fails the builds the same builder name claimed under a previous run (“Builder <name> restarted during the build.”). Two builder processes sharing a token must use different --names.
  • Docker jobs carry "docker": {"image", "dockerfile", "build_args", "registry": {"server", "username", "password"}, "push": true} instead of native.
  • Clone credentials are fetched at hand-out time and never stored. HTTPS clones use token/username instead of deploy_key.
  • env holds public front-end variables and variables exposed to the deploy script.
  • Native jobs carry native.install_command / native.build_command when the site defines FALAK_INSTALL_COMMAND / FALAK_BUILD_COMMAND.

NDJSON body, one event per line (started, output, progress, finished), idempotent on (build, seq). finished with exit_code 0 and a result (artifact.sha256|size_bytes|format or image.ref|digest) marks the build succeeded; exit code 124 means timed out.

Response Meaning
204 Accepted
404 Unknown build, or assigned to another builder
410 The build was cancelled: the builder aborts it
413 Batch larger than 8 MiB
422 Malformed line

POST /api/internal/builds/{build}/heartbeat

Section titled “POST /api/internal/builds/{build}/heartbeat”

Every 20 s while building. 204; 404 unknown or another builder’s; 410 the build is over (cancelled, failed by the watchdog, reaped) and the builder aborts. A running build fails after FALAK_BUILD_HEARTBEAT_TIMEOUT (90 s) without a heartbeat or event.

With the local driver, PUT /api/internal/artifacts/{key} (upload) and GET /api/internal/artifacts/{key} (download by agents) are authorized by the signed, expiring URL alone (403 otherwise). URLs are always https (FALAK_ARTIFACTS_URL, default APP_URL). With FALAK_ARTIFACTS_DRIVER=s3, builders and agents use SigV4-presigned bucket URLs instead.

The falak-builder binary for builder servers (from FALAK_BUILDER_BINARIES_PATH, or FALAK_BUILDER_DOWNLOAD_URL).