Back to blog
Product

ChartQuery: one API for charts, diagrams, QR codes, barcodes and labels

Josselin Liebe
Josselin Liebe

We built ChartQuery because generating visual assets from code is still way more painful than it should be. Need a bar chart in an email? Spin up a headless browser. Need a QR code in a PDF? Find a library, configure it, handle the output format. Need a Mermaid diagram as PNG? Good luck.

ChartQuery is a single REST API that handles all of this. Six endpoint families, one base URL, consistent request/response patterns across the board. Here is what it does and how to use it.

The endpoints

Endpoint Method What it does
/v1/chart GET, POST Chart images (bar, line, area, pie, radar, etc.)
/v1/diagram GET, POST Diagram images from text (Mermaid, PlantUML, D2, GraphViz, etc.)
/v1/chart/generate GET, POST AI-generated charts from plain English
/v1/diagram/generate POST AI-generated diagrams from plain English
/v1/barcode GET, POST 1D barcodes (EAN-13, Code 128, UPC, etc.)
/v1/qrcode GET, POST Styled QR codes with gradients and custom corners
/v1/label GET, POST Thermal label and receipt previews

Every endpoint supports both GET (URL parameters) and POST (JSON body). Every endpoint returns an image by default. Add share: true to any request and you get back a JSON object with shareable URLs instead.

Charts

The chart endpoint is built on Chart.js v4. You send a JSON config, you get back a PNG or SVG image. Ten chart types are supported: bar, line, area, doughnut, pie, radar, polarArea, bubble, scatter, and mixed.

A basic request looks like this:

{
  "type": "bar",
  "title": "Monthly Sales",
  "data": {
    "labels": ["Jan", "Feb", "Mar", "Apr", "May", "Jun"],
    "datasets": [
      {
        "label": "2025",
        "data": [42, 58, 37, 65, 49, 72],
        "backgroundColor": "rgba(99,102,241,0.85)"
      },
      {
        "label": "2026",
        "data": [51, 67, 44, 71, 58, 85],
        "backgroundColor": "rgba(249,115,22,0.85)"
      }
    ]
  },
  "scales": { "y": { "beginAtZero": true } },
  "width": 1200,
  "height": 600,
  "format": "png"
}

You can configure title, subtitle, legend position, scales, background color, dimensions (50-4000px), device pixel ratio for Retina output, and pass the full Chart.js options object for anything more advanced. The API returns image/png by default, or image/svg+xml when format is "svg".

For dual-axis charts, bind datasets to named scales with yAxisID and configure each axis separately in scales. For stacked charts, give datasets the same stack value. For mixed charts (bar + line on the same canvas), set type: "mixed" and add a type field on individual datasets.

The installed Chart.js version is returned in the X-ChartJS-Version response header. You can pin to a specific release with the version field.

No API key is required. Without one, charts include a small watermark and requests are rate-limited to 60 per hour per IP.

Diagrams

The diagram endpoint converts text-based diagram definitions into rendered images. 28 diagram languages are supported, covering general-purpose diagramming, UML, flow/sequence charts, data modeling, and scientific notation.

The main languages:

  • General purpose: Mermaid, GraphViz, D2, Svgbob, Nomnoml, Excalidraw
  • UML & architecture: PlantUML, C4 with PlantUML, Structurizr, UMlet
  • Flow & sequence: BPMN, SeqDiag, ActDiag
  • Data & networking: BlockDiag, NwDiag, PacketDiag, RackDiag, WireViz, DBML, ERD
  • Scientific: Vega, Vega-Lite, WaveDrom, TikZ, Pikchr, Bytefield, Ditaa, Symbolator

A Mermaid flowchart request:

{
  "diagram_type": "mermaid",
  "diagram_source": "graph TD\n  A[Start] --> B{OK?}\n  B -->|yes| C[End]\n  B -->|no| D[Error]",
  "output_format": "svg"
}

Output formats include SVG (default), PNG, JPEG, and PDF. Not all formats are available for every diagram type.

Each diagram engine runs its own rendering pipeline. Mermaid runs in a sandboxed V8 isolate, GraphViz uses a WebAssembly-compiled dot binary, PlantUML runs a JVM renderer with connection pooling, and D2 uses the native Go binary.

Like charts, diagrams work without an API key. Rate limits and branding rules are the same.

AI generation

The generate endpoints let you skip JSON configuration entirely. Describe what you want in English and get a rendered image back.

For charts:

{
  "prompt": "A stacked bar chart comparing monthly revenue by product line over H1 2026",
  "format": "png",
  "width": 1200,
  "height": 600
}

For diagrams:

{
  "prompt": "A sequence diagram showing JWT authentication: client sends credentials, server validates, returns access and refresh tokens",
  "diagram_type": "mermaid",
  "output_format": "svg"
}

You can pass existing data through raw_data in several formats: CSV-like strings ("Jan: 12400, Feb: 18900"), JSON arrays of objects, or key-value objects. When you provide data, the AI uses your exact values without making anything up. You can also override title, subtitle, legend position, colors, and dimensions.

The prompt is capped at 1,000 characters. raw_data as a string is capped at 10,000 characters, or 500 items as an array.

One difference from the other endpoints: AI generation requires an API key. Inference has a cost and is not available anonymously.

Barcodes

