Generate Social Cards and OG Images from HTML with a Free API

2026-05-01 | Tags: [html-to-image, api, og-image, social-cards, automation]

Every modern web app needs OG images. Twitter cards, LinkedIn previews, GitHub social images — they all want a static image that represents your page. Most teams either use static mockups (which go stale) or set up a Puppeteer pipeline (which is painful to maintain). There's a simpler way.

The Problem with OG Image Generation

The standard approach involves: 1. Install Puppeteer or Playwright 2. Configure a headless browser in your CI/CD 3. Write HTML templates 4. Render them to images 5. Debug Chrome crashes in production

That's a lot of infrastructure for what's essentially "turn this HTML into a PNG."

One API Call

curl -X POST "https://hermesforge.dev/api/html2image" \
  -H "Content-Type: application/json" \
  -d '{
    "html": "<div style=\"width:1200px;height:630px;background:linear-gradient(135deg,#667eea,#764ba2);display:flex;align-items:center;justify-content:center;font-family:system-ui\"><h1 style=\"color:white;font-size:48px\">My Blog Post Title</h1></div>",
    "width": 1200,
    "height": 630,
    "format": "webp"
  }' -o og-image.webp

That's it. No browser install, no Puppeteer, no Chrome flags. Send HTML, get an image.

Dynamic OG Images

Generate unique images per page by templating the HTML:

import requests

def generate_og_image(title, author, date):
    html = f'''
    <div style="width:1200px;height:630px;background:#1a1a2e;
         display:flex;flex-direction:column;justify-content:center;
         padding:60px;font-family:system-ui">
      <h1 style="color:#e94560;font-size:52px;margin:0">{title}</h1>
      <p style="color:#eee;font-size:24px;margin-top:20px">
        By {author} · {date}
      </p>
    </div>
    '''
    resp = requests.post(
        "https://hermesforge.dev/api/html2image",
        json={"html": html, "width": 1200, "height": 630, "format": "webp"},
    )
    return resp.content

Call this in your build step and every page gets a unique, branded OG image.

Social Media Card Sizes

Different platforms want different dimensions:

BASE="https://hermesforge.dev/api/html2image"

# Twitter card (1200×628)
curl -X POST "$BASE" -H "Content-Type: application/json" \
  -d '{"html": "YOUR_HTML", "width": 1200, "height": 628, "format": "webp"}' \
  -o twitter-card.webp

# LinkedIn post (1200×627)
curl -X POST "$BASE" -H "Content-Type: application/json" \
  -d '{"html": "YOUR_HTML", "width": 1200, "height": 627, "format": "webp"}' \
  -o linkedin-post.webp

# Facebook share (1200×630)
curl -X POST "$BASE" -H "Content-Type: application/json" \
  -d '{"html": "YOUR_HTML", "width": 1200, "height": 630, "format": "webp"}' \
  -o facebook-share.webp

Retina Quality

For crisp images on high-DPI displays, use scale: 2:

curl -X POST "$BASE" -H "Content-Type: application/json" \
  -d '{"html": "YOUR_HTML", "width": 1200, "height": 630, "format": "webp", "scale": 2}' \
  -o og-image@2x.webp

The output image is 2400×1260 pixels but designed for 1200×630 display — sharp on Retina screens.

Dynamic Badges

Generate status badges, counters, or labels:

curl -X POST "$BASE" -H "Content-Type: application/json" \
  -d '{
    "html": "<div style=\"display:inline-flex;align-items:center;background:#333;border-radius:4px;font-family:monospace;font-size:14px\"><span style=\"padding:4px 8px;color:#fff\">build</span><span style=\"padding:4px 8px;background:#4c1;color:#fff;border-radius:0 4px 4px 0\">passing</span></div>",
    "width": 200,
    "height": 30,
    "format": "png",
    "background": "transparent"
  }' -o badge.png

Email Headers

HTML emails can't use CSS background-image reliably. Generate header images instead:

curl -X POST "$BASE" -H "Content-Type: application/json" \
  -d '{
    "html": "<div style=\"width:600px;height:200px;background:linear-gradient(90deg,#2196F3,#21CBF3);display:flex;align-items:center;justify-content:center\"><h1 style=\"color:white;font-family:system-ui;font-size:36px\">Weekly Report</h1></div>",
    "width": 600,
    "height": 200,
    "format": "png"
  }' -o email-header.png

Works in every email client because it's just an <img> tag.

Full CSS Support

The API renders with a full Chromium engine, so all modern CSS works — flexbox, grid, gradients, shadows, @font-face, transforms:

<div style="width:800px;height:400px;display:grid;
     grid-template-columns:1fr 1fr;gap:20px;padding:40px;
     background:#f8f9fa;font-family:system-ui">
  <div style="background:white;border-radius:12px;padding:24px;
       box-shadow:0 2px 8px rgba(0,0,0,0.1)">
    <h2 style="margin:0;color:#333">Revenue</h2>
    <p style="font-size:48px;color:#4CAF50;margin:8px 0">$12.4k</p>
  </div>
  <div style="background:white;border-radius:12px;padding:24px;
       box-shadow:0 2px 8px rgba(0,0,0,0.1)">
    <h2 style="margin:0;color:#333">Users</h2>
    <p style="font-size:48px;color:#2196F3;margin:8px 0">1,247</p>
  </div>
</div>

Getting Started

No signup, no API key, no dependencies:

curl -X POST "https://hermesforge.dev/api/html2image" \
  -H "Content-Type: application/json" \
  -d '{"html": "<h1 style=\"font-family:system-ui;color:#333\">Hello World</h1>"}' \
  -o hello.png

For higher rate limits, get a free API key at /api. Full parameter reference at /tools/html2image.