Visual Infrastructure Bundle

One Key. Two Primitives.

Screenshot any URL. Render any chart. Both APIs included under a single key — built for AI agents, automated reports, and pipelines that need visual output without a browser.

Open Chart Studio → Get Free API Key See Pricing
Primitive 1

Screenshot API

GET /api/screenshot?url=...

Capture any public URL as PNG, JPEG, WebP, or PDF. Handles SPAs, dashboards, auth pages, dark mode, mobile viewports. Returns image bytes.

Primitive 2

Chart Rendering API

POST /api/charts/render

POST a Chart.js config JSON — bar, line, pie, radar, scatter and more. Get a PNG or JPEG back. No canvas, no frontend, no dependencies.

Chart Rendering — Quick Start
$ curl -X POST https://hermesforge.dev/api/charts/render \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_KEY" \
  -d '{
    "type": "bar",
    "data": {
      "labels": ["Jan", "Feb", "Mar", "Apr", "May"],
      "datasets": [{"label": "Revenue ($k)", "data": [12, 19, 15, 22, 28],
                    "backgroundColor": "#4f46e5"}]
    },
    "width": 800, "height": 400
  }' --output chart.png

→  HTTP 200  Content-Type: image/png  (28 KB)
Use Cases

Workflows That Use Both

The bundle earns its value when screenshot and chart rendering work together in one pipeline.

AI Agent Weekly Report

Data + Dashboard → Email

  1. Agent queries database for weekly KPIs
  2. Render trend chart from structured data Chart
  3. Screenshot the live dashboard Screenshot
  4. Attach both images to automated email — no UI needed
SaaS Analytics Export

PNG Reports Without Frontend

  1. Backend collects user activity metrics
  2. Render summary chart per user Chart
  3. Screenshot the customer's account page Screenshot
  4. Deliver visual usage recap with zero client-side code
RAG / LLM Pipeline

Structured Data → Visual Answer

  1. LLM extracts tabular data from documents
  2. Generate Chart.js config from extracted rows
  3. Render chart PNG inline in response Chart
  4. Screenshot any referenced web source Screenshot
BI Alert System

Threshold Breach → Slack Alert

  1. Pipeline monitors KPI thresholds continuously
  2. On breach: render alert chart Chart
  3. Screenshot relevant dashboard panel Screenshot
  4. Post both images directly to Slack or Teams
Chart Rendering API Reference

POST /api/charts/render

POST https://hermesforge.dev/api/charts/render   Content-Type: application/json   Returns: image/png or image/jpeg

ParameterTypeDefaultDescription
typestringrequired Chart type: bar, line, pie, doughnut, radar, scatter, bubble, polarArea
dataobjectrequired Chart.js data object — labels + datasets array
optionsobject{} Chart.js options — titles, scales, legend, colors, etc.
widthinteger800 Output width in pixels (100–2400)
heightinteger450 Output height in pixels (100–1600)
formatstringpng Output format: png | jpeg
qualityinteger90 JPEG quality 1–100 (ignored for PNG)
backgroundstring#ffffff Background CSS color, or transparent (PNG only)

Code Examples

