@chassis-cloud/sdk
v0.1.5
Published
Official TypeScript / JavaScript SDK for the Chassis GPU cloud API by OkeyMeta Ltd
Maintainers
Readme
@chassis-cloud/sdk
Official TypeScript / JavaScript client for the Chassis public API (/api/v1).
Default base URL: https://chassis.okeymeta.com.ng/api/v1
npm: https://www.npmjs.com/package/@chassis-cloud/sdk
Install
npm install @chassis-cloud/sdkAuth
Create an API key in the Chassis console under API Keys. Keys look like chs_… and are shown once. Send them as:
Authorization: Bearer chs_YOUR_KEYQuickstart
import { Chassis } from '@chassis-cloud/sdk'
const chassis = new Chassis({
apiKey: process.env.CHASSIS_API_KEY!,
})
const gpus = await chassis.listGpus()
console.log(gpus.map((g) => `${g.displayName} $${g.pricePerHourUsd}/hr`))
const instance = await chassis.spinUp({
gpuSkuId: gpus[0].id,
name: 'gpu-host-01',
imageName: 'ghcr.io/YOUR_ORG/your-gpu-app:latest',
ports: '8080/http,22/tcp',
})Example: list available GPUs
const gpus = await chassis.listGpus()
for (const gpu of gpus) {
console.log({
id: gpu.id,
name: gpu.displayName,
memoryGb: gpu.memoryGb,
pricePerHourUsd: gpu.pricePerHourUsd,
spotPricePerHourUsd: gpu.spotPricePerHourUsd,
stockStatus: gpu.stockStatus,
secureAvailable: gpu.secureAvailable,
})
}
const gpu = gpus.find((g) => g.displayName.includes('4090')) ?? gpus[0]
// use gpu.id as gpuSkuId on createInstance / spinUp / createCluster / createEndpointExample: host a GPU service
Any CUDA app — APIs, media tools, notebooks, batch workers — not only training.
const gpus = await chassis.listGpus()
const instance = await chassis.spinUp({
gpuSkuId: gpus[0].id,
name: 'gpu-host-01',
imageName: 'ghcr.io/YOUR_ORG/your-gpu-app:latest',
containerDiskGb: 50,
ports: '8080/http,22/tcp',
env: { MODEL_ID: 'your-model' },
})
const detail = await chassis.getInstance(instance.id)
console.log(detail.publicIp, detail.connection, detail.status)
// Point your clients at publicIp / published ports
await chassis.stop(instance.id)Example: training job
Spin up a dedicated GPU, run your trainer on the instance, then stop billing.
const gpus = await chassis.listGpus()
const gpu = gpus.find((g) => g.displayName.includes('A100')) ?? gpus[0]
const instance = await chassis.spinUp({
gpuSkuId: gpu.id,
name: 'finetune-bert',
gpuCount: 1,
imageName: 'pytorch/pytorch:2.1.0-cuda11.8-cudnn8-devel',
containerDiskGb: 80,
ports: '8888/http,22/tcp',
})
console.log('running', instance.id, instance.status)
// SSH or open Jupyter on the instance, then run train.py
await chassis.stop(instance.id)Example: multi-node cluster
const gpus = await chassis.listGpus()
const cluster = (await chassis.createCluster({
name: 'dist-train',
gpuSkuId: gpus[0].id,
nodeCount: 4,
gpusPerNode: 1,
imageName: 'pytorch/pytorch:2.1.0-cuda11.8-cudnn8-devel',
})) as { id: string }
console.log(await chassis.getCluster(cluster.id))
// Nodes receive CHASSIS_CLUSTER_ID, CHASSIS_NODE_RANK, CHASSIS_NODE_COUNT
await chassis.stopCluster(cluster.id)
// await chassis.terminateCluster(cluster.id)Example: serverless endpoint
const gpus = await chassis.listGpus()
const endpoint = await chassis.createEndpoint({
name: 'text-infer',
gpuSkuId: gpus[0].id,
workersMin: 0,
workersMax: 3,
})
const result = await chassis.runSync(endpoint.id, {
input: {
prompt: 'Summarize Chassis in one sentence.',
max_tokens: 128,
},
})
console.log(result)
const job = (await chassis.run(endpoint.id, {
input: { prompt: 'hello' },
})) as { id: string }
const status = await chassis.getJob(endpoint.id, job.id)
console.log(status)Instance options (createInstance / spinUp)
| Field | Required | Notes |
|-------|----------|--------|
| gpuSkuId | yes | Chassis SKU UUID from listGpus() |
| name | yes | Instance name |
| gpuCount | no | Default 1, max 8 (and SKU maxGpuCount) |
| imageName | no | Container image |
| containerDiskGb | no | Default 50 |
| volumeGb | no | Ephemeral volume GB |
| networkVolumeId | no | Chassis network volume UUID |
| registryCredentialId | no | Chassis registry credential UUID |
| cloudType | no | 'SECURE' | 'COMMUNITY' |
| ports | no | e.g. "8080/http,22/tcp" |
| env | no | String map passed into the container |
| startAfterCreate | no | Default true (spinUp forces true) |
Methods
GPUs & instances
| Method | HTTP |
|--------|------|
| listGpus() | GET /gpus |
| listInstances() | GET /instances |
| createInstance(input) | POST /instances |
| spinUp(input) | POST /instances (startAfterCreate: true) |
| getInstance(id) | GET /instances/:id |
| getInstanceLogs(id, tail?) | GET /instances/:id/logs |
| updateInstance(id, input) | PATCH /instances/:id |
| start(id) | POST /instances/:id/start |
| stop(id) | POST /instances/:id/stop |
| restart(id) | POST /instances/:id/restart |
| terminate(id) | DELETE /instances/:id |
Clusters (multi-node)
| Method | HTTP |
|--------|------|
| listClusters() | GET /clusters |
| createCluster(input) | POST /clusters |
| getCluster(id) | GET /clusters/:id |
| startCluster(id) | POST /clusters/:id/start |
| stopCluster(id) | POST /clusters/:id/stop |
| terminateCluster(id) | DELETE /clusters/:id |
Create a cluster with name, gpuSkuId, nodeCount (2–8), and optional gpusPerNode, imageName, networkVolumeId, ports. Nodes get CHASSIS_CLUSTER_ID, CHASSIS_NODE_RANK, and CHASSIS_NODE_COUNT env vars.
Templates, volumes, registries
| Method | HTTP |
|--------|------|
| listTemplates() / createTemplate(input) | GET / POST /templates |
| updateTemplate(id, input) / deleteTemplate(id) | PATCH / DELETE /templates/:id |
| listVolumes() / createVolume(input) | GET / POST /volumes |
| updateVolume(id, input) | PATCH /volumes/:id |
| listRegistries() / createRegistry(input) | GET / POST /registries |
Serverless endpoints
| Method | HTTP |
|--------|------|
| listEndpoints() | GET /endpoints |
| createEndpoint(input) | POST /endpoints |
| getEndpoint(id) / updateEndpoint(id, input) | GET / PATCH /endpoints/:id |
| deleteEndpoint(id) | DELETE /endpoints/:id |
| run(endpointId, body) | POST /endpoints/:id/run |
| runSync(endpointId, body, waitMs?) | POST /endpoints/:id/runsync |
| getEndpointHealth(id) | GET /endpoints/:id/health |
| getJob(endpointId, jobId) | GET /endpoints/:id/jobs/:jobId |
| cancelJob(endpointId, jobId) | POST /endpoints/:id/jobs/:jobId/cancel |
Serverless helpers:
const health = await chassis.getEndpointHealth(endpoint.id)Create options also accept env, interruptible, and publicIp.
Responses use { data: … } / { error: "…" }. Failures raise ChassisError with a clear .message.
Docs
Human setup guide: https://chassis.okeymeta.com.ng/docs
License
MIT · OkeyMeta Ltd
