szum

Saved charts

POST a config, get a stable URL. Embed in emails, Markdown, Slack – no API key in the markup.

Some features on this page require a paid plan. See Plans & Limits.

Pro users can save a chart config server-side and get back a stable, opaque URL that renders on demand. Embed it as <img src="https://szum.io/c/{id}"> anywhere <img> tags work – emails, Markdown, Slack, Notion – your API key stays out of the markup.

<img src="https://szum.io/c/abc123" />

This is the production primitive for embedding. The keyless GET /chart path works too, but it puts the full config in the query string – long URLs, no Pro features. Saved charts give you opaque short URLs, configs up to 50 KB, and access to custom themes.

When to use which

GET /chart?config=...Saved chart /c/{id}
AuthKeylessPro key to write, keyless to read
URL shapeFull config in queryShort opaque id
Config sizeURL-length limitedUp to 50 KB
Pro featuresNoYes (custom themes, large configs)
Use casePrototyping, no-authProduction emails, dashboards

POST /api/charts

Save a config and receive a URL. Wrap the config in { "config": ... }:

curl -X POST https://szum.io/api/charts \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"config":{"version":"2026-03-20","format":"png","marks":[{"type":"barY","data":[{"x":"Q1","y":42}]}]}}'

Response:

{ "url": "https://szum.io/c/abc123...", "id": "abc123..." }

With the TypeScript SDK:

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

const szum = new Szum({ apiKey: process.env.SZUM_KEY! });
const { url, id } = await szum.charts.create({
  format: "png",
  marks: [{ type: "barY", data: [{ x: "Q1", y: 42 }] }],
});

GET /c/{id}

Public render endpoint. Returns the rendered image. CDN-cached – repeated fetches of the same URL serve from edge cache and do not count as renders. See Caching & CDN for exact TTLs.

<img src="https://szum.io/c/abc123" alt="Quarterly revenue" />

Each fresh render counts as one render against the creator's monthly limit (the user who saved the chart, not the recipient opening the email).

DELETE /api/charts/{id}

Revoke a single saved chart. After deletion, the URL returns 404.

curl -X DELETE https://szum.io/api/charts/abc123 \
  -H "Authorization: Bearer YOUR_API_KEY"

You can only delete charts you own. Bulk deletion is available from the dashboard.

Config size

Per-config limit is 50 KB. Larger configs return 413.

On downgrade

Saved charts persist while your account is Pro.

If you downgrade to Free, charts enter a 30-day grace period:

  • Renders return 403 immediately (URLs paused, not deleted)
  • Data is retained for 30 days
  • Upgrading back to Pro within 30 days reactivates everything

After 30 days, saved charts are permanently deleted. URLs return 404 afterwards.

Account deletion, or "Delete all saved charts" in the dashboard, deletes them immediately.

Embedding

The URL works anywhere <img src> works:

<img
  src="https://szum.io/c/abc123"
  alt="Weekly active users, rising to 15,900"
  width="540"
  height="360"
  style="display: block; border: 0; width: 100%; max-width: 540px; height: auto;"
/>
![Weekly active users](https://szum.io/c/abc123)

Also see Charts in Emails.

Errors

Shares the szum error vocabulary. Saved-chart-specific status codes:

StatusMeaning
403Chart is paused (creator downgraded; in 30-day grace period)
404Chart was deleted, never existed, or grace period expired
413Config too large

Rate limits

Saved-chart writes (POST/DELETE) share the same per-key burst limit as the render API: 30 requests per second. Reads (GET /c/{id}) inherit unauthenticated burst limits and count against the creator's monthly render quota on cache miss.

See API → Rate limits for the full picture.

See also

On this page