# Bar chart curl -X POST https://hermesforge.dev/api/charts/render \ -H "Content-Type: application/json" \ -H "X-API-Key: YOUR_KEY" \ -d '{"type":"bar","data":{"labels":["Jan","Feb","Mar","Apr","May","Jun"], "datasets":[{"label":"Revenue","data":[12000,19000,15000,22000,28000,24000], "backgroundColor":"#4f46e5"}]},"width":900,"height":450}' \ --output revenue.png # Screenshot + chart in one pipeline (two separate calls, one key) curl "https://hermesforge.dev/api/screenshot?url=https://example.com/dashboard&delay=3000" \ -H "X-API-Key: YOUR_KEY" --output dashboard.png
import requests API_KEY = "YOUR_KEY" BASE = "https://hermesforge.dev" def render_chart(config: dict) -> bytes: r = requests.post(f"{BASE}/api/charts/render", json=config, headers={"X-API-Key": API_KEY}) r.raise_for_status() return r.content def screenshot_url(url: str, delay: int = 1000) -> bytes: r = requests.get(f"{BASE}/api/screenshot", params={"url": url, "delay": delay}, headers={"X-API-Key": API_KEY}) r.raise_for_status() return r.content # Full report pipeline — both APIs, one key chart_png = render_chart({ "type": "line", "data": {"labels": ["W1","W2","W3","W4"], "datasets": [{"label": "Users", "data": [120,195,280,340], "borderColor": "#4f46e5", "tension": 0.4}]}, "width": 900, "height": 400 }) dashboard_png = screenshot_url("https://your-app.com/dashboard", delay=3000) with open("chart.png", "wb") as f: f.write(chart_png) with open("dashboard.png", "wb") as f: f.write(dashboard_png)
const API_KEY = 'YOUR_KEY'; const BASE = 'https://hermesforge.dev'; async function renderChart(config) { const r = await fetch(`${BASE}/api/charts/render`, { method: 'POST', headers: {'Content-Type': 'application/json', 'X-API-Key': API_KEY}, body: JSON.stringify(config), }); if (!r.ok) throw new Error((await r.json()).error); return Buffer.from(await r.arrayBuffer()); } async function screenshotUrl(url, delay = 1000) { const r = await fetch(`${BASE}/api/screenshot?url=${encodeURIComponent(url)}&delay=${delay}`, {headers: {'X-API-Key': API_KEY}}); if (!r.ok) throw new Error((await r.json()).error); return Buffer.from(await r.arrayBuffer()); } // Use both — one key const chart = await renderChart({type:'bar', data:{labels:['Mon','Tue','Wed','Thu','Fri'], datasets:[{label:'API Calls',data:[234,456,389,512,298],backgroundColor:'#4f46e5'}]}, width:800, height:400}); const screenshot = await screenshotUrl('https://example.com/dashboard', 2000); require('fs').writeFileSync('chart.png', chart); require('fs').writeFileSync('dashboard.png', screenshot);
from langchain.tools import tool import requests, base64 API_KEY = "YOUR_KEY" BASE = "https://hermesforge.dev" @tool def render_chart_image(chart_config: dict) -> str: """Render a Chart.js config to PNG. Returns local file path. config: {type, data: {labels, datasets}, options?, width?, height?, background?}""" r = requests.post(f"{BASE}/api/charts/render", json=chart_config, headers={"X-API-Key": API_KEY}) r.raise_for_status() path = f"/tmp/chart_{abs(hash(str(chart_config))) % 100000}.png" with open(path, "wb") as f: f.write(r.content) return path @tool def screenshot_url(url: str, delay_ms: int = 1000) -> str: """Screenshot a public URL. Returns local file path.""" r = requests.get(f"{BASE}/api/screenshot", params={"url": url, "delay": delay_ms}, headers={"X-API-Key": API_KEY}) r.raise_for_status() path = f"/tmp/screenshot_{abs(hash(url)) % 100000}.png" with open(path, "wb") as f: f.write(r.content) return path # Agent uses render_chart_image() + screenshot_url() in one pipeline # One API key covers both tools
Chart Studio

Build a chart. See the API call.

Use the visual Chart Studio to design your chart, then click "Render via Hermesforge API" to see the server-side result and get the exact integration code.

Open Chart Studio →
Pricing

Visual Infrastructure Bundle

One key covers Screenshot API + Chart Rendering API. Limits are shared across both.

Free
$0 /forever
Rate limited. Watermarked output on images.
  • Screenshot API
  • Chart Rendering API
  • 2 req/min, 10/day
  • Watermark on output
Get Free Key →
Pro
$39 /30 days
For active pipelines.
  • Screenshot + Chart Rendering
  • 1,000 requests/day
  • 10 req/min
  • No watermark
Scale
$79 /30 days
High-volume agent workloads.
  • Screenshot + Chart Rendering
  • 5,000 requests/day
  • 20 req/min
  • No watermark

Existing API keys cover both APIs immediately — no re-onboarding needed.   See full pricing →

Start in 60 Seconds

Free API key. No credit card. Screenshot + Chart Rendering included.

Get Free API Key View All APIs →