Skip to main content
← Guides

Charts in PDF Reports

Render charts as PNG and embed them in any PDF library, or use format: "pdf" for direct single-chart PDF output. Every example is complete and runnable.

Approaches

ApproachBest forPlan
Render PNG → embed in PDF libraryMulti-chart reports, custom layouts, mixed contentAll plans
Render directly as format: "pdf"Single-chart stand-alone PDFsBusiness

Embed PNG in a PDF library

Render the chart as PNG (all plans) and embed it with pdfkit (Node.js) or ReportLab (Python). Use padding: "pdf" for generous margins, and scale: 2 for crisp output in print-resolution PDFs.

# Render chart to file curl -s -X POST https://chart-output.com/api/v1/render \ -H "Authorization: Bearer pk_live_YOUR_KEY" \ -H "Content-Type: application/json" \ --output chart.png \ -d '{ "type": "bar", "width": 500, "height": 280, "format": "png", "scale": 2, "padding": "pdf", "data": { "labels": ["Q1","Q2","Q3","Q4"], "datasets": [{ "label": "Revenue", "data": [100,150,120,180] }] } }' # Then use your PDF library of choice to embed chart.png

PDF output format (Business plan)

Set format: "pdf" to receive a single-page PDF sized to the chart dimensions. Works with card compositions — ideal for branded, printable one-pagers.

curl -s -X POST https://chart-output.com/api/v1/render \ -H "Authorization: Bearer pk_live_YOUR_KEY" \ -H "Content-Type: application/json" \ --output chart.pdf \ -d '{ "type": "line", "width": 800, "height": 500, "format": "pdf", "brandKitId": "linen", "padding": "pdf", "header": { "eyebrow": "ANNUAL REPORT 2025", "title": "Revenue Trend" }, "data": { "labels": ["Jan","Feb","Mar","Apr","May","Jun"], "datasets": [{ "label": "Revenue", "data": [14200,17800,20100,22900,25720,29840] }] } }'

Requesting PDF on Starter or lower returns a 403 with "PDF output requires the Business plan".

Multi-chart report

Render multiple charts in parallel using Promise.all, then compose them on multiple PDF pages:

javascript
import PDFDocument from 'pdfkit'; async function renderChart(spec) { const res = await fetch('https://chart-output.com/api/v1/render', { method: 'POST', headers: { Authorization: `Bearer ${process.env.CHART_OUTPUT_API_KEY}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ ...spec, format: 'png', scale: 2 }), }); return Buffer.from(await res.arrayBuffer()); } const [revenueChart, growthChart] = await Promise.all([ renderChart({ type: 'bar', width: 500, height: 240, padding: 'pdf', data: { labels: ['Q1','Q2','Q3','Q4'], datasets: [{ label: 'Revenue', data: [100,150,120,180] }] }, }), renderChart({ type: 'line', width: 500, height: 240, padding: 'pdf', data: { labels: ['Q1','Q2','Q3','Q4'], datasets: [{ label: 'Growth %', data: [12,18,14,22] }] }, }), ]); const doc = new PDFDocument({ size: 'A4', margin: 50 }); doc.pipe(fs.createWriteStream('report.pdf')); doc.fontSize(20).text('Annual Report', 50, 50); doc.image(revenueChart, 50, 100, { width: 500 }); doc.addPage(); doc.image(growthChart, 50, 100, { width: 500 }); doc.end();