DocsChart URLs

Chart URL specification

A RenderChart URL is a chart. Put it in an <img> tag, an email, a Google Sheets =IMAGE() cell, a Slack message, a README or an AI agent's reply and you get a PNG back. The first request renders the chart and every later request is served from cache.

This document is the contract for the chart endpoint, the dashboard builder, the REST API, the MCP tools and the docs. The Worker, the builder and the tests all implement exactly what is written here.

https://c.renderchart.com/?key=rc_pub_live_xxxxxxxxxxxxxxxxxxxx&type=bar&x=Mon,Tue,Wed&y=20,30,40&title=Signups
https://c.renderchart.com/?Endpoint key=rc_pub_live_7Hq2mX9pLk4vN8sT1wEa 1Key &type=bar 2Type &x=Mon,Tue,Wed&y=20,30,40 3Data &title=Signups 4Title

Endpoints

Endpoint Purpose
GET / Render a chart from query parameters. key is required.
GET /s/{id} Render a saved short chart. The key and the data are hidden. Requires Starter or above to create; on Pro the data can be updated and the same URL shows the new chart within about five minutes.

Only GET and HEAD are accepted. Everything else returns the 400 image.

Parameters

Parameter names are case sensitive and always lower case. Values are decoded as application/x-www-form-urlencoded: %XX sequences are decoded as UTF-8 and + means a space. To put a literal + in a value, encode it as %2B.

Parameter Meaning
key Your public key: rc_pub_live_ followed by 20 letters and digits in production, rc_pub_test_ locally. Required on /. Not used on /s/.
type bar (default), hbar, line, area, pie, doughnut, radar, polar or scatter.
x Category labels, separated by sep (default comma). For scatter these are the numeric x values shared by every series.
y, or y1 to y10 Values for one series, or up to ten series. y is an alias of y1; when both are present y1 wins. An empty entry (10,,30) is a gap.
n, or n1 to n10 Series names. n is an alias of n1. Default Series 1, Series 2 and so on.
sep A single character used to split x, y* and c, for when labels contain commas. Example: sep=;. It cannot be a letter, a digit, ., -, +, % or &. Series names (n*) are single values and are never split, so they may contain commas.
title, xlabel, ylabel Text, up to 200 characters each. xlabel titles the horizontal axis and ylabel the vertical one, whatever the chart type.
w, h Width and height in CSS pixels, 50 to 2000. Default 600 x 400. The image is w x dpr by h x dpr pixels.
dpr Device pixel ratio, an integer from 1 to 3. Default 2.
bg Background colour as hex without # (3, 4, 6 or 8 digits) or transparent. Default white, or the theme's background when theme is set.
c, or c1 to c10 Colours as hex without #. c is a list separated by sep: one colour per series for bar, line and similar types, and one per slice for pie, doughnut and polar. c1 to c10 set one series each and override c. Unset colours come from the theme palette.
theme light (default), dark or brand. brand uses the account's brand theme on Pro and falls back to light on other plans.
legend top, bottom, left, right or none. Default none for a single series and top for two or more. pie, doughnut and polar default to right because the legend carries the slice labels.
stacked 1 stacks the series (bar, hbar, line, area).
values 1 draws each value on the chart.
smooth 1 draws curved lines (line, area, radar, scatter with lines).
min, max Bounds for the value axis.
format png (default) or pdf (Pro). jpg is reserved and currently returns the 400 image.
cfg Advanced mode: a base64url encoded Chart.js configuration. See below.
exp Unix timestamp (seconds). Honoured only on signed URLs: after it passes the URL returns the 401 image.
sig The signature. See Signing.

Boolean parameters (stacked, values, smooth) are true for 1 or true and false for anything else.

An empty value (w=, theme=) means the parameter was not given and its default applies. An empty key is a missing key.

Numbers in x (scatter), y*, min and max are plain decimals such as 12, -3.5 or 1e3. Anything else is invalid.

Unknown parameters are ignored and never affect the image, the signature or the cache. Tracking parameters added by email tools (utm_source, fbclid and so on) therefore neither break charts nor cause new renders.

Limits

Limit Value
URL length 8,000 characters
Series 10
Points per series 500
Labels and series names 100 characters each
Title and axis labels 200 characters each
cfg 8,192 bytes decoded
Width and height 50 to 2000 each

Requests over a limit return the 400 image.

Chart types

type Chart.js type Notes
bar bar Vertical bars.
hbar bar with indexAxis: 'y' Horizontal bars. min and max apply to the x axis.
line line Straight lines unless smooth=1.
area line with fill: true The fill uses the series colour at 25% opacity.
pie pie One series. x gives the slice labels.
doughnut doughnut As pie, with a 55% cutout.
radar radar x gives the axis labels.
polar polarArea As pie.
scatter scatter x gives numeric x values; points are (x[i], y[i]) for each series. smooth=1 joins the points with a curved line.

stacked is ignored for pie, doughnut, polar, radar and scatter. Extra series on pie, doughnut and polar are ignored.

Advanced mode: cfg

