Authentication
Every request to the training API carries your API key:{"error": "<message>"} with status 400 (a bad request), 401 (no key, or an invalid one), 404 (not found, or not yours) or 503.
Fine-tuning jobs
id, status, created_at, model, dataset_name, batch_size, learning_rate, steps, finetune, lora_rank, lora_alpha, targets, cameras, name, step, loss, error, output_dir. See Fine-tuning for the fields and their limits.
Training sessions
A session is JSON:
id, status (starting, ready, closed or error), created_at, its request’s fields, url, token and error. Poll it until it’s ready, then open a websocket to its url with Authorization: Bearer <token>.
The session’s websocket
Messages are msgpack, with numpy arrays as maps with binary keys:{"__ndarray__": true, "data": <bytes>, "dtype": "<f4", "shape": [...]} (OpenPI’s encoding).
- The server sends
{"info": {"model", "action_horizon", "action_dim", "trainable_params"}}. - You send requests:
{"id": <int>, "op": <op>, ...arguments}. - It answers each, in order:
{"id", "result"}or{"id", "error"}. You may send the next before the last is answered.
data is a list of {"observation": {"image": {camera: <encoded frame>}, "state", "prompt"}, "actions", "weight"}, the frames encoded with codec (a Codec name: "LOSSLESS" for ZPNG, or "CODEC_JPEG_Q90" and the like for JPEG).
Inference
A policy server speaks OpenPI’s websocket protocol:- Connect to its
wss://URL. It sends its metadata, msgpack-encoded. - Send an observation: msgpack, then compressed with zstd (level 1) using Relay’s dictionary,
observation.zdict. It holds OpenPI’s keys plusimage_codec, the codec its frames are encoded with. - It replies with
{"actions", "policy_timing", "server_timing"}, or, if the request failed, a text frame with its traceback, and then closes the connection.
GET /healthz on the same host answers OK once the server is up.