API Reference

REST API endpoints for chart rendering and management.

OpenAPI 3.1 specification – Use with Swagger UI, Redoc, or code generators.

Postman collection – Import into Postman to test all endpoints. Set baseUrl, apiKey, and sessionToken variables.

POST /api/v1/render

Renders a chart from a JSON specification. Returns the image as binary (PNG, JPEG, SVG, WebP, or PDF) or JSON with a CDN URL when returnUrl: true.

Request Body

json
{ "type": "line" | "bar" | "pie" | "doughnut" | "radar" | "polarArea", "width": 800, "height": 400, "format": "png" | "jpeg" | "svg" | "webp" | "pdf", "data": { "labels": ["Jan", "Feb", "Mar"], "datasets": [{ "label": "Revenue", "data": [12000, 15000, 18000] }] }, "brandKitId": "uuid-or-preset", "devicePixelRatio": 1, "returnUrl": false, "options": {} }

See Chart Specifications and Card Composition for the full field reference. Authentication: Authorization: Bearer pk_live_... (optional — anonymous renders are allowed at starter plan limits).

Response Headers

  • Content-Typeimage/png, image/jpeg, image/svg+xml, image/webp, or application/pdf
  • X-Render-Time-Ms – Render latency in milliseconds
  • X-CacheHIT or MISS when Redis caching is enabled
  • X-Request-Id – Unique request ID for debugging and support
  • ETag – MD5 of the spec for client-side caching

GET /api/v1/render

Renders a chart from URL parameters. Ideal for <img src="..."> embeds in emails, Slack, Markdown, and forums.

Supports two formats: base64-encoded JSON (full spec) or simple query parameters (basic charts). URL length limit: 2000 characters — use POST for complex specs that exceed this.

Authentication

Browsers cannot send Authorization headers with image requests. Pass your API key as a query parameter instead:

  • key?key=pk_live_...
  • apiKey – Alias for key: ?apiKey=pk_live_...

Format 1: Base64-encoded JSON

Encode your full chart spec as base64url. Use chart or the alias c.

text
GET /api/v1/render?key=pk_live_YOUR_KEY&chart=eyJ0eXBlIjoibGluZSIsIndpZHRoIjo4MDAsImhlaWdodCI6NDAwLCJkYXRhIjp7ImxhYmVscyI6WyJKYW4iLCJGZWIiLCJNYXIiXSwiZGF0YXNldHMiOlt7ImxhYmVsIjoiUmV2ZW51ZSIsImRhdGEiOlsxMjAwMCwxNTAwMCwxODAwMF19XX19

Format 2: Query Parameters

Simple charts with comma-separated values. Best for quick embeds.

  • type or cht – line, bar, pie, doughnut, radar, polarArea
  • labels or l – Comma-separated labels
  • data or d – Comma-separated numbers
  • title or t – Chart title
  • width, height – Dimensions (100–4000 px)
  • format – png, jpeg, svg, webp, pdf
  • brandKitId – UUID or preset name (obsidian, linen, polar, studio, ember, harbor)
  • returnUrl – Return JSON with CDN URL instead of the image
text
GET /api/v1/render?key=pk_live_YOUR_KEY&type=bar&labels=Q1,Q2,Q3,Q4&data=100,150,120,180&title=Revenue&format=png&width=600&height=300

Email Embedding

Use the GET endpoint in HTML emails. PNG format recommended for best compatibility across Gmail, Outlook, and Apple Mail.

html
<img src="https://chart-output.com/api/v1/render?key=pk_live_YOUR_KEY&type=bar&labels=Jan,Feb,Mar&data=10,20,30&format=png" alt="Monthly stats" width="600" height="300" />

URL-encode special characters in labels (spaces → %20). Keep URLs under 2000 characters; use POST for complex charts.

GET /api/v1/templates/:templateId/render

Renders a built-in or custom template with optional query parameter overrides.

Query Parameters

  • labels – Comma-separated labels
  • data – Comma-separated values
  • title – Chart title
  • width, height
  • format – png, jpeg, svg, webp
  • brandKitId – UUID of brand kit or preset (obsidian, linen, polar, studio, ember, harbor)
  • scale / devicePixelRatio – 1–4; defaults to 2 on this route (retina output)
  • palette – Comma-separated hex colors (URL-encode # as %23)

Management APIs (Dashboard)

These endpoints require a session JWT (from the dashboard) or API key.

  • GET /api/v1/stats – Overview stats (renders this month, success rate, avg latency)
  • GET /api/v1/renders?limit=10 – Recent render history
  • GET /api/v1/usage – Usage data for current month
  • GET/POST/DELETE /api/v1/api-keys – API key management
  • GET/POST/PUT/DELETE /api/v1/brand-kits – Brand kit CRUD
  • GET/POST/DELETE /api/v1/webhooks – Webhook subscriptions
  • GET/POST/PUT/DELETE /api/v1/templates – Custom template CRUD
  • GET /api/v1/audit-logs – Audit log for account actions
  • GET/PUT /api/v1/settings/custom-domain – Custom CDN domain for returnUrl

Error Responses

400 Bad Request

Invalid chart specification or malformed JSON.

401 Unauthorized

An Authorization header was present but the key was invalid. Requests with no auth at all return 200 at anonymous limits, not 401.

402 Payment Required

Three distinct conditions return 402. Check the plan and error fields to determine which:

Monthly quota exceeded

json
{ "error": "Monthly render quota exceeded", "currentUsage": 10000, "limit": 10000, "plan": "trial" }

Trial expired

json
{ "error": "Trial expired. Please upgrade to continue.", "plan": "expired", "upgradeUrl": "/app/usage-billing" }

PDF format requires Pro plan

json
{ "error": "PDF output requires the Pro plan", "plan": "starter", "upgradeUrl": "/app/usage-billing" }

429 Too Many Requests

Rate limit exceeded: 100 requests per 15 minutes per API key or IP. Response body and key headers:

json
{ "error": "Rate limit exceeded", "retryAfter": 120 }
  • Retry-After – Seconds until the window resets
  • X-RateLimit-Limit – Request limit per window (100)
  • X-RateLimit-Remaining – Requests remaining in current window
  • X-RateLimit-Reset – ISO timestamp of window reset

500 Internal Server Error

Server error during rendering. Include X-Request-Id when reporting issues.