For pipelines, reports and anything that wants an image instead of an embed: a small HTTP
service that turns the same JSON spec into a PNG or an SVG.
Self-hosted — free, MIT
Your machine, your copy
Everything below runs a copy of the service on YOUR computer —
localhost:8787 is your own machine, not our server. No account, no key,
and nothing you render ever reaches us. That is the open-source deal: you get the
engine itself, not access to ours.
Hosted — planned
Our endpoint, your API key
For teams that would rather not run anything: a hosted render endpoint with real API
keys and quotas is the paid layer on this roadmap. This page will grow a "get a key"
path the day it exists.
Run it
One container: a headless Chromium stays warm inside it, renders arrive as a queue, and the
fonts ship in the image so output is identical on every machine.
# from the repository root
docker compose up render-api
# -> listening on http://localhost:8787
GET /healthz answers {"ok": true} once the service is up.
1–4 (device-pixel multiplier; final PNG is width×scale by height×scale)
SVG
Add "format": "svg" and the browser is skipped entirely — parsing, scene
building and serialization are pure computation, so SVG renders are cheap and exact.
scale is ignored (vectors have no pixels); font families are referenced by
name, not embedded.
curl -X POST http://localhost:8787/render \
-H "Content-Type: application/json" \
-d '{ "format": "svg", "spec": { ...same spec... } }'
# -> a standalone <svg>, no browser involved
Limits, all of them
The service treats every request as untrusted and refuses oversized work before running the
expensive parts:
Limit
Value
On breach
Request body
1 MiB
413
Total values across all series
10,000
400, structured error
Drawn dots (dotplot)
10,000
400, structured error
Final PNG area (width×scale × height×scale)
16,777,216 px
400, structured error
Errors
Invalid input returns 400 with the same {path, message, hint} list as
everywhere else in the project; unknown routes 404; unexpected failures 500. Nothing about a
bad spec is ever a crash:
{
"errors": [{
"path": "type",
"message": "Unknown chart type \"pei\"",
"hint": "Use one of: line, area, bar, column, stacked, donut, scatter, number, dotplot"
}]
}
Self-hosted today. When a hosted endpoint exists, this page will document it.