HTTP API
Validate documents, render images, and manage saved charts.
The API accepts the same chart document shape as Studio, Figma, MCP, and the TypeScript SDK. All JSON endpoints use UTF-8 and support CORS.
POST /validate
Validate a ChartDocument or supported 2026-03-20 config without rendering or saving. Validation is public, free, read-only, and does not consume a monthly render allowance.
curl 'https://szum.io/validate' \
--fail-with-body \
--max-time 30 \
-H 'Content-Type: application/json' \
-d '{
"version": "2026-09-26",
"config": {
"version": "2026-09-26",
"type": "column",
"category": { "field": "quarter" },
"values": { "type": "long", "field": "revenue" }
},
"data": [
{ "quarter": "Q1", "revenue": 42 },
{ "quarter": "Q2", "revenue": 58 }
],
"output": { "format": "svg" }
}'Success and chart-invalid responses use the validation contract:
{
"valid": true,
"diagnostics": []
}When a deterministic fix exists, the response may include one complete, validated suggestedDocument. Review the proposed changes before using it; validate again only if you modify it. When an older config is converted, the response also includes compatibility with its classification and stable codes. See Validation and compatibility.
POST /chart
Render a current ChartDocument or supported 2026-03-20 config. New integrations should use a document. Authenticate with an API key or dashboard session. The response body is the selected image format.
curl 'https://szum.io/chart' \
--fail \
--max-time 30 \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"version": "2026-09-26",
"config": {
"version": "2026-09-26",
"type": "column",
"category": { "field": "quarter" },
"values": { "type": "long", "field": "revenue" }
},
"data": [
{ "quarter": "Q1", "revenue": 42 },
{ "quarter": "Q2", "revenue": 58 }
],
"output": { "format": "svg" }
}' \
--output 'chart.svg'Successful responses include the image Content-Type, Content-Length, and usage headers for authenticated callers. They use private, no-store because usage is account-specific.
Theme overrides require Creator or Pro. Free output uses built-in themes and includes attribution. A semantic error, plan rejection, or render failure occurs before successful usage is finalized.
GET /chart
For small public images, URL-encode the complete document into the historical config query parameter:
https://szum.io/chart?config={URL_ENCODED_RENDER_REQUEST}No API key is required. Keyless output uses the anonymous monthly allowance and includes attribution. Theme overrides are rejected. Successful responses are publicly cacheable by the exact URL; cache hits do not reach origin and do not consume another render.
Do not put private data or credentials in this URL. Query strings can appear in browser history, proxy logs, analytics, and referrer metadata.
Response formats
Set output.format to "svg" or "png". PNG scale accepts 1, 2, 3, or 4 and defaults to 2. The format belongs inside the request rather than an Accept header so cache identity and validation remain explicit.
SVG responses are UTF-8 XML bytes. PNG responses are binary. Treat both as bytes; do not parse successful image bodies as JSON.
Saved charts
Saved-chart endpoints use a durable ChartDocument and stable chart identity:
POST /api/chartscreates and publishes{ document, title?, source? }.GET /api/chartslists owner-scoped metadata with source, sort, search, limit, and opaque cursor filters.GET /api/charts/:idreads metadata.PATCH /api/charts/:idrenames metadata.GET /api/charts/:id/documentreads the published document plus optional newer draft.PUT /api/charts/:id/documentreplaces and publishes the document in place.GET /api/charts/documents?ids=...reads up to 100 documents in one owner-scoped batch.DELETE /api/charts/:idpermanently deletes the chart.
Create supports Idempotency-Key. The key identifies one intended HTTP create and is reused across retries; deduplication is by key, not by comparing the body. Use a fresh key for a different chart. A concurrent request with the same key returns 409 with Retry-After. Document replacement keeps /c/{id} and /e/{id} stable and refuses to overwrite unpublished Studio work for Bearer callers.
See Saved charts for request bodies, response objects, drafts, storage, public URLs, and lifecycle behavior.
Rate limits
- Ordinary API traffic is limited to 10 requests per second per IP at the edge.
- API-key traffic also has a 30 requests-per-second credential bucket.
- Keyless
GET /charthas a 100 image monthly allowance per IP. - Authenticated renders consume the account's monthly plan allowance; validation and saved-chart metadata reads do not.
On 429, honor Retry-After and retry with backoff. CDN hits for successful public image and embed URLs do not reach these origin limits.
Errors
Handled HTTP failures return an error object with code, message, and retryable. Chart input failures add a single diagnostics array. /validate returns its completed validation result separately; see Errors for the distinction and transport exceptions.
{
"error": {
"code": "validation_failed",
"message": "Field \"revenue\" is missing from the data.",
"retryable": false
},
"diagnostics": [
{
"code": "incompatible_data",
"path": "/config/values/field",
"severity": "error",
"message": "Field \"revenue\" is missing from 1 of 1 data row. Every referenced field must exist on every row.",
"details": {
"reason": "data_field_missing",
"affectedRows": 1,
"field": "revenue",
"roles": ["value"],
"rowCount": 1,
"samplePaths": ["/data/0/revenue"]
}
}
]
}Common statuses:
400invalid JSON, contract shape, semantic input, or cursor;401missing or invalid credentials;403plan or presentation policy rejection;404missing or unavailable opaque chart id;409idempotency or concurrent draft/publication conflict;413document or account storage limit;429burst or monthly allowance exceeded;500render or application failure;503temporary credential or storage dependency failure.
See Errors for retry guidance and stable diagnostic handling.
Common mistakes
- Sending only
ChartConfigto/chartinstead of a complete document with data. - Omitting
versionin raw HTTP JSON. The SDK may add its current version; HTTP does not. - Sending
nullfor optional config properties instead of omitting them. - Putting
output,size, orpresentationinside semantic config. - Omitting the document version or using a different nested config version.
- Retrying a create with a new idempotency key and accidentally creating duplicates.
- Parsing an image success response as JSON.
Compatibility and versioning
New integrations should use 2026-09-26. The API also accepts the documented subset of 2026-03-20 configs for validation, rendering, save, and update operations. exact and normalized conversions may be rendered and saved. lossy durable writes require explicit acceptance of every returned loss code. unsupported input returns a stable compatibility error and is not written.
The version identifies a compatibility generation, not a product release. See older config compatibility.
Language examples
See Language examples for TypeScript, Python, Go, Ruby, curl, and HTML.
For agents
Agents should prefer the MCP server, which exposes chart-type discovery, examples, validation, previews, and saved-chart operations with machine-readable tool schemas. Direct HTTP remains available when an MCP client is not appropriate.