Using openapi-typescript
The Bluebot API publishes an OpenAPI document. Point openapi-typescript at it once and you get a fully typed client for every endpoint, every parameter, every response — usable from any Node or TypeScript project. It's the same stack we use internally.
We've published a runnable reference repo at bluebotdev/bluebot-examples-typescript. Every example endpoint in this developer center has a matching script there — clone it, drop in your API key, and run.
Install
Three packages: a runtime client and two dev-only tools (the type generator and a TypeScript runner so you can execute .ts files directly).
npm install openapi-fetch
npm install -D openapi-typescript tsxGenerate types from the API spec
Run this once to produce src/schema.d.ts. Re-run it whenever the API spec changes — TypeScript will surface breaking changes at compile time.
npx openapi-typescript http://localhost:8080/management/v1/api-json -o ./src/schema.d.tsWire it into a package.json script so re-generation is always one command:
{
"scripts": {
"openapi:generate": "openapi-typescript http://localhost:8080/management/v1/api-json -o ./src/schema.d.ts"
}
}Create the typed client + middleware
openapi-fetch takes the generated paths type and produces a fully typed client. A middleware adds the bluebot-api-key header to every request, so individual callers never have to think about auth.
// src/client.ts
import "dotenv/config";
import createClient, { type Middleware } from "openapi-fetch";
import type { paths } from "./schema";
const apiKey = process.env.BLUEBOT_API_KEY;
if (!apiKey) {
throw new Error("Missing BLUEBOT_API_KEY in environment.");
}
const apiKeyMiddleware: Middleware = {
async onRequest({ request }) {
request.headers.set("bluebot-api-key", apiKey);
return request;
},
};
export const client = createClient<paths>({
baseUrl: process.env.BLUEBOT_API_BASE_URL ?? "http://localhost:8080",
});
client.use(apiKeyMiddleware);Use it in a script
The simplest example. client.GET autocompletes every path, and the response body is fully typed.
// src/examples/list-organizations.ts
import { client } from "../client.js";
const { data, error } = await client.GET(
"/management/v1/organizations/mine",
);
if (error) {
console.error("Request failed:", error);
process.exit(1);
}
console.log(JSON.stringify(data, null, 2));Run it with tsx:
npx tsx src/examples/list-organizations.tsThe same client works in any server context — Node scripts, server actions, route handlers, background workers, AWS Lambdas. Anywhere you can read an environment variable, you can call it.
Reference scripts
Every script below lives in the example repo and is runnable on its own. The endpoint sections elsewhere in this site link directly to the matching script.
- list-organizations.ts — GET /management/v1/organizations/mine — the org your key is scoped to.
- list-devices.ts — GET /management/v1/device — paginated list of devices.
- historical-last-hour.ts — 5-minute buckets over the past hour.
- historical-raw-5min.ts — Raw rows over the past 5 minutes.
- historical-daily-totals.ts — Daily flow totals for the past 30 days.
- historical-today-total.ts — Today's flow total, anchored to the start of today in your timezone.
- historical-count-only.ts — Just the row count for a time range.
- adaptive-1day.ts — Adaptive resolution, ~500 datapoints across 24 hours.
- adaptive-7day.ts — Adaptive resolution, ~1000 datapoints across 7 days.
- adaptive-30day-tz.ts — 30 days of adaptive datapoints in your timezone.
- latest-all-metrics.ts — Uptime, last-seen, and quality across multiple devices.
- latest-lastseen-multi.ts — Just last-seen across up to 50 devices.
- latest-uptime-1h.ts — Uptime computed over the past hour at 1-minute resolution.
Regenerating after API changes
Re-run npm run openapi:generate. Any endpoint, parameter, or response shape that changed in a way that breaks your code will surface as a TypeScript error at compile time — no silent drift.