The barcode endpoint generates 1D barcodes as SVG or PNG. Over 25 formats are supported:

  • General purpose: Code 128, Code 39, Code 93, Codabar, MSI, Plessey, Pharmacode, Code 11
  • Retail (EAN/UPC): EAN-13, EAN-8, EAN-5, EAN-2, UPC-A, UPC-E
  • Logistics: ITF, ITF-14, GS1-128, GS1 DataBar, GS1 DataBar Limited, GS1 DataBar Expanded
  • Postal: Identcode, Leitcode, POSTNET, PLANET

Configuration options include bar height, bar width, colors, text display (above or below bars), font size and family, margins, rotation (0/90/180/270 degrees), bearer bars, and measurement units (px, mm, in, cm) for print workflows.

{
  "data": "4006381333931",
  "type": "ean13",
  "show_text": true,
  "height": 100,
  "color": "#1e293b"
}

No API key required. Watermark applies without one.

QR codes

The QR code endpoint goes well beyond basic black-and-white squares. It supports all QR versions (1-40), all error correction levels, and 11 dot styles: square, rounded, dots, diamond, classy, classy-rounded, extra-rounded, vertical-line, horizontal-line, small-square, tiny-square.

You can style QR codes with color gradients (linear or radial), custom corner shapes for each finder pattern, circular clipping (shape: "circle"), and configurable module size ratios.

A styled QR code:

{
  "data": "https://www.chartquery.com",
  "size": 300,
  "ec_level": "H",
  "dot_type": "rounded",
  "color": {
    "type": "linear",
    "rotation": 45,
    "stops": [
      { "offset": 0, "color": "#6366f1" },
      { "offset": 1, "color": "#f97316" }
    ]
  },
  "corners": {
    "top_left": { "outer_shape": "rounded", "inner_shape": "dots" }
  }
}

The data field accepts URLs, plain text, vCards, email (mailto:), SMS (SMSTO:), geo coordinates, and Wi-Fi network configs. Output is SVG by default, PNG when requested.

No API key required. Same rules as the other endpoints.

Label previews

This one is niche but useful if you work with thermal printers. The label endpoint generates visual previews of label and receipt layouts before you send them to a printer.

You define labels with elements: text, boxes, lines, circles, ellipses, reverse (invert) regions, erase regions, and raw printer commands. The API renders them with font metrics specific to the target printer language. The same label definition looks different depending on whether you render it for TSC, ZPL, or ESC/POS.

Nine printer languages are supported: TSC, ZPL, EPL, CPCL, DPL, SBPL, ESC/POS, Star PRNT, and IPL. There are 20 built-in printer profiles (like zebra-zd420, epson-tm-t88vi, star-tsp143iv) that auto-configure DPI and paper width.

{
  "width": 40,
  "height": 30,
  "unit": "mm",
  "dpi": 203,
  "language": "tsc",
  "elements": [
    { "type": "text", "content": "ACME Corp", "x": 10, "y": 10, "size": 2 },
    { "type": "text", "content": "SKU: PRD-00123", "x": 10, "y": 35 },
    { "type": "line", "x1": 5, "y1": 55, "x2": 310, "y2": 55 },
    { "type": "box", "x": 5, "y": 5, "width": 310, "height": 230, "thickness": 2 }
  ]
}

Sharing and embedding

Every endpoint supports a share: true flag. When set, the API returns a JSON object instead of an image:

{
  "id": "cq-a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "render_url": "https://api.chartquery.com/v1/chart/render/cq-...",
  "view_url": "https://api.chartquery.com/v1/chart/view/cq-...",
  "embed_url": "<iframe src=\"...\" frameborder=\"0\" width=\"800\" height=\"500\"></iframe>",
  "expires_in": "3 days"
}

render_url is a direct image link. Drop it in an <img> tag, an email, a Markdown document, or a Slack message. No authentication needed to access it.

view_url is an interactive HTML page. Charts get tooltips and legend toggling. You can embed it as an iframe.

For charts specifically, the render URL supports query parameter overrides. You can change the title, labels, dataset values, colors, dimensions, and format without re-saving. This turns saved charts into reusable templates that you populate with live data via URL parameters:

https://api.chartquery.com/v1/chart/render/cq-...?data1=120,180,150&labels=Q1,Q2,Q3&title=Revenue

Free plan charts expire after 3 days and include a watermark. Paid plans get 6 months and no branding.

Authentication

Most endpoints work without an API key. Anonymous requests are rate-limited to 60 per hour per IP and outputs include a "ChartQuery" watermark.

With an API key (passed via the x-api-key header), rate limits depend on your subscription tier, and paid plans remove the watermark entirely.

The only exception is AI generation (/v1/chart/generate and /v1/diagram/generate), which requires an API key because of the inference cost.

Output formats

Endpoint Formats
Charts PNG, SVG
Diagrams SVG, PNG, JPEG, PDF
Barcodes SVG, PNG
QR codes SVG, PNG
Labels SVG, PNG

SVG is lossless and scalable. PNG is the safe default for email and messaging. Diagrams additionally support JPEG (for smaller file sizes) and PDF (for print).

Try it

Every endpoint works with a simple GET request. Paste this in your browser:

https://api.chartquery.com/v1/chart?query={"type":"bar","title":"Hello ChartQuery","data":{"labels":["A","B","C"],"datasets":[{"label":"Demo","data":[10,20,15],"backgroundColor":"#6366f1"}]}}

You will get a PNG image back. No account, no API key, no setup.

Full documentation is available at docs.chartquery.com.

The playground is available at chartquery.com/playground.

Register for an account at chartquery.com/register.