szum

API Endpoint

POST JSON, get an image. Or embed via GET.

One endpoint, two methods. Send a chart config, get back an SVG or PNG.

POST /chart

POST requests require an API key. Include it in the Authorization header:

curl -X POST https://szum.io/chart \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "version": "2026-03-20",
    "theme": "editorial",
    "marks": [{
      "type": "barY",
      "data": [
        { "x": "Q1", "y": 42 },
        { "x": "Q2", "y": 58 },
        { "x": "Q3", "y": 65 }
      ]
    }]
  }'

The response body is the rendered image.

GET /chart

Pass the config as a query parameter. GET requests are always keyless and always follow the free tier path – there is no way to authenticate a GET embed.

https://szum.io/chart?config={"version":"2026-03-20","marks":[{"type":"barY","data":[{"x":"Q1","y":42},{"x":"Q2","y":58}]}]}

This is what makes <img> embeds work – no JavaScript required:

<img src='https://szum.io/chart?config={"version":"2026-03-20","marks":[{"type":"barY","data":[{"x":"Q1","y":42},{"x":"Q2","y":58}]}]}' />

Both methods accept up to 100 KB of JSON.

Response

HeaderValue
Content-Typeimage/svg+xml (default) or image/png
Cache-Controlpublic, max-age=86400, s-maxage=604800, stale-while-revalidate=86400

SVG is the default. Set "format": "png" in your config for raster output.

Rate limits

Unauthenticated requests are limited to 10 requests per second per IP. Authenticated requests (with an API key) are limited to 30 requests per second per key. Beyond that, each plan has a monthly render allowance.

PlanMonthly renders
Free1,337
Pro100,000
Business1,000,000

When you exceed either limit, the API returns 429 Too Many Requests:

{ "error": "Monthly render limit exceeded. Upgrade at szum.io/dashboard." }

Limits reset on the 1st of each month (UTC). See Plans & Limits for full details.

Errors

StatusMeaning
400Invalid JSON, missing version, or validation error
401Missing or invalid API key (paid plan requests only)
403Feature not available on current plan (e.g. themeOverrides requires Pro or Business)
413Config exceeds 100 KB
429Monthly render limit exceeded – upgrade or wait for reset
500Render failure

Error responses return JSON with a message:

{ "error": "marks.0.type: Invalid discriminator value" }

The error path tells you exactly where the problem is. marks.0.type means the first mark's type field is invalid.

Common mistakes

Missing version – Every config needs "version": "2026-03-20". Without it you'll get a 400.

Wrong mark type – Valid types are barY, barX, line, dot, areaY, areaX, text, ruleX, ruleY. Typos like "bar" or "Bar" will fail.

Mismatched field names – If your data has { "month": "Jan", "revenue": 42 } but your mark uses "x": "date", the chart will render with no data. Field names must match exactly.

Mixing sizing modes – You cannot set both width/height and plotWidth/plotHeight. Pick one. See Sizing.

Unquoted JSON in GET – The config query parameter must be valid JSON with double-quoted keys. Single quotes or unquoted keys will return a 400.

Versioning

version is required. The current version is "2026-03-20". Configs with older versions are automatically migrated forward – old configs keep working. See the changelog for version history.

Language examples

No SDK required – any language that can make an HTTP request works. See Language Patterns for copy-paste examples in Node, Python, Go, Ruby, and curl.

For AI agents

Building an integration or tool that generates charts? Two resources:

  • szum.io/schema.json – JSON Schema for chart configs. Use it in tool definitions or for validation.
  • szum.io/llms.txt – Compact API reference designed for LLM context windows.

On this page