The output drifts
Generated plotting code is rewritten on every run, so the same question can produce a different-looking chart each time — and sometimes code that does not run at all.
Send a small JSON spec and get back SVG, durable PNG and SVG URLs, alt text, and a quality review in one call. The same input always gives the same chart. The value axis always includes zero.
No signup for the playground · Free accounts get 1,000 renders a month once the email is confirmed (100 before that) · No card to start
A model that emits matplotlib or Chart.js is writing a program you never reviewed, for data you cannot see, into a report that goes straight to someone else.
Generated plotting code is rewritten on every run, so the same question can produce a different-looking chart each time — and sometimes code that does not run at all.
A chart image with no text description is unusable for screen readers and worthless in an email client that blocks images. Nobody in the loop writes that description.
Nine-slice pies, a legend with twelve series, colours that vanish into the background, an axis that starts at 90 so a 2% change looks like a cliff. No one catches them before the customer does.
One POST to /api/v1/charts with a Bearer key. Your agent can act on the answer without a human in the loop.
Five chart types, at most 12 series and 100 points per series. A schema this small leaves a model little to get wrong, and an invalid spec comes back as HTTP 400 with the exact field path and what is wrong with it.
The response carries the SVG itself, durable PNG and SVG URLs, an alt-text summary of what the chart shows, and a list of structural QA findings — each with a severity and a suggested fix.
A finding like pie-too-many-slices names the problem and the remedy, so the agent can revise its own spec and call again before anyone sees the first attempt.
curl -X POST "$CHARTRELAY_URL/api/v1/charts" \
-H "Authorization: Bearer $CHARTRELAY_KEY" \
-H "Content-Type: application/json" \
-d '{
"type": "bar",
"title": "Monthly recurring revenue",
"series": [{
"name": "MRR",
"data": [
{ "label": "Aug", "value": 31200 },
{ "label": "Sep", "value": 33900 }
]
}]
}'Authenticate with a Bearer API key from your dashboard. Unset fields fall back to the schema defaults (900 x 520, light theme, legend on).
{
"id": "V1StGXR8_Z5jdH",
"svg": "<svg xmlns=\"http://www.w3.org/2000/svg\" ...>",
"altText": "Monthly recurring revenue. MRR peaks at 33,900 for Sep and bottoms at 31,200 for Aug. It increased 8.7% from first to last point.",
"warnings": [
{
"severity": "tip",
"code": "healthy",
"message": "No structural chart problems detected.",
"suggestion": "Verify the source data and intended takeaway before publishing."
}
],
"urls": {
"svg": ".../api/v1/charts/V1StGXR8_Z5jdH?format=svg",
"png": ".../api/v1/charts/V1StGXR8_Z5jdH?format=png"
},
"usage": { "used": 41, "limit": 1000 }
}Shape of a real response: id, svg, altText, warnings, urls and usage.
Not a bare image endpoint. Everything an agent needs to publish the chart, or to decide not to.
The chart is drawn by a plain function in the same process — no headless browser, no screenshot step. The same JSON produces the same SVG.
GET /api/v1/charts/{id}?format=svg|png needs no key, so the URL works in Slack, email, and a web page. It is served immutable and cached for a year.
Each render returns a written summary: the title, the peak and the low with their labels, and, for time-ordered charts, the change from the first to the last point — or the largest shares for a pie.
Missing title, multiple series in a pie, too many slices, negative pie values, a dense chart, too many series, low-contrast colours, and labels the axis will shorten. Each one names a fix.
The scale is computed from zero and the data, never from the data alone, so an agent cannot produce the truncated axis that exaggerates a small change.
Every render reports the count used this month against your plan limit, so an agent can back off before it hits the quota instead of after.
ChartRelay is an ordinary JSON API, so it works from any language or agent framework. The repository also ships an MCP server with a single tool, render_chart, which returns the same URLs, alt text and findings — plus an inline PNG preview so the model can see its own chart.
{
"mcpServers": {
"chartrelay": {
"command": "node",
"args": ["/absolute/path/to/chartrelay/mcp/index.js"],
"env": {
"CHARTRELAY_API_KEY": "cr_live_...",
"CHARTRELAY_API_URL": "https://your-chartrelay-host"
}
}
}
}@chartrelay/mcp is not on npm yet, so today the server runs from the repository checkout against whichever ChartRelay host you point it at (see mcp/README.md). The one-line npx install lands when the package is published.
The same render as the REST API: durable PNG and SVG URLs, the alt text, and the quality review with a suggested fix per finding. The tool description tells the model to revise and call again when the review reports a problem, so a bad first attempt is corrected inside the conversation rather than in front of a customer.
Agent builders test in loops, so the free tier is 1,000 renders a month — enough to wire up a real workflow before you decide anything.
1,000 renders a month once you confirm your email; 100 before that. No card. SVG, PNG, alt text and QA are all included, the same as on the paid plans.
10,000 renders a month, for a product or automation with real traffic. Billed monthly, cancel whenever.
100,000 renders a month, for high-volume reporting and agent fleets.
It is not a general visualization library and not a dashboard tool. There are five chart types and no maps, no custom layout language and no interactive charts. If you need dozens of chart types, AntV's mcp-server-chart is a free, open-source MCP server covering 25+ of them (as of September 2026), and Vega handles arbitrary specifications. ChartRelay is for the narrower case: an agent that has to produce a chart nobody will review.
No, and it never claims to. Every check reads the chart specification — the type, the number of series and points, the colours, the labels, the title. It can catch a pie with negative values or a legend nobody can track. It cannot know whether your numbers are right or whether the title is a fair summary of them. When it finds no structural problem, the finding it returns still asks you to verify the data and the intended takeaway.
Bar, line, area, pie and scatter. At most 12 series, at most 100 points per series, a width between 320 and 2,400 pixels and a height between 240 and 1,600, in a light or dark theme. Anything outside those bounds is rejected with a validation error naming the field, rather than silently clipped.
The API returns HTTP 429 with a message saying which limit you reached, and nothing is charged automatically — you are never billed for an overage you did not choose. The count resets at the start of the next calendar month, UTC. If you are on the free tier and have not confirmed your email, confirming it raises the limit from 100 to 1,000 immediately; otherwise you can upgrade from the pricing page.
Not for the playground. It runs the same rendering engine through a rate-limited public endpoint, so you can edit the JSON and see the SVG, the alt text and the QA findings without signing up. You need a free account only when you want an API key of your own.
Not today. The hosted API is the only supported way to run ChartRelay: there is no published source distribution or self-hosting licence, and no self-hosted plan. The MCP server is the exception — its source ships in the repository and talks to whichever ChartRelay instance you point it at.
Open the playground and break a chart on purpose: add a tenth pie slice, drop the title, pick an unreadable colour, and watch what comes back.
The playground needs no signup. A free account gives 1,000 renders a month once your email is confirmed, with no card.