Integration
How an execution machine joins the fleet and drains the queue.
Lifecycle
An executor enrols itself with a one-time token, lands in PENDING, and stays inert until an operator approves it. After approval it loops: pull a job, run it, heartbeat while running, submit the result.
- 1Operator mints an enrollment token (Executors → Add node)
- 2Worker POSTs /executors/register → receives its bearer token, status PENDING
- 3Operator approves the node
- 4Worker polls /pull → claims one job at a time
- 5Worker heartbeats to extend the lease and report progress
- 6Worker submits result + files; job becomes SUCCEEDED or FAILED
Authentication
Every call below carries the bearer token issued at registration: Authorization: Bearer ufx_…. The plaintext is returned exactly once — only its SHA-256 hash is stored, so a lost token means re-enrolling.
A node that is not APPROVED gets 403 with a code field naming its state. That is expected while waiting for approval — keep polling rather than exiting.
Endpoints
{
"enrollmentToken": "ufe_…",
"name": "studio-mac",
"hostname": "timmys-mbp.local",
"backend": "MLX_SWIFT",
"capabilities": ["T2I", "EDIT", "INTERLEAVE", "VQA"],
"maxPixels": 4194304,
"concurrency": 1,
"specs": { "chip": "Apple M5 Pro", "memoryBytes": 68719476736, "quantization": "8bit-g64" }
}201 { "executorId": "…", "token": "ufx_…", "status": "PENDING" }The enrollment token is burned atomically, so two machines racing the same token cannot both enrol.
{ "capabilities": ["T2I","VQA"], "maxPixels": 4194304 } // optional200 {
"jobId": "…", "kind": "T2I", "params": { … },
"inputs": [{ "id": "…", "url": "/api/integration/assets/…", "filename": "a.png", "mimeType": "image/png" }],
"leaseUntil": "2026-08-27T…Z", "attempt": 1
}
204 // nothing this node can runCapabilities re-advertised here take effect immediately — lower maxPixels after an OOM without re-enrolling. Claiming is atomic; two executors pulling at once never get the same job.
{ "progress": 0.42, "message": "step 21/50" } // both optional200 { "leaseUntil": "…", "canceled": false }Extends the lease by 1200s. This is also the only way to learn about cancellation — when "canceled" is true, abort and stop; do not submit.
multipart/form-data
payload = {"status":"SUCCEEDED","text":"…","metrics":{"durationMs":332000,"peakMemoryBytes":24030000000}}
files = <one or more binary parts>200 { "ok": true, "assets": 1 }Terminal — a job accepts exactly one submit. Image kinds attach files; VQA sends text only. If the lease was reclaimed while you were working, this returns 409 and the result is discarded.
200 binary
Fetch a job's input images. Scoped to INPUT assets only.
Leases and failure
A claimed job carries a lease of 1200s. Heartbeat to extend it — a 2048² render measured 332s on MLX 8-bit and 623s on PyTorch/MPS, so a long job outlives its initial lease without one.
If the lease expires, the platform reclaims the job on the next pull from any node and re-queues it. After maxAttempts it is failed outright rather than looped forever — a machine that OOMs on a job will OOM on the retry too.
Crashing mid-run is therefore safe: do nothing, and the job returns to the queue. What you must not do is submit and then crash — submit is the commit point.
Job kinds
| Kind | Params | Submits |
|---|---|---|
| T2I | prompt, width, height, think, steps, cfgScale, timestepShift, seed | one image |
| EDIT | prompt, inputAssetIds[], imgCfgScale, + sampling | one image |
| INTERLEAVE | prompt, resolution, + sampling | several images + text |
| VQA | question, inputAssetIds[], maxNewTokens, temperature, topP, think | text only |