What the platform injects
Four environment variables arrive in every training container. Your code reads them; it never receives account credentials, cluster addresses, or object-store keys.
Authenticate with
X-StarForge-Token: <token>. The routes also accept
Authorization: Bearer <token>, which is what a client that already has a bearer helper will do
naturally.
The endpoints
All arePOST, all take JSON, all include run_id.
POST /api/ingest/lifecycle — say when training actually began
POST /api/ingest/lifecycle — say when training actually began
starting, running, succeeded, failed.Report running immediately before you hand control to the training entrypoint. The executor’s
own RUNNING is much earlier — it fires before the virtualenv is built and the weights are pulled,
which can be several minutes — so using it as the billing start systematically overcharges.POST /api/ingest/metrics — the curves
POST /api/ingest/metrics — the curves
{"ok": true, "inserted": 2}. Points are already flattened: one scalar per key, per step.
Nested dictionaries and non-scalar values are the caller’s problem to reduce first.POST /api/ingest/hparams — the config panel
POST /api/ingest/hparams — the config panel
POST /api/ingest/validation — sample conversations and reward histograms
POST /api/ingest/validation — sample conversations and reward histograms
user, assistant, env, and reward are the skeleton the console renders. Anything
algorithm-specific — DPO’s rejected completion, SFT’s reference answer — goes in each sample’s
extra and is displayed without the platform needing to know what it is.Large validation rounds split across chunks: set total_chunks and send each with its own
chunk_index.POST /api/ingest/logs — stdout and stderr
POST /api/ingest/logs — stdout and stderr
eof yourself. The platform sets it when the job reaches a terminal state, because a
container killed with SIGKILL never gets the chance.POST /api/ingest/artifact — register what you produced
POST /api/ingest/artifact — register what you produced
checkpoint, hf_export, eval_report, merged_model. format is required and must
not be empty.On a container executor, path must be an object-store URI. A local path stops existing the
moment the container does, and the platform will not guess where it went. GET /api/ingest/artifact/upload-url
hands you a signed URL to PUT to first.POST /api/ingest/hardware and /environment — the System tab
POST /api/ingest/hardware and /environment — the System tab
hardware takes sampled points (GPU utilisation, memory, network). environment takes the static
picture once: package versions, CUDA version, GPU models. environment/nodes reports per-node
hardware for a multi-node run.The SDK collects and sends all three for you unless you pass monitor_hardware=False.POST /api/ingest/benchmark — externally produced scores
POST /api/ingest/benchmark — externally produced scores
For a harness that scores outside the platform and reports back. See
benchmarks for the workflow that surrounds it.
Confirm it worked
Open the job in the console. The Charts tab shows a point within a few seconds of your firstmetrics call. If logs are streaming and charts stay empty, the reporting call is not happening —
check that STARFORGE_ENABLED is 1 inside the container, and that your code reached init().
Why reporting lives in the SDK rather than in the uploaded working directory
Why reporting lives in the SDK rather than in the uploaded working directory
Lifecycle marks and artifact registration are how the platform knows a job really started and what
it produced. If that code shipped inside the user’s own
common/ directory, deleting or breaking
that directory would blind the platform — and the person doing it would have no way to know. It is
also why the module depends on nothing but the standard library: it has to import cleanly inside
any training image, and every dependency is one more way for that to fail.