LanguagePython ≥ 3.10 SDK0.1.0 APIv1

Workloads API

Submit requirements. Nodus matches a nodus:… catalog route, runs to verified completion, and recovers through reclaim. You never pick a supplier.

# Quick start

Run a job on infrastructure you never picked. Three steps, about a minute.

  1. Install the SDK

    The distribution is nodus_compute and the import is nodus, the same split as scikit-learn and sklearn. Python 3.10 or newer; httpx is the only dependency.

    shell
    pip install nodus_compute

    Source is on GitHub.

  2. Create an API key

    Open the console and create a key under Access. Copy it then. It is stored as a hash and never shown again. Export it:

    shell
    export NODUS_API_KEY=nk_live_your_key_here
  3. Run something

    Describe the work and the budget. Nodus picks the infrastructure, runs it, and resumes it if the capacity is reclaimed.

    quickstart · python ~/your-app
    # export NODUS_API_KEY=nk_live_…
    >>> import nodus
    >>>
    >>> with nodus.Client() as client:
    ...     wl = client.run(
    ...         image="pytorch/pytorch:2.6.0-cuda12.4-cudnn9-runtime",
    ...         command=["python", "train.py"],
    ...         budget=50,
    ...     )
    ...     done = client.wait(wl.id)
    ...     print(done.status, done.spend_usd)

    That is the whole surface worth setting by hand: an image, a command, and a budget. Everything else has a default. See what the API needs.

Two things that will bite you

  • Your image must ship curl, wget, or python3. Fetching the runner with the first of the three it finds is how your container gets bootstrapped. The default, python:3.11-slim, carries python3; ubuntu:22.04 carries none of them (measured 2026-08-29), so a stock Ubuntu box rents and then runs nothing.
  • Budget is a hard cap, not a warning. Nothing is withheld from it: routing rejects any offer whose expected cost to completion exceeds what is left (over_budget), and the same check runs again against the live figure immediately before capacity is reserved. Omit budget and the run is bounded only by your account's spend cap.

# What the API needs

Three fields to set deliberately. Only command has no default at all; the other two have one you should not lean on. Everything else is either defaulted or derived, and a few things are accepted but not yet acted on. Those are listed too, because a silent no-op is worse than a missing feature.

FieldDefaultWhat it does
image python:3.11-slim The container the work runs in. The default bootstraps, but it is a Python base image and not a runtime for your work. See the warning above.
command required The argv the runner executes. No default; a single-stage job without one rents a machine and runs nothing.
budget none Hard cap on cost to completion. Omitted, the run is bounded only by your account's spend cap; the SDK warns when you leave it out.
Optional, and what Nodus defaults them to
FieldDefaultWhat it does
model "" A memory hint only. The string is matched for a size token (70B, 13B…) to pick a memory floor; nothing else reads it.
peak_memory_gb from model, else 40 A hard filter and a fit penalty. Too low and the run runs out of memory; too high and you pay for a larger machine.
expected_runtime_hours 1 Drives expected cost, deadline feasibility, the bid arithmetic and the checkpoint cadence cap.
compute_class accelerator vm is how you reach CPU and batch capacity.
continuity checkpointed ephemeral refuses interruptible capacity; restartable resumes at a unit boundary rather than a checkpoint.
finish_by none An absolute RFC 3339 instant, not a duration. With no deadline the router puts its whole time weight into cost.

Accepted today, not yet acted on

  • data_regions: the SDK sends it inside requirements, where the control plane does not model it, so it is dropped. The field the router does filter on (rejecting an offer outside the listed regions) is policy.data_regions — reach it with policy={"data_regions": […]}.
  • env: the SDK sends it. The payload has no field for it, so it is dropped.
  • Unknown fields in general. The request decoder does not reject them, so a typo returns 202 and is discarded.

Fit class, catalog SKU, disk, placement, checkpoint cadence and the fallback graph are all derived. They are reported back on the route, never submitted.

# Playground

Describe the work and its constraints, not a machine SKU, and see the exact call it produces. This page makes no API request and reserves no capacity: the route and lifecycle below are a simulation of the decision Nodus makes, shown so the shape of the response is legible before you have a key. It quotes no prices. Rates are per account during the pilot.

The brief below is the one this repository's own demo submits: python train.py at 68 GB for twelve hours against a $60 cap. That script is a real program with state worth carrying. It writes its weights every epoch and, on restart, reads them back and continues. Interrupt it and it resumes at the epoch it reached. That is the only way a checkpoint claim is checkable.

Must ship curl, wget, or python3. The runner fetches itself onto the host with one of them, so an image carrying none is billed for a host that never starts. ubuntu:22.04 ships none of the three.

Request

                
Simulated response idle
workload
-
catalog sku
-
fit
-
status
-
generation
-

# CLI

The nodus command ships with the SDK, reads the same environment, and submits one-off briefs.

cli ~/your-app
$ export NODUS_API_KEY=nk_live_…

# submit and block until the work is done
$ nodus run \
      --model "7B fine-tune" \
      --peak-memory-gb 80 --hours 18 --budget 400 \
      --continuity checkpointed \
      --wait --timeout 72000 \
      -- python train.py --epochs 10

# inspect without blocking
$ nodus list --status active
$ nodus get wl_9f3c1b2a --wait
$ nodus events wl_9f3c1b2a --follow
$ nodus artifacts wl_9f3c1b2a
$ nodus cancel wl_9f3c1b2a

Everything after -- runs inside the workload. --wait exits non-zero on failed or cancelled, so it composes in CI.