Groundwork

Groundwork / api

API reference

Everything the cockpit does goes through this HTTP API — the browser holds no privileges a script can't have. Your own instance serves the same reference interactively at /docs (Swagger over the live schema) and as a curated walkthrough in the API tab, with examples templated for your install.

Authentication

Two credentials, one rule each. A session cookie is a person — sign in through the UI or POST /api/login. An API key (Authorization: Bearer gw_…) is a script or another machine, minted in the cockpit and scoped:

ScopeMay do
readGET only
train (default)GET plus a whitelist of write paths: runs, exports, counting, auto-label, machine pairing
fulleverything a session can do except account/key management and machine registration — those stay session-only, so a leaked key can be revoked but never used to mint its successor or point your datasets at a new machine

Failed logins are throttled (delays, never lockouts), and every sign-in, refusal and key change lands in an append-only audit trail.

The project rule

Almost every route is project-scoped and the project is never implicit: pass ?project=<slug>. A missing project is a 422, not a fallback — no request can silently operate on the wrong dataset. Machine-level routes (/api/machines…, /api/overview, /healthz) take no project.

Worked examples

BASE=http://localhost:8000
AUTH="Authorization: Bearer gw_…"        # minted in the cockpit

# What is serving, and how good is it?
curl -s "$BASE/api/state?project=widgets" -H "$AUTH" | jq .served

# Add photos to the fix queue
curl -s -X POST "$BASE/api/upload?project=widgets" -H "$AUTH" \
     -F "files=@bench1.jpg" -F "files=@bench2.jpg"

# Count one image with the serving model (count + overlay URL back)
curl -s -X POST "$BASE/api/count?project=widgets" -H "$AUTH" \
     -F "image=@bench1.jpg"

# Start a training run (model × machine × card)
curl -s -X POST "$BASE/api/train?project=widgets" -H "$AUTH" \
     -H 'Content-Type: application/json' \
     -d '{"model":"yolov8n","machine":"here","epochs":250}'

The catalog — every route

Generated from the live application (app.openapi()), not written by hand — in the repo, CI fails if this table goes stale. As of v0.3.0 · 100 routes.

