[ INTEGRATION SURFACE · BETA ] ━━ API, SDKs, and event payloads may change between releases. Read the versioning policy

TypeScript SDK

@cheetahengineering/cheetah-client — install from GitHub Packages, connect, typed usage, and error handling.

▸ BETA
▸ APPLIES TO
cheetah service >=0.0.132

@cheetahengineering/cheetah-client wraps the open REST API for Node ≥ 18. ESM, Promise-based throughout, fully typed.

Install#

The package is published to the GitHub Packages registry, not public npm. You need a GitHub token with read:packages scope.

In your project's .npmrc:

@cheetahengineering:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=${GITHUB_TOKEN}

In package.json, pin the version matching your cell's cheetah-service:

"@cheetahengineering/cheetah-client": "0.0.132"

Install with the token in the environment:

GITHUB_TOKEN=$(gh auth token) pnpm install

${GITHUB_TOKEN} must be set at install time — without it the registry returns a 404 for the package, which is GitHub's way of saying "unauthorized."

Connect#

import { CheetahClient } from "@cheetahengineering/cheetah-client";

const client = new CheetahClient("http://cheetah-cell.local:8000");

console.log(await client.health());

The constructor takes the cell's base URL and an optional { timeout } in milliseconds (default 30000 — note the unit differs from the Python SDK's seconds). Every method returns a Promise; there is no close method to call.

The public surface#

How the SDK maps onto the API reference. Method names are camelCase; response fields mirror the wire format and stay snake_case (run.serial_number):

Method Endpoint
client.health() GET /health
client.programs.list() · .get(programId) GET /programs · GET /programs/{program_id}
client.programs.listAllRuns({...}) GET /runs — options: programId, status, serialNumber, updatedSince, limit, offset
client.programs.listRuns(programId, {...}) GET /programs/{program_id}/runs
client.programs.getRun(runId) · .getActiveRun() GET /runs/{run_id} · GET /runs/active
client.programs.getRunQualityReport(runId) GET /runs/{run_id}/quality-report
client.programs.downloadClSweepCsv(runId, stepIndex) GET /runs/{run_id}/steps/{step_index}/cl_sweep.csv — returns string
client.sensor.getFrame(frameId) · .getFrameFiles(frameId) GET /sensor/frames/{frame_id} · …/files
client.sensor.downloadPly(frameId, raw = false) GET …/file.ply (raw…/file.raw.ply) — returns ArrayBuffer
client.sensor.downloadPng(frameId, luminance = false) GET …/file.png (luminance…/file.luminance.png) — returns ArrayBuffer
client.sensor.downloadNpy(frameId) GET …/file.npy — returns ArrayBuffer
client.webhooks.list() · .get() · .create({...}) · .update() · .delete() /webhooks management
client.webhooks.test(webhookId) POST /webhooks/{webhook_id}/test
client.webhooks.listDeliveries(webhookId, {...}) · .getDeliveryDetail(deliveryId) · .retryDelivery(deliveryId) Delivery log and replay

The SDK exposes more than this — see scope for what that means.

Putting it together#

Recent inspection results with their QC outcomes:

import { CheetahClient } from "@cheetahengineering/cheetah-client";

const client = new CheetahClient("http://cheetah-cell.local:8000");

const page = await client.programs.listAllRuns({ status: "completed", limit: 10 });
for (const run of page.runs) {
  const report = await client.programs.getRunQualityReport(run.id);
  if (report.quality_report) {
    console.log(run.serial_number, run.revision, report.quality_report.status);
  }
}

Every response is typed — page is a ProgramRunSummaryList, and the types are all exported from the package root. For the production polling pattern behind this loop, see incremental sync.

Errors#

All SDK errors derive from CheetahError:

Class Thrown when
ConnectionError The cell can't be reached — network problem, not an API one
APIError Any HTTP error; carries statusCode, code, params from the error envelope
NotFoundError 404s — a subclass of APIError with resource and resourceId
import { CheetahClient, NotFoundError } from "@cheetahengineering/cheetah-client";

const client = new CheetahClient("http://cheetah-cell.local:8000");

try {
  await client.programs.getRun("0196a3f2-7c1e-7d2a-b3a4-9e8d1c2b3a4f");
} catch (err) {
  if (err instanceof NotFoundError) {
    console.error(`no such ${err.resource}: ${err.resourceId}`);
  } else {
    throw err;
  }
}

Which failures are worth retrying is covered in Errors and retries.

Next#

▸ LAST VERIFIED Fri Jun 12 2026 00:00:00 GMT+0000 (Coordinated Universal Time) ▸▸ /content/developers/client-libraries/typescript.md
▸ DOCS UNDER CONSTRUCTION LAST UPDATED 2026-07-25 ▸ CHANGELOG