Menu
og-imagesapitutorial

Free OG Image Generator API: Create Social Preview Images Automatically

SnapSharp Team·April 16, 2026·8 min read

Every blog post, product page, and news article shared on social media renders a preview card. That card is driven by Open Graph meta tags — and the image behind it determines whether people click or scroll past.

Generating OG images manually doesn't scale. Once you have more than a few pages, you need automation: a consistent visual style, dynamic text injection, and an API that returns a rendered image in under a second.

This guide covers how to generate OG images programmatically with a free API.

What is an OG Image?

An OG (Open Graph) image is a 1200×630 PNG or JPEG linked in a page's <meta> tags:

<meta property="og:image" content="https://yoursite.com/og/my-post.png" />
<meta property="twitter:image" content="https://yoursite.com/og/my-post.png" />

When someone shares your URL on Twitter/X, LinkedIn, Slack, or iMessage, the platform fetches this image and uses it as the preview card. A good OG image increases click-through rate significantly — studies show social cards with images get 3× more engagement than text-only shares.

The fastest approach is an API that accepts template data and returns a rendered image. No infrastructure, no browser dependencies.

Quick start with SnapSharp

SnapSharp's /v1/og-image endpoint accepts a template name and data payload, renders the image server-side with a headless browser, and returns the PNG in under 200ms:

curl -X POST https://api.snapsharp.dev/v1/og-image \
  -H "Authorization: Bearer YOUR_FREE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "template": "blog-post",
    "data": {
      "title": "How We Cut Infrastructure Costs by 40%",
      "author": "Sarah Kim",
      "date": "April 2026",
      "tag": "Engineering"
    }
  }' \
  --output og-image.png

Returns a 1200×630 PNG. The free tier includes 100 OG image requests per month — no credit card required.

Built-in templates

Five templates ship out of the box:

TemplateBest for
blog-postBlog articles with title, author, date, tag
product-cardProduct pages with name, price, description
social-cardGeneral sharing with title and subtitle
quote-cardPull quotes with attribution
github-readmeGitHub repository documentation

Node.js example

import SnapSharp from '@snapsharp/sdk';
import { writeFile } from 'fs/promises';

const client = new SnapSharp(process.env.SNAPSHARP_API_KEY!);

async function generateOgImage(post: { slug: string; title: string; author: string; date: string; category: string }) {
  const image = await client.ogImage({
    template: 'blog-post',
    data: {
      title: post.title,
      author: post.author,
      date: post.date,
      tag: post.category,
    },
  });

  await writeFile(`./public/og/${post.slug}.png`, image);
  console.log(`Generated OG image for: ${post.title}`);
}

Python example

from snapsharp import SnapSharp
import os

client = SnapSharp(os.environ['SNAPSHARP_API_KEY'])

def generate_og_image(post: dict) -> bytes:
    return client.og_image(
        template='blog-post',
        data={
            'title': post['title'],
            'author': post['author'],
            'date': post['date'],
            'tag': post['category'],
        }
    )

# Save to file
with open(f"public/og/{post['slug']}.png", 'wb') as f:
    f.write(generate_og_image(post))

Option 2: Custom HTML/CSS templates

If the built-in templates don't match your brand, you can build custom templates using HTML and CSS in the SnapSharp dashboard. The template editor gives you full control over layout, fonts, colors, and background.

Custom templates use Handlebars syntax for dynamic data injection:

