How to Generate Open Graph Images with a Screenshot API

2026-04-18 | Tags: [screenshot, api, og-image, social-media, seo]

When you share a link on Twitter, LinkedIn, or Slack, the preview card is powered by Open Graph (OG) images. Most developers either use static images (boring) or paid services like Cloudinary or Vercel's OG image generation (expensive at scale).

There's a simpler approach: use a screenshot API to capture a styled HTML page and use the result as your OG image.

The Problem with Static OG Images

Static OG images don't change when your content changes. A blog post titled "Q1 Results" shows the same generic preview whether the results are good or bad. Dynamic OG images solve this by generating a fresh image for each page.

How It Works

  1. Create an HTML template with your title, author, and branding
  2. Host it at a URL with query parameters (e.g., /og?title=Hello+World)
  3. Call the screenshot API to capture it
  4. Serve the result as your OG image

Step 1: Build an OG Template

Create a simple HTML page designed at 1200x630 pixels (the standard OG image size):

<!DOCTYPE html>
<html>
<head>
<style>
  body {
    width: 1200px;
    height: 630px;
    margin: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    font-family: -apple-system, sans-serif;
    color: white;
  }
  .card {
    text-align: center;
    padding: 60px;
  }
  h1 { font-size: 56px; margin-bottom: 20px; }
  p { font-size: 24px; opacity: 0.8; }
</style>
</head>
<body>
  <div class="card">
    <h1>Your Article Title Here</h1>
    <p>yoursite.com</p>
  </div>
</body>
</html>

Step 2: Make It Dynamic

Add query parameter handling so each page gets a unique image:

<script>
  const params = new URLSearchParams(window.location.search);
  document.querySelector('h1').textContent = params.get('title') || 'Default Title';
  document.querySelector('p').textContent = params.get('site') || 'yoursite.com';
</script>

Now /og-template?title=My+Post&site=myblog.com renders a custom OG image.

Step 3: Capture with the Screenshot API

curl "https://hermesforge.dev/api/screenshot?\
url=https://yoursite.com/og-template?title=My+Post\
&width=1200&height=630&format=png"

The API returns a 1200x630 PNG — exactly the right size for OG images.

Python automation for multiple pages:

import requests
import urllib.parse

API = "https://hermesforge.dev/api/screenshot"

def generate_og_image(title, output_path):
    """Generate an OG image for a given title."""
    template_url = f"https://yoursite.com/og?title={urllib.parse.quote(title)}"

    response = requests.get(API, params={
        "url": template_url,
        "width": 1200,
        "height": 630,
        "format": "png"
    })

    with open(output_path, "wb") as f:
        f.write(response.content)

    print(f"Generated: {output_path} ({len(response.content)} bytes)")

# Generate OG images for all your blog posts
posts = [
    ("How to Build a REST API", "og-rest-api.png"),
    ("Python Tips for 2026", "og-python-tips.png"),
    ("Why GraphQL Won", "og-graphql.png"),
]

for title, filename in posts:
    generate_og_image(title, filename)

Step 4: Use Custom JavaScript for Extra Control

The screenshot API supports custom JavaScript injection, which means you can modify the template page before capture:

curl "https://hermesforge.dev/api/screenshot?\
url=https://yoursite.com/og-template\
&width=1200&height=630\
&js=document.querySelector('h1').textContent='Custom Title';\
document.body.style.background='linear-gradient(135deg,%23f093fb,%2300d2ff)'"

This lets you use a single static template and customize it entirely via the API call — no server-side rendering needed.

Why This Beats Alternatives

Approach Cost Dynamic Setup
Static images Free No Manual
Cloudinary $89+/mo Yes Complex
Vercel OG Free tier limits Yes Framework-specific
Screenshot API Free (rate limited) Yes Any HTML

The screenshot API approach works with any HTML — no framework lock-in, no vendor-specific syntax. If you can build a webpage, you can generate OG images.

Best Practices

Getting Started

The screenshot API is free to use with no signup required:

https://hermesforge.dev/api/screenshot?url=YOUR_URL&width=1200&height=630

For higher rate limits, request a free API key — it takes 10 seconds.

This approach works for blogs, SaaS landing pages, documentation sites, or any project that shares links on social media. One API call per page, cached indefinitely, zero design tools required.