Skip to content

TypeScript SDK

The official TypeScript SDK is published as @sybilion/sdk on npm. It ships two layers in one package:

  • Client — the hand-written wrapper exposed to users (waitForecast, getAlerts, iterUsagePages, iterJobsPages).
  • client.raw — the OpenAPI-generated DefaultApi. Use it as an escape hatch for any endpoint not yet wrapped.

This page documents the wrapper's idioms. For canonical use cases (forecasts, drivers, alerts, account, regions/categories), see the Features section — every example there has a TypeScript tab.

Install

bash
npm install @sybilion/sdk

Requires Node 18+ (for global fetch), or a custom fetchApi on older runtimes.

Construct a client

ts
import { Client } from "@sybilion/sdk";

const client = new Client({
  token: process.env.SYBILION_API_TOKEN,
});

const me = await client.raw.apiV1MeGet();
console.log(me.userId, me.availableEurCents);

token (alias apiKey) is required — unlike the other SDKs, Client does not fall back to SYBILION_API_TOKEN on its own. Read it from the environment yourself and pass it in explicitly, as shown above. The token can be an API key (sk_ops_...) or a dashboard session token; see Authentication.

ClientOptions fields

FieldAliasDefaultNotes
tokenapiKeyBearer credential. Required — the constructor throws if neither is set.
baseUrlapiUrlresolved at runtimeAPI origin without trailing slash. See resolution rules below.
fetchApiglobal fetchInject your own fetch-compatible function for Node polyfills or mocks.
userAgentcompiled-in defaultOverride to brand outgoing requests.

Base URL resolution

baseUrl (alias apiUrl) is the only option that falls back automatically:

  1. Explicit baseUrl (or apiUrl) in the constructor options.
  2. process.env.SYBILION_API_BASE_URL (Node environments only).
  3. The compiled-in default (https://api.sybilion.dev).

resolveApiUrl() and SYBILION_API_BASE_URL_ENV are also exported from @sybilion/sdk if you need the same resolution logic elsewhere.

Wrapper methods

MethodEndpoint
client.raw.apiV1MeGet()GET /api/v1/me
client.raw.apiV1ForecastsPost({ forecastRequestV1 })POST /api/v1/forecasts
client.raw.apiV1ForecastsIdGet({ id })GET /api/v1/forecasts/{id}
client.waitForecast(id, opts)polling helper
client.raw.apiV1ForecastsIdArtifactsNameGet({ id, name })GET /api/v1/forecasts/{id}/artifacts/{name} (returns a Blob)
client.raw.apiV1DriversPost({ recommendRequestV1 })POST /api/v1/drivers
client.getAlerts(request)POST /api/v1/alerts
client.iterJobsPages(opts)pagination helper
client.iterUsagePages(opts)pagination helper
client.raw.apiV1CategoriesGet()GET /api/v1/categories
client.raw.apiV1RegionsGet()GET /api/v1/regions

For endpoints not yet wrapped, client.raw returns the DefaultApi instance directly. Method names mirror the OpenAPI operationId in camelCase, and each returns a Promise of the typed response model.

waitForecast — poll until settled

ts
import { Client } from "@sybilion/sdk";
import { readFileSync } from "fs";

const client = new Client({ token: process.env.SYBILION_API_TOKEN });

const body = JSON.parse(readFileSync("forecast_body.json", "utf-8"));
const started = await client.raw.apiV1ForecastsPost({ forecastRequestV1: body });

const job = await client.waitForecast(started.jobId, {
  pollMs:    2_000,     // milliseconds between polls
  timeoutMs: 3_600_000, // max total wait
});

console.log("status:", job.status, "cost (cents):", job.eurCentsFinal);
for (const art of job.artifacts ?? []) {
  console.log(" -", art.name, art.size, "bytes");
}

Behaviour:

  • Polls GET /api/v1/forecasts/{id} every pollMs milliseconds (default 2000).
  • Returns the response as soon as settled === true — works for completed, failed, and canceled jobs.
  • Throws an Error when timeoutMs is exceeded (default 3_600_000); the job continues on the server and you can resume polling later.

Download artifacts

ts
const art = job.artifacts![0];
const blob = await client.raw.apiV1ForecastsIdArtifactsNameGet({
  id: started.jobId,
  name: art.name!,
});
const buffer = Buffer.from(await blob.arrayBuffer());

Artifacts come back as a Blob — there is no wrapped "download to file" helper, so convert and write it yourself when running on Node.

Pagination iterators

Two async generators walk paginated endpoints page-by-page:

ts
// All usage events (newest first by default).
let total = 0;
for await (const page of client.iterUsagePages({ limit: 50, order: "desc" })) {
  total += page.usageEvents.length;
}
console.log("usage events:", total);

// Only completed forecast jobs.
for await (const page of client.iterJobsPages({ status: "completed", limit: 50 })) {
  for (const job of page.jobs) {
    console.log(job.jobId, job.status, job.eurCentsFinal);
  }
}

Each iterator stops automatically when the last page is reached. Exit early with break.

Error handling

The generated client throws on non-2xx responses. ResponseError is re-exported under the generated namespace, not at the package root:

ts
import { Client, generated } from "@sybilion/sdk";

const client = new Client({ token: process.env.SYBILION_API_TOKEN });

try {
  await client.raw.apiV1ForecastsPost({ forecastRequestV1: body });
} catch (err) {
  if (err instanceof generated.ResponseError) {
    const text = await err.response.text();
    console.error("HTTP", err.response.status, text);
    // 422 → validation failure: {"error":"...","details":[{"field":"...","message":"..."}]}
    // 402 → insufficient balance
    // 429 → rate limit
  } else {
    throw err; // network / parse errors
  }
}

ResponseError extends Error and exposes response (the raw Response) for status-code branching and body reading.

Versioning

The SDK uses SemVer independently of the API server version; minor releases stay backward-compatible, breaking changes bump the major. Pin a version (@sybilion/[email protected]) for production builds.

See also

[email protected] · Slack · Discord (links in Community page & header icons)