Saved charts
POST a config, get a stable URL. Embed in emails, Markdown, Slack – no API key in the markup.
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} | |
|---|---|---|
| Auth | Keyless | Pro key to write, keyless to read |
| URL shape | Full config in query | Short opaque id |
| Config size | URL-length limited | Up to 50 KB |
| Pro features | No | Yes (custom themes, large configs) |
| Use case | Prototyping, no-auth | Production 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
403immediately (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;"
/>Also see Charts in Emails.
Errors
Shares the szum error vocabulary. Saved-chart-specific status codes:
| Status | Meaning |
|---|---|
403 | Chart is paused (creator downgraded; in 30-day grace period) |
404 | Chart was deleted, never existed, or grace period expired |
413 | Config 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
- API – synchronous
/chartrender endpoint - Authentication – getting an API key
- Plans & Limits – Pro plan details
- Charts in Emails – embedding patterns