Skip to content
FlightStack Docs
Sign in Start free

Build Agents API | FlightStack

The build-agent surface has two audiences:

  • User-facing (Bearer auth): list, register, update, delete agents from a dashboard or CLI.
  • Agent-facing (Agent-Token header): polling for jobs, sending heartbeats, posting build status, uploading artifacts and logs.

All endpoints under /buildagent.

MethodPathPurpose
GET/buildagentList agents. Respects X-Organization-Id.
POST/buildagentRegister a new agent. Returns { agentId, token, ... }.
GET/buildagent/{id}Get agent details.
PUT/buildagent/{id}Update agent (name, organization, public flag).
DELETE/buildagent/{id}Delete / unregister an agent.
GET/buildagent/scriptsList install scripts available for each platform.
POST/buildagent/{id}/commandsQueue a command for an agent (admin only — pause, resume, …).
GET/buildagent/{id}/commandsList queued commands for an agent.
Terminal window
curl -X POST https://api.flightstack.voostack.com/buildagent \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "macbook-pro",
"platform": "macOS",
"organizationId": null,
"canBuildIOS": true,
"canBuildAndroid": true,
"canBuildWeb": true,
"operatingSystemVersion": "14.5",
"xcodeVersion": "16.0",
"flutterVersion": "3.27.0",
"dartVersion": "3.5.0"
}'

Response:

{
"agentId": "a1b2c3d4-...",
"token": "eyJhbG…",
"organizationName": null
}

Persist the token — it’s used for every agent-side call below.

These are called by the build-agent binary itself. Authentication is Agent-Token: <token>.

MethodPathPurpose
GET/buildagent/{id}/pollLong-poll for the next build job. Returns null if idle.
POST/buildagent/{id}/heartbeatSend a heartbeat. Response signals pause/throttle.
POST/buildagent/{id}/jobs/{jobId}/statusUpdate build status (running, succeeded, failed).
POST/buildagent/{id}/jobs/{jobId}/logsStream a chunk of build log entries.
POST/buildagent/{id}/jobs/{jobId}/artifactsUpload an artifact (multipart, small files).
POST/buildagent/{id}/jobs/{jobId}/artifacts/upload-urlGet a signed URL for a large artifact.
POST/buildagent/{id}/jobs/{jobId}/artifacts/confirmConfirm a large artifact uploaded via signed URL.
GET/buildagent/{id}/jobs/{jobId}/credentialsFetch signing credentials for the current job.
POST/buildagent/{id}/cancel-buildsCancel listed jobs (used during graceful shutdown).
GET/buildagent/{id}/deployments/pollPoll for the next deployment task.
GET/buildagent/{id}/deployments/{deploymentId}Get deployment details (credentials, artifact URLs).
POST/buildagent/{id}/deployments/{deploymentId}/statusUpdate deployment status.
GET/buildagent/{id}/commands/pollPoll for pending commands (pause, resume, …).
POST/buildagent/{id}/commands/{commandId}/statusUpdate command status / result.
POST/buildagent/{id}/logs/streamStream agent console logs.
POST/buildagent/{id}/screenstack/uploadUpload ScreenStack screenshot (multipart).
POST/buildagent/{id}/screenstack/upload-by-targetUpload ScreenStack screenshot keyed by canvas/view target.
Terminal window
curl https://api.flightstack.voostack.com/buildagent/$AGENT_ID/poll \
-H "Agent-Token: $AGENT_TOKEN"

Returns either null (nothing pending) or a BuildJob payload. The agent runs the job and posts back through the /jobs/{jobId}/... endpoints above.

Terminal window
curl -X POST https://api.flightstack.voostack.com/buildagent/$AGENT_ID/heartbeat \
-H "Agent-Token: $AGENT_TOKEN" \
-H "Content-Type: application/json" \
-d '{"queueDepth": 0, "cpuLoad": 0.42}'

Response includes canAcceptJobs (and an optional constraintReason if the server has paused the agent). The agent should stop polling for jobs when canAcceptJobs is false.

For artifacts over a few MB, request a signed URL and upload directly to object storage:

  1. POST /buildagent/{id}/jobs/{jobId}/artifacts/upload-url{ uploadUrl, objectKey }
  2. PUT $uploadUrl with the file bytes.
  3. POST /buildagent/{id}/jobs/{jobId}/artifacts/confirm with { objectKey, sizeBytes, sha256 }.

Per-agent and per-job state is broadcast on the SignalR hub — see Realtime.