API Documentation

Complete reference for all BuildHut endpoints. Log in to see your app secrets in examples.

Authentication

MethodUsed byHeader / Param
SessionWeb portalCookie: dev-id, session-token
BearerCI/CD, CLIAuthorization: Bearer bh_<token>
SecretTelemetry, OTLPX-Secret header, ?secret= query, or body

API tokens are managed at /portal/tokens. Up to 5 per developer. Format: bh_ + 64 hex chars. Expiry: never, 1w, 2w, or 1 month.

App & Build APIs

GET /api/app/{id} public

Latest build info + presigned download URL. 5-minute cache.

Response
{
  "app": "my-app",
  "version": "1.0.5",
  "tag": "1.0.5",
  "downloadUrl": "https://s3.../presigned-url",
  "uploadedAt": "2026-04-01T10:00:00.000Z"
}
GET /api/apps/{name}/latest public

Redirect to latest build download. Increments download count (30s debounce).

GET /api/apps/{name}/latest/{os}/{arch}/{format} public

Platform-specific build download.

Format aliases: appimage, deb, rpm, flatpak

Upload APIs

POST /api/upload/presign auth

Generate presigned S3 URL for direct upload. 5-minute expiry.

FieldRequiredDescription
fileNameyesFile name with extension
nameyesApp name
versionyesVersion string
curl -X POST "https://buildhut.fly.dev/api/upload/presign" \
  -H "Authorization: Bearer bh_YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "fileName": "app.apk", "name": "my-app", "version": "1.0.0" }'
POST /api/upload auth

Finalize build upload and create DB records. Max 200MB.

FieldRequiredDescription
nameyesApp name
versionyesVersion string
fileNameyes*Original file name
s3Keyyes*S3 key from presign
osnoAuto-detected from filename
architecturenoe.g. x86_64, arm64-v8a, universal
filenoBinary file (direct upload)
curl -X POST "https://buildhut.fly.dev/api/upload" \
  -H "Authorization: Bearer bh_YOUR_TOKEN" \
  -F "name=my-app" \
  -F "version=1.0.0" \
  -F "file=@app-release.apk"

* Required for presign flow. Use file field for direct upload.

Telemetry API

POST /api/telemetry secret

Submit telemetry events from your app. Secret passed via X-Secret header, ?secret= query, or body.

FieldLocationDescription
appNamequery/bodyApp name
kindbodyerror | warning | info | trace | debug
versionbodyApp version
bitsbodyArbitrary JSON payload
curl -X POST "https://buildhut.fly.dev/api/telemetry?appName=YOUR_APP" \
  -H "X-Secret: YOUR_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
    "kind": "info",
    "version": "1.0.0",
    "bits": { "event": "app_opened" }
  }'
GET /api/telemetry session

List telemetry events.

ParamDescription
appNameFilter by app name
kindFilter by kind (comma-separated)
limitMax results (default 200)

OTLP Endpoints

OpenTelemetry Protocol ingestion. Accept JSON and Protobuf. Auth: app secret.

POST /v1/traces
POST /v1/metrics
POST /v1/logs

Feature Flags API

GET /v1/flags secret

Fetch feature flag definitions for an app.

curl "https://buildhut.fly.dev/v1/flags?appName=YOUR_APP" \
  -H "X-Secret: YOUR_SECRET"
POST /v1/flags/eval secret

Report feature flag evaluations.

{
  "evaluations": [
    { "flagName": "dark_mode", "enabled": true },
    { "flagName": "new_dashboard", "enabled": false, "context": { "userId": "abc" } }
  ]
}

Response: {"accepted": 2, "unknown": []}

Publishing APIs

MethodEndpointDescriptionAuth
POST/api/publish/generatePreview publishing files (PKGBUILD, metadata.yml)session
POST/api/publish/publishExecute async publish runsession
GET/api/publish/status/{runId}Poll publish run statussession
GET/api/publish/ssh-keysList SSH keyssession
POST/api/publish/ssh-keysAdd SSH key (encrypted at rest)session
DEL/api/publish/ssh-keys/{id}Delete SSH keysession

Utility APIs

MethodEndpointDescriptionAuth
ANY/api/auth/statusCheck auth statepublic
POST/api/logoutClear session cookiespublic
GET/api/img/{key}Serve uploaded imagespublic
GET/api/branches?app={name}List git branches from source reposession
POST/api/pgp/fetch-keyFetch PGP key from keys.openpgp.orgsession
POST/api/validateValidate bot challengepublic