Roboflare
SDKs

TypeScript SDK

Typed client over the Roboflare OpenAPI spec, runs in Node, Bun, and the browser.

The TypeScript SDK is a thin wrapper around openapi-fetch with the generated types from packages/api-spec/openapi.json. Every method is type-safe end to end.

Install

The SDK lives in this monorepo as packages/sdk-ts. Until it is published to npm, link it locally:

pnpm add @roboflare/sdk@workspace:*

Create a client

import { RoboflareClient } from "@roboflare/sdk";

const client = new RoboflareClient({
  token:   process.env.ROBOFLARE_TOKEN!,
  baseUrl: "https://api.roboflare.com",
});

token is a portal token (rf_org_... or rf_user_...). baseUrl defaults to the hosted API.

Resources

The client exposes one object per resource:

await client.robots.list();
await client.robots.health(robotId);
await client.robots.timeline(robotId);
await client.robots.rosbags(robotId, { start_unix, end_unix });

await client.fleets.list();
await client.fleets.logs(fleetId);

await client.sites.list();
await client.sites.create({ name: "Warehouse A" });

await client.releases.list();
await client.releases.create({ semver: "1.2.3", notes: "..." });
await client.releases.deploy(releaseId, { fleet: fleetId });

await client.configs.list();
await client.configs.set({ name, namespace, payload });
await client.configs.deployments.list();
await client.configs.deployments.create({ config_blob_id, target_kind, target_id });
await client.configs.deployments.events(deploymentId);

await client.deployments.list();
await client.deployments.create({ release_id, target_kind, target_id });
await client.deployments.events(deploymentId);

await client.enrollmentKeys.list();
await client.enrollmentKeys.create({ site_id, fleet_id, name });
await client.enrollmentKeys.revoke(keyId);

await client.orgUsers.list();
await client.orgUsers.create({ email, role });
await client.orgUsers.revoke(userId);

Idempotency

client.deployments.create() generates a UUIDv4 idempotency key for you on every call. To make a retry safe, pass the same key:

const key = crypto.randomUUID();
await client.deployments.create({ release_id, target_kind: "robot", target_id }, key);
// safe to retry with the same key — returns the original deployment
await client.deployments.create({ release_id, target_kind: "robot", target_id }, key);

Streaming logs

client.robots.logs(id) returns an async iterable backed by the live WebSocket at /api/robots/<id>/logs/ws:

for await (const line of client.robots.logs(robotId)) {
  console.log(line);
}

Stop iterating to close the socket. The client appends ?token=... to the WS URL automatically.

Errors

Failed calls throw RoboflareApiError with the raw payload attached:

import { RoboflareApiError } from "@roboflare/sdk";

try {
  await client.deployments.create({ ... });
} catch (err) {
  if (err instanceof RoboflareApiError) {
    console.error("API rejected:", err.payload);
  }
  throw err;
}

Bring-your-own login

For end-user portals where the user hasn't pasted a token yet, exchange their portal token via client.login(portal_token) and store the returned org/role pair. The HTTP client keeps using the bearer token you passed at construction.

On this page