DYNAMIC OG-IMAGE API · REAL CHROMIUM, NOT A CSS SUBSET

Social cards,
developed to print.

Give every blog post, product, and profile a share image worth clicking. Fill a designed template straight from a URL — or POST your own HTML — and ogshot renders it with a real browser: any font, any layout, cached hard. Full-page screenshots too, when you need them.

<meta property="og:image" content="https://ogshot.dev/v1/template/article?title=Your+post&author=You&access_key=$KEY"> # one tag in your <head> · a fresh 1200×630 card per page · x-cache: HIT after the first
A SaaS engineering blog card: headline 'How we cut cold starts by 4x with a warm pool', author Maya Reyes with avatar and read time
SaaS blog post· 1200×630 @2x· MISS· rendered live by this server

One API, every kind of card

a product, a launch, a podcast — each one rendered live by the server behind this page All templates →
E-commerce card: Trailrunner 2 sneaker, $148 down from $180, 4.8 stars
E-commerce·product card
Launch card: Finch, #1 Product of the Day, 1,204 upvotes
Product launch·social announce
Podcast card: The Build Log episode 142, Scaling Postgres, 58 min
Podcast·episode art
Webinar card: rendering systems deep dive, July 24, three speakers
Webinar·event promo
Release notes card: v3.2.0, realtime collaboration and faster search
Release notes·changelog
Growth report card: 48,112 signups, +27% week over week, $92k new MRR
Growth report·metrics

Drop it in your <head>

if your stack renders a head tag, it works — interpolate the page's own data
HTML

Static & server-rendered

<meta property="og:image" content="https://ogshot.dev /v1/template/article ?title=My+post&access_key=$KEY">
NEXT.JS

App Router metadata

export const metadata = { openGraph: { images: [ `.../v1/template/article` + `?title=${title}&access_key=$KEY` ] }, };
ASTRO

Frontmatter interpolation

<meta property="og:image" content={`.../template/article` + `?title=${post.title}`} />

Or bring your own HTML

POST /v1/render — any HTML and CSS you can write, no template needed
curl -X POST -H "x-api-key: $KEY" \ -H "content-type: application/json" \ -d '{"html": "<your card markup>"}' \ https://ogshot.dev/v1/render -o card.png # any font, any layout — it's a real browser
A dev-tool API status card rendered from HTML: 200 OK, deploy queued
POST /v1/render·your html → png

Why not just satori, or your own Puppeteer?

Any CSS, because it's a real browser

Vercel's OG library runs on satori — a CSS subset that trips on the layout you actually wrote. ogshot is Chromium, so flexbox, gradients, web fonts, and emoji render exactly as designed.

No browser fleet to babysit

Chromium won't run on most serverless, leaks memory, and needs a warm pool. That's ours to operate — you send a URL and get a PNG.

The cache is the point

The same card for the same post is rendered once, then served from cache in single-digit milliseconds. A viral post costs you one render, not a million.

SSRF-guarded & honest

Private ranges and cloud metadata are refused on every hop inside the browser. Failures come back as machine-readable codes, never mystery 500s.

Also: full-page screenshots

same engine, when you need to capture the web instead of compose it Try it →
curl -H "x-api-key: $KEY" \ "https://ogshot.dev/v1/screenshot?url=https://news.ycombinator.com&full_page=true&dark_mode=true" \ -o shot.png # device presets (iPhone 15, Pixel 7), dark mode, full-page, png/jpeg — all query params

Pricing

sign in with GitHub, upgrade when the free tier pinches · cache hits are always free
Darkroom
$0 / month
  • 100 renders / month
  • Cache hits don't count
  • All templates & render options
Get a key
Agency
$49 / month
  • 25,000 renders / month
  • Up to 5 API keys
  • Usage exports
Upgrade in dashboard