Models
Per-model wire contracts — the shapes the NT inference API enforces for each base model.
Draft — pending review.
The NT inference API supports multiple base models. Each base has a different input shape — different state dimensions, different camera names, different image resolution. These per-model shapes are the contract.
When you call Robot(model="so101").run(...), the API resolves the model, reads its contract, and validates your first observation frame against it. If the shapes don't match, the connection closes with code 4422 before any inference runs.
What a contract is
A contract declares five things about a model's wire interface:
| Field | Type | What it means |
|---|---|---|
state_shape | list of int | Expected dimensions of the joint-state vector your read_state() callback returns |
state_dtype | str | Expected dtype ("float32") |
cameras | object | {required: [...], expected: [...]} — required camera keys must be present in your images dict (missing one closes 4422); expected camera keys zero-fill if missing |
image_shape | list of int | Expected shape of each camera array, CHW ([C, H, W]) |
action_shape | list of int | Shape of each action chunk the server returns ([horizon, action_dim]) |
The first four fields are checked on your first observation frame. action_shape is informational — the server outputs it, not you.
How to read the contract for your model
curl -H "Authorization: Bearer $NT_API_KEY" \
https://nt-registry-production.up.railway.app/v1/models/ft_6341c5_d13da9The response includes the full contract block. Fine-tune entries return the resolved contract inherited from their base. The registry is an always-on service — the curl returns in about a second without waking the GPU container.
Coercion within a contract
The API coerces missing data within a contract, but not for every camera. If your images dict is missing a camera listed in cameras.expected (and not in cameras.required), the server fills that slot with zeros and the connection stays alive. A missing camera listed in cameras.required closes 4422 — contract_mismatch.camera_missing — instead.
Coercion does not apply across contracts. An [8]-dimensional state vector sent to a model expecting [14] closes 4422, not coerced.
Choosing a model
Pick the model whose embodiment matches your hardware.
- MA2-SO-101 — SO-101 single-arm, 6D state, 2 cameras