Generate dynamic Open Graph images and social cards via API. Render any HTML template to pixel-perfect 1200×630 PNG — for blog posts, products, user profiles, and more.
Render any HTML/CSS template to a pixel-perfect image. All CSS properties supported — it's a real browser.
The exact OG image size for Twitter/X, Facebook, LinkedIn, Slack, and Discord. Or use any custom dimensions.
Google Fonts, Adobe Fonts, or self-hosted fonts. Font loading works perfectly — it's Chromium, not a canvas.
Pass title, author, date, and any data via URL query params to your template. Generate unique images for every page.
Send raw HTML in the request body — no need to host a template. Inject CSS, images, and fonts inline.
PNG for sharpest text quality. WebP for 30-50% smaller files. AVIF for modern formats. All supported.
# Generate a 1200x630 OG image from an HTML template curl "https://api.snapapi.pics/v1/screenshot" \ -H "X-Api-Key: sk_live_YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{ "url": "https://yoursite.com/og-template?title=My+Blog+Post&author=Jane+Doe", "width": 1200, "height": 630, "format": "png", "blockAds": true }' \ --output og-image.png # Or send raw HTML directly (no template hosting needed) curl "https://api.snapapi.pics/v1/screenshot" \ -H "X-Api-Key: sk_live_YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{ "html": "<html><body style=\"background:#1e1e2e;display:flex;align-items:center;justify-content:center;height:100vh;margin:0;font-family:system-ui\"><h1 style=\"color:#fff;font-size:3rem\">My Blog Post</h1></body></html>", "width": 1200, "height": 630, "format": "png" }' \ --output og-image.png
// Generate OG image for a blog post async function generateOGImage(post) { const templateUrl = `https://yoursite.com/og-template?` + `title=${encodeURIComponent(post.title)}` + `&author=${encodeURIComponent(post.author)}` + `&date=${encodeURIComponent(post.date)}`; const response = await fetch('https://api.snapapi.pics/v1/screenshot', { method: 'POST', headers: { 'X-Api-Key': process.env.SNAPAPI_KEY, 'Content-Type': 'application/json' }, body: JSON.stringify({ url: templateUrl, width: 1200, height: 630, format: 'png', blockAds: true }) }); if (!response.ok) throw new Error(`API error: ${response.status}`); const buffer = Buffer.from(await response.arrayBuffer()); // Upload to CDN and return URL return await uploadToCDN(`og/${post.slug}.png`, buffer); }
import requests import os def generate_og_image(title: str, author: str, slug: str) -> bytes: """Generate a 1200x630 OG image for a blog post.""" template_url = ( f"https://yoursite.com/og-template" f"?title={requests.utils.quote(title)}" f"&author={requests.utils.quote(author)}" ) response = requests.post( "https://api.snapapi.pics/v1/screenshot", headers={"X-Api-Key": os.environ["SNAPAPI_KEY"]}, json={ "url": template_url, "width": 1200, "height": 630, "format": "png", "blockAds": True } ) response.raise_for_status() # Save locally or upload to S3/R2 with open(f"og-images/{slug}.png", "wb") as f: f.write(response.content) return response.content
<!-- /og-template.html — your OG image template -->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
body {
width: 1200px; height: 630px;
background: linear-gradient(135deg, #0f0f1a, #1a1a2e);
color: white; font-family: 'Inter', sans-serif;
display: flex; flex-direction: column;
justify-content: center; padding: 64px;
}
.logo { font-size: 24px; font-weight: 800; color: #818cf8; margin-bottom: 32px; }
h1 { font-size: 52px; font-weight: 800; line-height: 1.1; margin-bottom: 16px; }
.meta { font-size: 22px; color: rgba(255,255,255,0.5); }
</style>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@800&display=swap" rel="stylesheet">
</head>
<body>
<div class="logo">YourBlog</div>
<h1 id="title"></h1>
<div class="meta" id="meta"></div>
<script>
const params = new URLSearchParams(location.search);
document.getElementById('title').textContent = params.get('title') || 'Untitled';
document.getElementById('meta').textContent =
(params.get('author') || '') + ' · ' + (params.get('date') || '');
</script>
</body>
</html>
// app/api/og/route.ts — Next.js App Router API route import { NextRequest, NextResponse } from 'next/server'; export async function GET(request: NextRequest) { const { searchParams } = request.nextUrl; const title = searchParams.get('title') ?? 'My Post'; const author = searchParams.get('author') ?? 'Author'; // Option 1: Use your hosted template const templateUrl = `https://yoursite.com/og-template?title=${encodeURIComponent(title)}&author=${encodeURIComponent(author)}`; const res = await fetch('https://api.snapapi.pics/v1/screenshot', { method: 'POST', headers: { 'X-Api-Key': process.env.SNAPAPI_KEY!, 'Content-Type': 'application/json' }, body: JSON.stringify({ url: templateUrl, width: 1200, height: 630, format: 'png' }), next: { revalidate: 86400 } // Cache for 24h }); const buffer = await res.arrayBuffer(); return new NextResponse(buffer, { headers: { 'Content-Type': 'image/png', 'Cache-Control': 'public, max-age=86400, stale-while-revalidate=604800' } }); }
Generate unique OG images for every blog post at publish time. Use your brand colors, post title, author photo, and date. Works with WordPress, Ghost, Contentful, and any headless CMS.
Dynamic cards showing product name, price, rating, and image when shoppers share products on social media. Drives click-through rates from social sharing.
GitHub-style profile cards with avatar, stats, and bio. Generate unique cards for every user that look great when shared on Twitter or LinkedIn.
Turn charts, metrics, and dashboards into shareable social images. Perfect for weekly reports, public stats pages, and milestone announcements.
| Parameter | Type | Description |
|---|---|---|
| url | string | URL of your HTML template. Pass dynamic data via query params. Use https://. |
| html | string | Raw HTML string to render. Mutually exclusive with url. Inject CSS and fonts inline. |
| width | number | Image width in pixels. Default: 1280. Use 1200 for standard OG images. |
| height | number | Image height in pixels. Default: 800. Use 630 for standard OG images. |
| format | string | png | jpeg | webp | avif. Use png for sharpest text quality. |
| quality | number | JPEG/WebP quality (1-100). Default: 90. |
| delay | number | Wait N milliseconds after page load before screenshot. Useful for animations and font loading. |
| waitForSelector | string | Wait for a CSS selector to appear before capturing. Ensures dynamic content is loaded. |
| blockAds | boolean | Block ads and trackers. Default: false. |
Pass a URL to your HTML template with dynamic content in query params, or send raw HTML directly in the request body. Set width: 1200 and height: 630 for standard OG image dimensions. SnapAPI renders it in Chromium and returns the image.
No. You can send raw HTML directly in the html parameter. This is great for simple cards where you want to avoid setting up a template server. For complex designs with multiple variants, hosting a template and passing query params is more flexible.
1200×630 pixels works across Twitter/X, Facebook, LinkedIn, Slack, and Discord. Some platforms also accept 1200×600. Always test with each platform's sharing debugger to verify your images display correctly.
Yes. Since SnapAPI uses a real Chromium browser, web fonts load exactly as they do in a regular browser. Add a Google Fonts <link> tag to your template HTML, or use a delay parameter to ensure fonts finish loading before capture.
Use png for sharpest text quality (recommended for most social cards). Use webp for smaller file sizes (30-50% smaller than PNG) if your CDN and platforms support it. Keep file sizes under 1MB for reliable social media previews.
Generate OG images at publish time and serve them from a CDN. Set long cache headers (max-age=86400 or longer). For user-generated content that changes frequently, use a cache key based on content hash. Avoid generating on every social share request.