Skip to content

szum-io/sdk

Repository files navigation

@szum-io/sdk

Official TypeScript SDK for szum, a chart image API.

Turn a JSON config into an SVG, PNG or interactive embed. Use it in transactional emails, weekly digests, PDF reports, Slack messages, dashboards – anywhere an <img> tag works. No headless browser, no canvas, no client-side JavaScript.

szum chart example

Install

npm install @szum-io/sdk

Server-side only. The SDK sends your API key on every request. Never import it into browser code – save charts server-side and pass the URLs to the client.

Quick start

import { Szum } from "@szum-io/sdk";

const szum = new Szum({ apiKey: process.env.SZUM_KEY! });

const png = await szum.render({
  format: "png",
  theme: "editorial",
  title: "Quarterly Revenue",
  subtitle: "By region, FY 2025",
  marks: [
    {
      type: "barY",
      data: [
        { x: "Q1", y: 4.2, region: "Americas" },
        { x: "Q2", y: 5.1, region: "Americas" },
        { x: "Q1", y: 2.1, region: "EMEA" },
        { x: "Q2", y: 2.8, region: "EMEA" },
      ],
      fill: "region",
    },
  ],
});

Saved charts

Save a config server-side and embed the returned short URL in an <img> tag, or drop the embed URL into an <iframe> for an interactive version (Pro plan):

const chart = await szum.charts.create({
  format: "svg",
  theme: "editorial",
  marks: [
    {
      type: "barY",
      data: [
        { x: "Q1", y: 42 },
        { x: "Q2", y: 58 },
      ],
    },
  ],
});

// Static image: <img src={chart.imageUrl} />
// Interactive embed: <iframe src={chart.embedUrl} />
// Revoke later: await szum.charts.delete(chart.id);

create returns a chart object{ id, source, title, createdAt, updatedAt, sizeBytes, imageUrl, embedUrl, configUrl } – and the same shape comes back from get, update, and each item of list. imageUrl (https://szum.io/c/<id>) renders the same image on every fetch; append .png/.svg to force a format. embedUrl (https://szum.io/e/<id>) serves an interactive HTML page with tooltips, legend toggle, and responsive resize.

Managing saved charts

Beyond create and delete, the charts resource lets you enumerate and edit:

// List your charts, newest first; page via nextCursor
const { items, nextCursor } = await szum.charts.list({ source: "api" });

// Read one chart's metadata, or its config
const chart = await szum.charts.get(id);
const config = await szum.charts.getConfig(id);

// Read many configs in one request (max 100 ids)
const { configs, missing } = await szum.charts.getConfigs([id1, id2]);

// Replace a config in place – same id, same /c/ and /e/ URLs
await szum.charts.update(id, {
  format: "svg",
  marks: [
    /* … */
  ],
});

list pages via nextCursor (pass it back as cursor; null on the last page). getConfigs returns { configs, missing }; each missing entry carries a reason – an open set (today "not_found" or "unavailable"), so match the values you handle and treat anything unfamiliar as a non-fatal skip.

Configuration

const szum = new Szum({
  apiKey: process.env.SZUM_KEY!,
  timeout: 30_000, // ms, default 30s
  maxRetries: 2, // default 2; retries 429, 502, 503, 504, and network errors
});

Every method accepts an optional second argument for per-call overrides:

const controller = new AbortController();

await szum.render(config, {
  timeout: 60_000, // override client timeout
  signal: controller.signal, // caller-initiated cancellation
});

Set SZUM_DEBUG=true in your environment to log every request, response status, timing, and retry attempt to stderr.

Error handling

Errors are typed by category. Match by subclass instead of status codes:

import {
  Szum,
  SzumError,
  SzumAuthenticationError,
  SzumRateLimitError,
  SzumInvalidRequestError,
  SzumConnectionError,
} from "@szum-io/sdk";

try {
  await szum.render(config);
} catch (err) {
  if (err instanceof SzumAuthenticationError) {
    // 401 – bad or missing API key
  } else if (err instanceof SzumRateLimitError) {
    // 429 – wait err.retryAfter seconds
  } else if (err instanceof SzumInvalidRequestError) {
    // 400 / 413 – bad config
  } else if (err instanceof SzumConnectionError) {
    // timeout or network error
  } else if (err instanceof SzumError) {
    console.error(err.code); // "api_error", "invalid_request", etc.
    console.error(err.message);
    console.error(err.status); // HTTP status
    console.error(err.retryAfter); // seconds (on 429)
    console.error(err.requestId); // from x-vercel-id – include in support tickets
  }
}

All errors serialize cleanly via JSON.stringify(err) (they implement toJSON), so they work with Sentry, Datadog, and standard loggers.

Exports

Export Description
Szum Client class (render; charts.create/list/get/getConfig/getConfigs/update/delete)
SzumOptions Constructor options (apiKey, timeout, maxRetries, …)
RequestOptions Per-call options (timeout, signal)
SzumError Base error (code, status, message, retryAfter, requestId)
SzumAuthenticationError 401
SzumPermissionError 403
SzumInvalidRequestError 400 / 413
SzumRateLimitError 429
SzumAPIError 5xx
SzumConnectionError Timeout / network
ChartConfig Config type for SDK methods (version optional)
ChartConfigInput Full config type including required version
SavedChart Saved-chart object from charts.create/get/update/list
SavedChartSource Open union of chart origins ("api", "figma", "app", "mcp", …)
SavedChartPage charts.list result (items, nextCursor)
SavedChartConfigs charts.getConfigs result (configs, missing)
ConfigMissingReason Open union: why a config was missing ("not_found", "unavailable", …)
SCHEMA_VERSION Schema version this SDK was built against

Documentation

Full reference at szum.io/docs.