OG IMAGE API

Dynamic Open Graph cards for every page you ship.

Generate branded 1200×630 social preview cards on demand — from structured data, not templates you have to design. One endpoint, and every blog post, product page and profile gets a card.

POST https://api.ottersnap.com/v1/og

Perfect size, every time

Every card comes out exactly 1200×630 — the size Facebook, X, LinkedIn and Slack all expect.

Structured, not designed

Send a title, subtitle and site name. No Figma, no template engine, no font licensing on your side.

Four themes

Emerald, dark, light and paper themes match your brand without a single line of CSS.

Dynamic at scale

Render a unique card per blog post, product or user profile on the fly — it's one HTTP call each.

Fast enough to be sync

Cards render in seconds, so you can generate them during build or on first request.

Never a broken preview

PNG served with the right headers means link previews stop failing on platforms that cache aggressively.

Call it in seconds

JSON in, rendered file out. Works with anything that can make an HTTP request.

CURL
curl -X POST https://api.ottersnap.com/v1/og \
  -H "Authorization: Bearer otter_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"title": "Shipping v2.0", "subtitle": "Everything new this quarter", "theme": "emerald"}' \
  --output og.png
NODE.JS
const res = await fetch("https://api.ottersnap.com/v1/og", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.OTTERSNAP_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    title: `Blog: ${post.title}`,
    subtitle: post.excerpt,
    siteName: "yourblog.com",
  }),
});

fs.writeFileSync("og.png", Buffer.from(await res.arrayBuffer()));
PYTHON
import os, requests

res = requests.post(
    "https://api.ottersnap.com/v1/og",
    headers={"Authorization": f"Bearer {os.environ['OTTERSNAP_KEY']}"},
    json={"title": "Shipping v2.0", "subtitle": "Everything new this quarter"},
)

open("og.png", "wb").write(res.content)

Parameters

NameTypeDescription
titlestring · requiredMain headline. Longer titles wrap automatically.
subtitlestring · optionalSupporting line under the headline.
siteNamestring · default ottersnap.comFooter label on the card — usually your domain.
themestring · default emeraldVisual theme: emerald, dark, light or paper.

Questions about the og image api

Can I use my own fonts and layout?

Custom template uploads are on the roadmap. Today the four built-in themes cover most brands — pick the closest and your title and colors do the branding.

Should I generate OG images at build time or on request?

Both work. Build-time generation keeps deploys self-contained; on-request generation suits user-generated pages where the set of titles is unbounded.

Why aren't my new cards showing on Facebook or X?

Those platforms cache aggressively. After changing an image, run the URL through the Facebook Debugger or a cache-busting query string once, and the new card picks up.

Ready to render?

Free tier, no credit card. Upgrade only when you scale.

Get your API key