Skip to content

TypeScript SDK

The @novavms/sdk package is a thin, typed wrapper over the NovaVMS REST API (v1). It targets Node.js 20+ and modern browsers. Types are generated from the OpenAPI spec — changes in the API surface show up as TypeScript errors at compile time.

Install

Terminal window
npm install @novavms/sdk

Since v1.0. Requires TypeScript 5.0 or later if you consume the type definitions.

Initialize

import { createClient } from '@novavms/sdk';
const client = createClient({
apiKey: 'sk_live_abc123def456',
baseUrl: 'https://api.novavms.io',
});

The apiKey is an org-scoped API key issued from the Admin console. Never ship it in browser bundles — use a server-side proxy instead.

Client options

OptionTypeDefaultSinceDescription
apiKeystringv1.0Org-scoped API key. Required.
baseUrlstringhttps://api.novavms.iov1.0Override for self-hosted deployments.
timeoutMsnumber10000v1.0Per-request timeout in milliseconds.
maxRetriesnumber3v1.0Retries on 429 and 5xx with exponential backoff.
fetchtypeof fetchglobal fetchv1.0Inject a custom fetch (for proxies, logging).
userAgentstring@novavms/sdk/<version>v1.0Appended to the default User-Agent.

Available methods

The client exposes one namespace per top-level resource:

NamespacePurpose
client.camerasList, get, create, update, delete cameras; fetch snapshots and live-view tokens.
client.eventsQuery the event feed, fetch a single event, acknowledge, star, add notes.
client.alertsList alert history, acknowledge alerts, change status.
client.rulesCreate, read, update, delete alert rules; enable/disable.
client.sitesCreate, read, update, delete sites; manage site-scoped user access.
client.usersInvite users, list members, change roles, revoke sessions.
client.webhooksCreate, list, update, delete webhook definitions; test delivery. Secret rotation requires the Admin role.

Each namespace exposes the same five-verb shape: list, get, create, update, remove, plus resource-specific verbs (for example cameras.trigger(), events.acknowledge()).

const { data: cameras } = await client.cameras.list({ siteId: '8f2b3a71-0c4e-4b5f-9d1a-2e7c3a4b5d6f' });
const event = await client.events.get('3c4d5e6f-7a8b-9c0d-1e2f-3a4b5c6d7e8f');
await client.rules.update('9a8b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d', { enabled: false });

Error types

All errors inherit from NovaVMSError. Catch the base class for a catch-all or narrow to the subclass you care about.

ClassThrown whenSince
NovaVMSErrorAny API error. Includes status, code, requestId.v1.0
AuthError401 or 403 — invalid key or missing scope.v1.0
RateLimitError429 — exposes retryAfterMs.v1.0
ValidationError400 — fieldErrors lists per-field messages.v1.0
NotFoundError404 — resource does not exist in this org.v1.0
import { RateLimitError, AuthError, NovaVMSError } from '@novavms/sdk';
try {
await client.cameras.list();
} catch (err) {
if (err instanceof RateLimitError) {
await new Promise((r) => setTimeout(r, err.retryAfterMs));
} else if (err instanceof AuthError) {
throw new Error('API key is invalid or revoked');
} else if (err instanceof NovaVMSError) {
console.error('NovaVMS API error', err.requestId, err.code, err.message);
} else {
throw err;
}
}

Typed responses

Every response object is fully typed. The type definitions are generated from the OpenAPI spec shipped at /api/v1/openapi.yaml, so an SDK version always matches an API version — no hand-written types drift.

import type { Camera, Event, AlertRule } from '@novavms/sdk';
function render(camera: Camera): string {
return `${camera.name} (${camera.status})`;
}

For the full list of types, see /developer/api/.

Pagination

List endpoints use opaque cursors. Two patterns:

Manual page-by-page

let cursor: string | undefined = undefined;
do {
const page = await client.events.list({ cursor, limit: 100 });
for (const event of page.data) {
process(event);
}
cursor = page.nextCursor;
} while (cursor);

Auto-iteration helper

for await (const event of client.events.iterate({ limit: 100 })) {
process(event);
}

iterate() fetches the next page only when the current one is exhausted. It stops when nextCursor is null. Since v1.0.