@swarmdo/gpu-sdk
v0.7.2
Published
TypeScript SDK for renting cloud GPUs (H100, A100, L40S, RTX 4090) and running serverless GPU inference with an OpenAI-compatible API. Typed, zero-dependency, Node and browser.
Maintainers
Readme
@swarmdo/gpu-sdk
TypeScript SDK for renting cloud GPUs and running serverless GPU inference. Search H100, A100, L40S and RTX 4090 capacity across providers, rent by the hour, or deploy an autoscaling serverless endpoint and call it over an OpenAI-compatible API.
Fully typed, zero dependencies, works in Node and the browser.
npm install @swarmdo/gpu-sdkQuick start
import { SwarmDoClient } from '@swarmdo/gpu-sdk';
const swarmdo = new SwarmDoClient({ apiKey: process.env.SWARMDO_API_KEY });
// What H100 capacity is available, and what does it cost?
const offers = await swarmdo.catalog.search({ gpuModel: 'H100' });
console.log(offers[0]); // { id, gpuModel, region, pricePerHr, ... }An API key comes from your dashboard at gpu.swarmdo.com. Catalog search works without one.
Serverless GPU inference
Deploy a container, autoscale it from zero, and invoke it. You are billed per GPU-second of execution plus per request.
const endpoint = await swarmdo.serverless.deploy({
name: 'my-llm',
image: 'runpod/worker-v1-vllm:v2.23.0',
gpuClass: 'A100',
region: 'us-east',
minWorkers: 0, // scale to zero when idle
maxWorkers: 3,
env: { MODEL_NAME: 'Qwen/Qwen2.5-0.5B-Instruct' },
});
// OpenAI-compatible chat completions
const reply = await swarmdo.serverless.invoke(endpoint.id, '/openai/v1/chat/completions', {
model: 'Qwen/Qwen2.5-0.5B-Instruct',
messages: [{ role: 'user', content: 'Explain CUDA streams in one sentence.' }],
});Cold starts
A worker starting from zero must pull its image and load model weights, which for a large model is minutes, not seconds. Two ways to avoid paying that on every request:
// 1. Keep a worker warm — no cold start, billed per reserved GPU-second around the clock.
await swarmdo.serverless.scale(endpoint.id, { minWorkers: 1, maxWorkers: 3 });
// 2. Prebake the weights onto a fast-start volume, then pin it at deploy time.
const cache = await swarmdo.serverless.prebaked.create({
hfRepo: 'Qwen/Qwen2.5-7B-Instruct',
region: 'us-east',
sizeGb: 40,
});
// Populating is async — poll until ready before pinning it.
while ((await swarmdo.serverless.prebaked.get(cache.id)).status === 'preparing') {
await new Promise((r) => setTimeout(r, 10_000));
}
await swarmdo.serverless.deploy({ /* … */, prebakedModelId: cache.id });When an endpoint misbehaves
status() returns a derived state rather than raw counters, so you can tell "still loading weights" from "wedged":
const s = await swarmdo.serverless.status(endpoint.id);
// s.state: 'serving' | 'starting' | 'stuck' | 'throttled' | 'failing' | 'idle'
if (s.state === 'stuck') {
await swarmdo.serverless.purgeQueue(endpoint.id); // drop a wedged backlog
await swarmdo.serverless.restart(endpoint.id); // bounce the workers
}
const logs = await swarmdo.serverless.logs(endpoint.id, { limit: 100 });Renting a GPU by the hour
const rental = await swarmdo.rentals.rent({ offerId: offers[0].id });
console.log(rental.endpoints?.ssh);
// Snapshot the workload, move it to a fresh instance, then hand it back.
await swarmdo.rentals.checkpoint(rental.id, { label: 'epoch-3' });
await swarmdo.rentals.migrate(rental.id);
await swarmdo.rentals.terminate(rental.id);What else is on the client
| Namespace | What it does |
| --- | --- |
| catalog | Search offers, list GPU classes and regions |
| rentals | Rent, inspect, checkpoint, migrate, terminate, rate |
| serverless | Deploy, scale, invoke, diagnose, prebaked model caches |
| models | One-click deploy of curated models |
| managed | Call hosted model APIs without managing a GPU |
| storage | Network volumes |
| jobs | Batch container jobs |
| datasets | Dataset registry |
| telemetry | GPU/VRAM/CPU time series and threshold alerts |
| idle | Idle detection and auto-stop policy |
| billing | Balance, transactions, budgets |
| cache | Model weight cache prewarming |
| sla | SLA tier, incidents, credits |
| keys, secrets, teams | Access control |
Error handling
Every non-2xx response throws a SwarmDoError carrying the status and the request that caused it:
import { SwarmDoError } from '@swarmdo/gpu-sdk';
try {
await swarmdo.serverless.deploy({ /* … */ });
} catch (err) {
if (err instanceof SwarmDoError) {
console.error(err.status, err.method, err.path, err.message);
if (err.status === 402) console.error('Out of credit — top up to continue.');
}
}Configuration
new SwarmDoClient({
apiKey: process.env.SWARMDO_API_KEY, // omit for public catalog reads
baseUrl: 'https://gpu.swarmdo.com', // default
fetch: myFetch, // required on Node < 18
});Provider masking
SwarmDo brokers capacity across several upstream clouds. The SDK never exposes which one is behind a given instance or endpoint — you get SwarmDo ids, SwarmDo hostnames and SwarmDo prices, and the routing underneath can change without touching your code.
License
MIT — see LICENSE. The licence covers this client library only; it grants no rights to the SwarmDo platform itself, which is governed by your account's terms of service. "SwarmDo" and the SwarmDo logo are trademarks and are not licensed for use as your own product's name or branding.
Links
- Docs: gpu.swarmdo.com/docs
- Dashboard: gpu.swarmdo.com
- MCP server (use this from Claude Code and other AI agents):
@swarmdo/gpu-mcp
