Self-host

Your GPU, our gate.

Generate on your own GPU with any model. NIUA checks the result against a contract, replays it in physics on CPU, and signs a receipt you can verify offline. Simulation only, no hardware tested

Make a robot motion clip on your own GPU, have NIUA check it, and verify the signed result yourself. For robotics and simulation teams who run their own models.

  1. 01 Get a key from the console

    export NIUA_API_KEY=... # https://ohao.tech/niua/console/keys
  2. 02 Check your clip with niua-runner (from Ohao, on request)

    niua-runner check clip.csv --contract motion.g1-safe@1
  3. 03 Verify the receipt offline

    niua-runner keys --out keys.json && niua-runner verify receipt.json --file clip.csv --keys keys.json
Gate
NIUA's checker. It runs a contract on your file and says pass or fail, with a fix for each fail.
Contract
the published rules a file must meet, by name and version. Each rule has a threshold and a fix.
MuJoCo replay
the gate plays a G1 clip on a simulated robot, on CPU, and checks that it stays upright.
Receipt
a signed note that this exact file passed this exact contract. Anyone can verify it, offline.

For agents: llms.txt · runner-run.json (this real session) · OpenAPI

  1. 01

    Your GPU

    Your generator, on your machine. The gate itself runs on CPU and spends nothing on GPUs. Hosted media generation is a separate, legacy paid add-on.

    niua-gpu generate motionbricks: runs on a GPU; idle clips pass after repair, walking: next

  2. 02

    Artifact

    A G1 motion clip (niua.g1-motion/v1), a URDF bundle, a GLB prop or WAV audio.

    splat scenes: next

  3. 03

    NIUA gate

    Contract checks plus a MuJoCo replay, on CPU. On ohao.tech, or on your server.

    niua-runner check

  4. 04

    Signed receipt

    Ed25519 over the file hash and the contract. Anyone can verify it, offline.

    niua-runner verify

niua-runner, run for real

A real session against the production gate on 2026-10-15: the G1 clip passes motion.g1-safe@1, and the receipt verifies offline with the saved key.

$ niua-runner check fixed.csv --contract motion.g1-safe@1 --out receipt.json
PASS motion.g1-safe@1  fixed.csv
  receipt cb35bd7c-543d-4f80-a49b-eb291349e9b3  signature valid (checked here)  covers this file yes
  sha256 349ca008168b1c184dccf2df4f07e98b4972dd4ea2abdf0740ad575c8e7f6016
  wrote receipt.json  ·  anyone can re-check it: https://api.ohao.tech/api/v1/receipts/cb35bd7c-543d-4f80-a49b-eb291349e9b3

$ niua-runner verify receipt.json --file fixed.csv --keys keys.json
signature valid  key niua-receipt-2026-10  (offline, keys.json)
  pass motion.g1-safe@1  issued 2026-10-15T19:55:29Z  checker niua-gate/1.0.0
  fixed.csv sha256 349ca008168b1c184dccf2df4f07e98b4972dd4ea2abdf0740ad575c8e7f6016 matches the receipt

receipt cb35bd7c · verify it · fixed.csv · runner-run.json

Fixed before passing: raw.csv failed on joints.position_limits, joints.velocity_limits, contact.ground_penetration, feet.skate.