audit1 route
RouteMethodsWhat it does
/api/auditGETAudit Trail
bots8 routes
RouteMethodsWhat it does
/api/botsGET,POSTList Bots
/api/bots/{key}DELETEUnregister Bot
/api/bots/{key}/allowedPOSTSet Allowed
/api/bots/{key}/installPOSTInstall
/api/bots/{key}/probePOSTProbe Bot
/api/bots/{key}/projectPOSTMove Project
/api/bots/{key}/servicePOSTService
/api/bots/{key}/tokenPOSTSet Token
bucket-vocab1 route
RouteMethodsWhat it does
/api/bucket-vocabGET,PATCHGet Vocab
buckets2 routes
RouteMethodsWhat it does
/api/bucketsGETBuckets
/api/buckets/{stem}POSTSet Bucket
collect1 route
RouteMethodsWhat it does
/api/collectGETCollect Overview
count1 route
RouteMethodsWhat it does
/api/countPOSTCount
crop1 route
RouteMethodsWhat it does
/api/crop/{collection}/{stem}POSTCrop
dedup1 route
RouteMethodsWhat it does
/api/dedupGETDedup
engine1 route
RouteMethodsWhat it does
/api/engineGET,POSTEngine
export4 routes
RouteMethodsWhat it does
/api/exportGET,POSTStart
/api/export/artifactsGETArtifacts
/api/export/cardsGETCards
/api/export/formatsGETFormats
healthz1 route
RouteMethodsWhat it does
/healthzGETHealthz
image1 route
RouteMethodsWhat it does
/api/image/{collection}/{stem}DELETEDelete
images1 route
RouteMethodsWhat it does
/api/images/{collection}GETImages
img/{collection}/{stem}1 route
RouteMethodsWhat it does
/img/{collection}/{stem}GETImage
join1 route
RouteMethodsWhat it does
/api/join/bundleGETBundle
join.sh1 route
RouteMethodsWhat it does
/join.shGETJoin Script
keys3 routes
RouteMethodsWhat it does
/api/keysGET,POSTList Keys
/api/keys/scopesGETKey Scopes
/api/keys/{kid}DELETEDelete Key
la2 routes
RouteMethodsWhat it does
/api/laDELETE,GETStatus
/api/la/{collection}/{stem}POSTStart
lab8 routes
RouteMethodsWhat it does
/api/lab/imgGETLab Img
/api/lab/logGETLog
/api/lab/runsGETRuns
/api/lab/runs/{run}/detailGETDetail
/api/lab/scorePOSTScore
/api/lab/statusGETStatus
/api/lab/trainDELETE,POSTTrain
/api/lab/visGETVis
lab_status1 route
RouteMethodsWhat it does
/api/lab_statusGETLab Status
label_audit2 routes
RouteMethodsWhat it does
/api/label_auditGET,POSTLabel Audit Start
/api/label_audit/{collection}/{stem}POSTLabel Audit Points
login1 route
RouteMethodsWhat it does
/api/loginPOSTLogin
logout1 route
RouteMethodsWhat it does
/api/logoutPOSTLogout
machine5 routes
RouteMethodsWhat it does
/api/machine/cardsGETCards
/api/machine/pairPOSTAccept Pair
/api/machine/pairing-codePOSTMint Pairing Code
/api/machine/selfGETSelf Info
/api/machine/statusGETMachine Status
machines8 routes
RouteMethodsWhat it does
/api/machinesGET,POSTList Machines
/api/machines/joinPOSTJoin
/api/machines/join-tokenPOSTMint Join Token
/api/machines/pairPOSTHq Pair
/api/machines/{key}DELETERemove Machine
/api/machines/{key}/probePOSTProbe
/api/machines/{key}/syncPOSTSync Now
/api/machines/{key}/testPOSTTest Data Plane
me3 routes
RouteMethodsWhat it does
/api/meGETMe
/api/me/passwordPOSTChange Password
/api/me/usernamePOSTChange Username
model1 route
RouteMethodsWhat it does
/api/model/activateDELETE,POSTActivate
models1 route
RouteMethodsWhat it does
/api/modelsGETModels
overview1 route
RouteMethodsWhat it does
/api/overviewGETOverview
points1 route
RouteMethodsWhat it does
/api/points/{collection}/{stem}GET,POSTGet Points
projects3 routes
RouteMethodsWhat it does
/api/projectsGET,POSTList Projects
/api/projects/{slug}GETGet Project
/api/projects/{slug}/classesGET,PATCHGet Classes
promote1 route
RouteMethodsWhat it does
/api/promote/{stem}POSTPromote
promote_testset1 route
RouteMethodsWhat it does
/api/promote_testset/{stem}POSTPromote Testset
retrain1 route
RouteMethodsWhat it does
/api/retrainDELETE,GET,POSTStart
root1 route
RouteMethodsWhat it does
/GETIndex
runs9 routes
RouteMethodsWhat it does
/api/runsGETRuns
/api/runs/{run}GETRun Detail
/api/runs/{run}/curveGETRun Curve
/api/runs/{run}/imagesGETRun Images
/api/runs/{run}/logGETRun Log
/api/runs/{run}/notePOSTSet Note
/api/runs/{run}/peekGETRun Peek
/api/runs/{run}/restore/{stem}POSTRestore
/api/runs/{run}/snapshotGETSnapshot
sessions3 routes
RouteMethodsWhat it does
/api/sessionsGETList Sessions
/api/sessions/revoke-othersPOSTRevoke Other Sessions
/api/sessions/{sid}DELETERevoke Session
setup6 routes
RouteMethodsWhat it does
/api/setup/claimPOSTClaim
/api/setup/extras/laPOSTExtras La
/api/setup/extras/stackPOSTExtras Stack
/api/setup/factsGETFacts
/api/setup/instancePOSTInstance
/api/setup/statusGETStatus
state1 route
RouteMethodsWhat it does
/api/stateGETState
testset1 route
RouteMethodsWhat it does
/api/testset/{stem}DELETE,POSTTo Testset
train2 routes
RouteMethodsWhat it does
/api/trainDELETE,POSTStart
/api/train/optionsGETOptions
truth1 route
RouteMethodsWhat it does
/api/truth/{stem}POSTSet Truth
upload1 route
RouteMethodsWhat it does
/api/uploadPOSTUpload
users3 routes
RouteMethodsWhat it does
/api/usersGET,POSTList Users
/api/users/statsGETUser Stats
/api/users/{username}DELETEDelete User
version1 route
RouteMethodsWhat it does
/api/versionGETVersion

View on GitHub Read the case study