<!-- Custom OG template -->
<div style="
  width: 1200px; height: 630px;
  background: linear-gradient(135deg, #0f172a 0%, #1e293b 100%);
  display: flex; flex-direction: column;
  padding: 80px; font-family: 'Inter', sans-serif;
">
  <div style="color: #10b981; font-size: 18px; font-weight: 600; margin-bottom: 32px;">
    {{tag}}
  </div>
  <h1 style="color: white; font-size: 56px; line-height: 1.1; flex: 1; margin: 0;">
    {{title}}
  </h1>
  <div style="display: flex; align-items: center; gap: 16px; margin-top: 40px;">
    <div style="color: #94a3b8; font-size: 20px;">{{author}} · {{date}}</div>
  </div>
</div>

Then call it by template ID:

curl -X POST https://api.snapsharp.dev/v1/og-image \
  -H "Authorization: Bearer YOUR_KEY" \
  -d '{"template": "tpl_a1b2c3d4", "data": {"title": "...", "tag": "...", "author": "...", "date": "..."}}'

Integrating with Next.js

The most common pattern is generating OG images at build time for static content, or on-demand using Next.js Route Handlers:

// scripts/generate-og-images.ts
import SnapSharp from '@snapsharp/sdk';
import { writeFile } from 'fs/promises';
import { getAllPosts } from './lib/posts';

const client = new SnapSharp(process.env.SNAPSHARP_API_KEY!);

async function main() {
  const posts = await getAllPosts();

  // Generate in batches of 10 to avoid rate limits
  for (let i = 0; i < posts.length; i += 10) {
    const batch = posts.slice(i, i + 10);
    await Promise.all(batch.map(async (post) => {
      const image = await client.ogImage({
        template: 'blog-post',
        data: { title: post.title, author: post.author, date: post.date, tag: post.category },
      });
      await writeFile(`public/og/${post.slug}.png`, image);
    }));
    console.log(`Generated ${Math.min(i + 10, posts.length)} of ${posts.length}`);
  }
}

main();

Run this script as part of your build:

{
  "scripts": {
    "build": "tsx scripts/generate-og-images.ts && next build"
  }
}

On-demand generation (for dynamic content)

// app/api/og/route.ts
import { NextRequest, NextResponse } from 'next/server';
import SnapSharp from '@snapsharp/sdk';

const client = new SnapSharp(process.env.SNAPSHARP_API_KEY!);

export async function GET(request: NextRequest) {
  const { searchParams } = request.nextUrl;
  const title = searchParams.get('title') ?? 'Untitled';
  const author = searchParams.get('author') ?? '';

  const image = await client.ogImage({
    template: 'blog-post',
    data: { title, author, date: new Date().toLocaleDateString('en-US', { month: 'long', year: 'numeric' }) },
  });

  return new NextResponse(image, {
    headers: {
      'Content-Type': 'image/png',
      'Cache-Control': 'public, max-age=86400, s-maxage=86400',
    },
  });
}

Then reference the route in your metadata:

// app/blog/[slug]/page.tsx
export async function generateMetadata({ params }: { params: { slug: string } }): Promise<Metadata> {
  const post = await getPost(params.slug);
  const ogUrl = `${process.env.NEXT_PUBLIC_APP_URL}/api/og?title=${encodeURIComponent(post.title)}&author=${encodeURIComponent(post.author)}`;

  return {
    openGraph: {
      images: [{ url: ogUrl, width: 1200, height: 630 }],
    },
    twitter: {
      card: 'summary_large_image',
      images: [ogUrl],
    },
  };
}

Caching OG images

OG images rarely change after generation. Cache them aggressively:

  • CDN caching: Set Cache-Control: public, max-age=604800 (7 days) on the response
  • Redis caching: SnapSharp caches repeated identical requests automatically (set cache: true)
  • Static files: For build-time generation, serve from /public/og/ directly — zero compute
// With Redis cache (subsequent requests return in ~50ms)
const image = await client.ogImage({
  template: 'blog-post',
  data: { title, author, date },
  cache: true,
  cache_ttl: 86400, // 24 hours
});

Comparison: API vs. self-hosted

SnapSharp API@vercel/ogPuppeteer self-hosted
Setup time5 minutes30 minutes2–4 hours
InfrastructureNoneVercel onlyYour server
Custom fontsVia templateEdge font loadingFull control
Complex layoutsFull HTML/CSSLimited (Satori)Full HTML/CSS
PricingFree–$149/moVercel pricingServer cost
LanguagesAny (HTTP)JavaScript onlyAny

@vercel/og is great for simple layouts on Vercel. For complex HTML/CSS templates, multi-language projects, or non-Vercel deployments, an API approach gives you more flexibility.

Free OG image generator

SnapSharp's free tier includes 100 OG image requests per month. That covers a small blog or testing in production:

# Test with your own content — replace with your API key
curl -X POST https://api.snapsharp.dev/v1/og-image \
  -H "Authorization: Bearer YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"template": "blog-post", "data": {"title": "Your Post Title", "author": "Your Name", "date": "April 2026", "tag": "Tutorial"}}' \
  --output test-og.png

Sign up at snapsharp.dev/sign-up — no credit card required.

Free OG Image Generator API: Create Social Preview Images Automatically — SnapSharp Blog