The fail, as the runner printed it
$ niua-runner check raw.csv --contract motion.g1-safe@1
FAIL motion.g1-safe@1  raw.csv  (6 to fix)
  joints.position_limits  waist_pitch_joint
    expected within [-0.5200, 0.5200] rad; got 0.7841 rad at 2.64 s
    fix: Keep the joint inside its range: clamp it, or retarget so the pose needs less of it.
  joints.position_limits  right_elbow_joint
    expected within [-1.0472, 2.0944] rad; got 2.1585 rad at 2.00 s
    fix: Keep the joint inside its range: clamp it, or retarget so the pose needs less of it.
  joints.velocity_limits  right_elbow_joint
    expected at most 37.0 rad/s (1× Unitree's 37 rad/s); got 50.1 rad/s at 2.00 s
    fix: Slow the move down (retime it), or remove the one-frame pop with a short median filter.
  contact.ground_penetration  left_ankle_roll_link
    expected no geometry deeper than 0.010 m into the floor; got 0.040 m deep at 1.00 s
    fix: Lift the root on those frames so the lowest foot point rests on the floor.
  feet.skate  left_ankle_roll_link
    expected a planted contact point (within 0.02 m of the floor) slides at most 0.2 m/s; got 0.34 m/s at 0.86 s
    fix: Lock the planted foot: remove the root drift on frames where the foot is on the floor.
  feet.skate  right_ankle_roll_link
    expected a planted contact point (within 0.02 m of the floor) slides at most 0.2 m/s; got 0.32 m/s at 0.88 s
    fix: Lock the planted foot: remove the root drift on frames where the foot is on the floor.

Get the runner

A Node CLI and a Docker image (node:22 with Python, MuJoCo and pyarrow for the dataset recipes, all on CPU). It sends your file to the gate you point it at and nowhere else; set NIUA_API_URL to use your own NIUA. niua-runner is proprietary and not published: customers get it from us, on request today.

export NIUA_API_KEY=...                                   # from the console
niua-runner check clip.csv --contract motion.g1-safe@1    # upload, check, verify the receipt locally
niua-runner keys --out keys.json                          # once
niua-runner contracts --out contracts.json                # once: the contracts NIUA publishes
niua-runner verify receipt.json --file clip.csv --keys keys.json --contracts contracts.json   # offline
niua-runner contracts motion.g1-safe@1                    # the exact rules that receipt met
niua-runner check arm.zip --contract urdf.sim-ready@1 --out receipt.json
niua-runner simulate receipt.json                         # sweep the robot's joints in MuJoCo, signed
docker run --rm -e NIUA_API_KEY -v "$PWD:/work" niua-runner check clip.csv --contract motion.g1-safe@1

Ask for niua-runner

Two ways to run the gate

Use ohao.tech

The hosted gate, on CPU

Contract checks and the MuJoCo replay run on our CPUs; receipts are signed with our published key. Point niua-runner at it with an API key, or connect your agent over MCP.

claude mcp add --transport http niua https://mcp.ohao.tech/mcp

Other agents · REST API

Self-host everything

The same gate, inside your network

The container that runs ohao.tech, with receipts signed by your key. Your files never leave your network. The runner and the gate image are offered to customers by arrangement; NIUA's own code is not published.

Gateway
One container: the checker, contracts, MuJoCo on CPU, receipts and the REST API. Run it with NIUA_GENERATION=off: no GPU, no Modal, no LLM key.
MCP server
A second container your agents connect to, pointed at your gateway with NIUA_API_URL.
Postgres
Checks, receipts, contracts and API keys.
S3-compatible storage
Uploaded artifacts. R2, or AWS S3 and MinIO through R2_ENDPOINT_URL.
Your signing key
An Ed25519 key you hold. Receipts are signed with it and verify against your own published key.

Talk to us about self-hosting

Motion · live

The clip in the session, with its evidence.

Each claim opens to its evidence: a demo you can run, the file we used, and a signed receipt you can verify. Simulation only, no hardware tested

  1. A humanoid clip passes a physics replay

    simulation only, no hardware tested

    A real NVIDIA Unitree G1 humanoid clip passes motion.g1-safe@1 in a MuJoCo physics replay, run on CPU: every joint inside its range and speed limit, feet on the floor without sliding, upright the whole time. Four mistakes we planted were fixed first, each from a failure NIUA named.

    Measured 2026-10-15. tools/g1-motion/record_production.mjs: the production gate checked the published clips; MuJoCo 3.16.0, Menagerie unitree_g1, timestep 0.002 s, joint PD kp 500 kv 10.32, root unactuated, sampled at 50 Hz. Source: the first 3.5 s of NVIDIA GR00T-WholeBodyControl macarena_001__A545. production.json