Workloads API
Submit work by outcome. Nodus matches a nodus:…
catalog route, runs toward completion, and recovers when capacity is reclaimed.
You never pick a wholesale supplier.
# Playground
Describe the work and its constraints, not a machine SKU.
Watch Nodus match a catalog route, run with checkpoints,
and recover when capacity is reclaimed. Same lifetime as
make demo: match → cost →
completion. Customer surface shows nodus:…
only; no wholesale brands. No API key required.
- workload
- -
- catalog sku
- -
- fit
- -
- est. cost
- -
- status
- -
- generation
- -
- spend_usd
- -
# Install
From the monorepo (published PyPI later). Runtime dependency:
httpx.
$ pip install -e sdk/python # or: pip install nodus-sdk (when published)
# Authentication
Every request uses Authorization: Bearer <api_key>.
Create a key in the console with invite
NODUS-LAUNCH.
| Variable | Default | Notes |
|---|---|---|
NODUS_API_KEY |
- | Required for the SDK. |
NODUS_BASE_URL |
https://nodus-api-74it.onrender.com |
Hosted control plane (Render). Cold-starts after idle on the free plan. |
# Quick start
Describe the work and constraints. Hardware fit, placement, and recovery stay with Nodus.
# export NODUS_API_KEY=<from console signup> # export NODUS_BASE_URL=https://nodus-api-74it.onrender.com >>> import nodus >>> >>> with nodus.Client() as client: ... wl = client.run( ... command=["train"], ... requirements={ ... "model": "7B fine-tune", ... "expected_runtime_hours": 1, ... "peak_memory_gb": 24, ... }, ... budget=100, ... continuity={"mode": "checkpointed", "resume_on_interruption": True}, ... ) ... done = client.wait(wl.id) ... print(done.status, done.route.offer_id, done.spend_usd)
# HTTP surface
Canonical contract: design/api.md and
design/openapi.yaml. Mutations require
Idempotency-Key.
| Endpoint | Contract |
|---|---|
POST /v1/workloads | Submit workload revision → 202 + workload_id |
GET /v1/workloads | List workloads for the authenticated tenant |
GET /v1/workloads/{id} | Status, customer route (nodus:…), spend |
GET /v1/workloads/{id}/events | Ordered lifecycle events |
GET /v1/workloads/{id}/ledger | Customer-safe ledger evidence + settlement |
POST /v1/workloads/{id}/cancel | Safe stop |
GET /v1/workloads/{id}/artifacts | Verified checkpoint / output manifests |
PUT /v1/webhooks | Register signed customer webhook endpoint |
# Python client
| Method | Purpose |
|---|---|
Client.run(...) | Submit from requirements / budget / continuity |
Client.get(id) | Fetch current workload |
Client.wait(id) | Poll until terminal |
Client.events(id) | Lifecycle event page |
Client.cancel(id) | Request cancel |
Client.artifacts(id) | List verified artifacts |
Workload.route.offer_id is always a Nodus catalog SKU
(for example nodus:A100-40-us-local). It is never
runpod:, vast:, or a Fleet pool id.
# Workload states
accepted → planning → reserving → provisioning → running → recovering? → completed
↘ cancelled | failed
completed means durable success for the continuity mode
(verified checkpoint / artifact path for checkpointed work).
# Errors
HTTP errors return JSON {"error": "…", "message": "…"}.
The SDK raises nodus.NodusError with
status_code and body.
# Local control plane
$ make demo # embedded lifetime walkthrough $ make compose-up # Postgres + Temporal + MinIO $ make build && ./bin/api $ make smoke-fleet # reclaim against a running API
# Issue API keys
$ export NODUS_DATABASE_URL='postgres://nodus:nodus@localhost:5432/nodus?sslmode=disable' $ ./bin/nodus-key provision -tenant ten_acme -name "Acme AI" -key-name acme-pilot # prints api_key=nk_live_… once; store it; never use ten_dev for partners # full checklist: docs/runbooks/pilot.md