CLI and SDK

Rent GPU machines from a terminal with the nodelodge command, or from your own code with the TypeScript and Python SDKs.

The nodelodge command and the SDKs for TypeScript and Python call the Node Lodge API with an API key. They find a Node Lodge Secure machine, launch a session with a maximum cost, give you the SSH command and stop the session.

Before you start

  1. In the console, open Keys and create a key with the scopes workloads:read, workloads:write and billing:read.
  2. Set its Spending limits (per session and total). Node Lodge refuses any session that would go past one.
  3. Have an SSH key pair ready. See SSH keys.

Every session reserves its maximum cost on your organization credit at launch, as its budget. It is billed for the real time it runs, never past the budget. See Billing.

Command line

Requires Node.js 22 or newer.

Install

mkdir -p ~/.local/bin && cd ~/.local/bin
curl -fsSLO https://nodelodge.com/downloads/nodelodge.mjs
curl -fsSLO https://nodelodge.com/downloads/nodelodge.mjs.sha256
sha256sum -c nodelodge.mjs.sha256 && mv nodelodge.mjs nodelodge && chmod +x nodelodge

On macOS, check with shasum -a 256 -c nodelodge.mjs.sha256. Make sure ~/.local/bin is on your PATH.

Log in

nodelodge login

Paste the key when asked. It is checked, then saved readable by you only, in your configuration folder (~/.config/nodelodge on Linux, ~/Library/Application Support/nodelodge on macOS, %APPDATA%\nodelodge on Windows). The key is never typed on the command line, so it stays out of your shell history. In CI, set NODELODGE_API_KEY instead. nodelodge logout removes the saved key.

Find a machine

nodelodge offers --min-vram 48
nodelodge offers --gpu H100 --min-gpus 2

Filters: --gpu <model>, --min-gpus <n>, --min-vram <GB>, --max-price <USD per hour>, --all (machines out of stock too). Offers are listed cheapest first, with their specs, hourly price and location.

Launch, connect, stop

nodelodge balance
nodelodge launch 3f0c8f5e-8c3a-4f39-9a8e-2d9b4c1e7a10 --max-cost 20 --allow 203.0.113.7
nodelodge status 9b2d6a1e-1f5c-4a8e-9a77-3c0f2e6d4b21 --wait
nodelodge raise-budget 9b2d6a1e-1f5c-4a8e-9a77-3c0f2e6d4b21 --max-cost 40
nodelodge stop 9b2d6a1e-1f5c-4a8e-9a77-3c0f2e6d4b21
  • --max-cost is required: the most the session may cost, in USD. It is reserved on your credit, and the session stops before it is spent. Add --hours <n> to stop it after n hours.
  • --environment <id> picks the environment, jupyterlab by default: data-center machines run jupyterlab.
  • raise-budget raises the budget of a running session to a new --max-cost, within the limits of the key.
  • --allow is the public IPv4 address you connect from, or a range up to /24. Only it can reach the machine over SSH.
  • The SSH key is read from ~/.ssh/id_ed25519.pub (then id_ecdsa.pub, id_rsa.pub). Pass another with --ssh-key <file>. It opens this session only and is not saved on your account.
  • status --wait waits until the machine runs, printing each launch step as it starts, then prints its ssh command. With --json, only the session object is printed, with its launch field. status alone lists your live sessions, status --ended your ended ones.
  • stop ends the session: billing stops and the machine and its disk are deleted. Copy your results off the machine first.

Add --json to any command to get the session objects, for scripts:

id=$(nodelodge launch "$OFFER" --max-cost 20 --allow "$MY_IP" --json | jq -r .id)
nodelodge status "$id" --wait --json | jq -r '.ssh.host'

Exit codes: 0 done, 1 refused by Node Lodge (the reason and its code are printed), 2 invalid command line.

TypeScript SDK

Requires Node.js 22 or newer.

npm install https://nodelodge.com/downloads/nodelodge-sdk.tgz
import { ConflictError, NodeLodge, PaymentRequiredError } from '@nodelodge/sdk';

const nl = new NodeLodge({ apiKey: process.env.NODELODGE_API_KEY ?? '' });