cfg is a base64url encoded (RFC 4648 section 5, padding optional) JSON object with the shape of a Chart.js 4 configuration: { "type": "...", "data": { ... }, "options": { ... } }. When cfg is present, type, x, y*, n*, c*, title, xlabel, ylabel, legend, stacked, values, smooth, min, max and sep are ignored. w, h, dpr, bg, theme, format, key, exp and sig still apply.

The configuration is validated against an allow list before use:

  • type must be one of bar, line, pie, doughnut, radar, polarArea, scatter or bubble.
  • Values may only be objects, arrays, strings, numbers, booleans or null. There are no functions, so callbacks, custom tick formatters and scriptable options are not available. Keys starting with __ are removed.
  • Strings that contain http:, https:, //, data:, javascript: or url( are removed, so nothing in a chart can reach the network.
  • options.plugins may only contain legend, title, subtitle, tooltip, values and background. Anything else, including the watermark, is removed.
  • options.animation and options.responsive are always forced off, and options.devicePixelRatio comes from dpr.
  • Up to 8,192 bytes decoded, 1,000 array elements in total, and 12 levels of nesting.

An invalid cfg returns the 400 image.

Themes

light draws dark text and grid lines on a white background. dark draws light text and grid lines on a near-black background. Both use the RenderChart default palette for series that have no colour set. brand (Pro) replaces the palette, background, text colour and font with the account's brand theme, and may load a Google Font. bg always overrides the theme background.

Uptime chart in the light theme
theme=light
Uptime chart in the dark theme
theme=dark

Watermark

Unsigned URLs, and every URL on Free, unverified and admin-free accounts, carry a small semi-transparent "renderchart.com" mark in the bottom right corner, inside the image. Signed URLs on paid plans have no watermark. No parameter can remove it.

Monthly active users with the renderchart.com watermark in the bottom right corner
An unsigned 400 x 200 chart, shown at actual size.

Responses

Successful responses on /:

200 OK
Content-Type: image/png            (or application/pdf)
Cache-Control: public, max-age=31536000, immutable
Access-Control-Allow-Origin: *
X-RC-Cache: edge | r2 | render

Successful responses on /s/{id} are the same except Cache-Control: public, max-age=300.

Errors return a static PNG at the same size for every request, with Cache-Control: no-store unless noted, so a broken URL is visible wherever the image is embedded:

Status Meaning Notes
400 Invalid request A parameter is missing, malformed, over a limit, or cfg failed validation. Also returned for format=jpg while it is reserved.
401 Bad or expired signature sig is present but wrong, or exp has passed.
402 Free limit reached The account is Free or unverified and has used its renders for the period. Cache-Control: public, max-age=300.
403 Unknown or revoked key Also returned when key is missing or malformed.
429 Rate limited Too many renders for this key or from this address in the last minute. Cached charts are never rate limited.
503 Renderer unavailable html2img failed or timed out, or the local render budget is exhausted.

Checks run in this order: request shape and parameters (400), key lookup (403), signature and expiry (401), then only when the chart is not already cached: account limit (402), rate limits (429) and rendering (503).

Only the first request for a given chart renders. A chart is "the same" when the canonical query (see Signing), the account's render epoch and the output flags (watermark, theme) match. Every later request is served from the edge cache or R2 and never counts against your allowance.

The 400 error image: Invalid request
400 Invalid request
The 401 error image: Bad or expired signature
401 Bad or expired signature
The 402 error image: Free limit reached
402 Free limit reached
The 403 error image: Unknown or revoked key
403 Unknown or revoked key
The 429 error image: Rate limited
429 Rate limited
The 503 error image: Renderer unavailable
503 Renderer unavailable

Rate limits

Rate limits apply to renders, not to cached responses.

Scope Limit
Per key, Free and unverified 20 renders per minute
Per key, Starter and Pro 300 renders per minute
Per key, Business 1,000 renders per minute
Per client address 600 renders per minute

Examples

# Bar chart with a title
/?key=KEY&type=bar&x=Mon,Tue,Wed,Thu,Fri&y=12,19,3,5,2&title=Signups%20this%20week

# Two stacked series with names and colours
/?key=KEY&type=bar&x=Q1,Q2,Q3,Q4&y1=10,20,30,40&y2=5,15,25,35&n1=Online&n2=Retail&c1=2563eb&c2=f59e0b&stacked=1

# Smooth line with axis labels and a fixed range
/?key=KEY&type=line&x=Jan,Feb,Mar,Apr&y=99.9,99.95,99.7,100&smooth=1&min=99&max=100&ylabel=Uptime%20%25

# Doughnut with slice colours and values
/?key=KEY&type=doughnut&x=Yes,No,Maybe&y=62,28,10&c=16a34a,dc2626,9ca3af&values=1

# Labels containing commas
/?key=KEY&type=hbar&sep=;&x=Smith, John;Doe, Jane&y=3;5

# Dark theme, retina, PDF (Pro), signed
/?key=KEY&type=area&x=1,2,3,4,5&y=1,4,9,16,25&theme=dark&dpr=3&format=pdf&sig=SIGNATURE

Replace KEY with your public key. The dashboard builder writes these URLs for you.

Next: Signing