const { items } = await nl.offers.list({ minVramGb: 48, bookableOnly: true });
try {
  const session = await nl.sessions.launch({
    offerId: items[0].id,
    maxCostCents: 2000,
    sshPublicKey: 'ssh-ed25519 AAAA... you@laptop',
    allowedCidr: '203.0.113.7',
  });
  let s = await nl.sessions.get(session.id);
  while (!s.ssh) {
    await new Promise((r) => setTimeout(r, 10_000));
    s = await nl.sessions.get(session.id);
  }
  console.log(`ssh ${s.ssh.user}@${s.ssh.host}`);
  // ... run your job ...
  await nl.sessions.stop(session.id);
} catch (err) {
  if (err instanceof ConflictError) console.error(err.code, err.message); // API_KEY_LIMIT
  else if (err instanceof PaymentRequiredError) console.error('Add credit in Billing.');
  else throw err;
}

Amounts are in cents. nl.sessions.raiseBudget(id, 4000) raises the budget of a running session. launch takes an optional environmentId, and nl.environments.list({ offerId }) lists what a Community machine can run. nl.account.funds() returns the credit available for a new session.

Python SDK

Requires Python 3.10 or newer.

pip install https://nodelodge.com/downloads/nodelodge-0.2.0-py3-none-any.whl
import os
import time

from nodelodge import ConflictError, NodeLodge, PaymentRequiredError

with NodeLodge(os.environ["NODELODGE_API_KEY"]) as nl:
    offer = nl.offers.list(min_vram_gb=48, bookable_only=True).items[0]
    try:
        session = nl.sessions.launch(
            offer.id,
            max_cost_cents=2000,
            ssh_public_key=open(os.path.expanduser("~/.ssh/id_ed25519.pub")).read().strip(),
            allowed_cidr="203.0.113.7",
        )
        while (s := nl.sessions.get(session.id)).ssh is None:
            time.sleep(10)
        print(f"ssh {s.ssh.user}@{s.ssh.host}")
        # ... run your job ...
        nl.sessions.stop(session.id)
    except ConflictError as e:      # API_KEY_LIMIT
        print(e.code, e.message)
    except PaymentRequiredError:
        print("Add credit in Billing.")

Models are typed with snake_case fields, for example offer.price_per_hour_cents and session.max_cost_cents. nl.sessions.raise_budget(session.id, 4000) raises the budget of a running session. launch takes an optional environment_id, and nl.environments.list(offer_id=...) lists what a Community machine can run.

Sessions in both SDKs

A session has the same fields in both SDKs (camelCase in TypeScript, snake_case in Python):

Field Meaning
status booked, starting, running, stopping, ended or failed.
maxCostCents The budget: the most the session can cost.
costSoFarCents Billed so far, the final charge once ended.
heldCents The part of the budget still reserved on your credit.
ssh Host, user and port once the machine runs.
stopsAt When the session stops at the latest.
kind session, or reservation for a machine booked as a reservation.
launch While the session starts, its launch steps in order (ordered, allocated, booting, verifying on data-center machines, ready), each done, active or pending. Null once it runs. The step under way: currentLaunchStep(session) in TypeScript, session.launch_step in Python.

What both SDKs do for you

  • Retries: reads and launches are retried on network errors, 429 and 5xx, with exponential backoff, and Retry-After is honored. A launch is sent with an idempotency key, so a retry never starts two sessions. Stopping and raising a budget are not repeated after a failure that may have reached Node Lodge: check the session with get instead.
  • Typed errors: AuthenticationError (401), PaymentRequiredError (402), PermissionError (403), NotFoundError (404), ConflictError (409), RateLimitError (429), ServerError (5xx), NetworkError and TimeoutError. Each API error has a stable code and a message you can show to a person.
  • A failed start costs nothing: if the machine cannot start, the session fails, nothing is billed and its budget is released.
  • Sessions and reservations: on an account that books data-center machines as reservations (RESERVATION_REQUIRED), launch, get, list and stop work the same way, and kind is reservation.
  • Your key stays private: it is sent only to Node Lodge over HTTPS, and never appears in an error message.

To drive sessions from an AI agent instead, see Use Node Lodge from an AI agent (MCP).

Last updated View as Markdown

Results appear as you type. Arrow keys move through them.