Free Open Graph image API โ€” dynamic og:image cards from a URL, no deploy

Every page you share on Bluesky, Twitter/X, Slack, Discord, LinkedIn or Facebook gets judged by its og:image โ€” and making one per page is the chore everyone postpones. The classic fixes all cost something: opening an image editor for every post, deploying an image-generation function (@vercel/og is great, but it's JSX + a deployment + font files), or paying a card-rendering SaaS.

Mockbird gives you a dynamic og:image URL instead. Put your title in a query string, paste the URL into a <meta> tag, done โ€” no signup, no deploy, no watermark:

The 10-second version

# a 1200x630 PNG social card โ€” this URL works right now
curl -o card.png "https://mockbird.mockbird.workers.dev/m/demo/og?title=My+launch+post"

# title + muted subtitle + footer with your site name
curl -o card.png "https://mockbird.mockbird.workers.dev/m/demo/og?title=Ship+week&subtitle=everything+we+released+in+May&site=example.com"

And in your page head:

<meta property="og:image"
      content="https://mockbird.mockbird.workers.dev/m/demo/og?title=My+launch+post&site=example.com">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">

dynamic OG card example

Prefer clicking to typing? The image playground has an OG card tab โ€” build the URL live with an instant preview.

Why PNG by default

This is the one endpoint where raster isn't optional: social scrapers don't render SVG. Facebook's crawler, Twitter/X cards, Slack unfurls, Discord embeds and Bluesky link cards all expect PNG/JPEG/GIF/WebP โ€” an SVG og:image simply shows nothing. So /og serves real PNG bytes by default (8-bit RGBA, decodes anywhere), and keeps an SVG twin behind .svg / ?format=svg for previews and oversized use. Details on where SVG fails: the PNG placeholder guide.

Every parameter

ParamWhat it does
titlethe big text โ€” up to 120 chars, word-wrapped onto up to 4 lines, auto-sized
subtitle / descsmaller muted text under the title โ€” up to 200 chars, up to 3 lines
sitesmall footer text with an accent square โ€” your domain or brand name
logo=<seed>deterministic 5ร—5 identicon mark bottom-right, in the accent color (same seed โ†’ same mark forever; see identicon API)
themedark (default) or light
bg / fg / accent3- or 6-digit hex without # โ€” full brand-color control
seedpicks the accent color deterministically from a palette (otherwise the title picks it)
/og/:WxHsize override, 120โ€“2000 per side โ€” /og/800x418, /og/600x600 square; PNG capped at 1,000,000 px (the default 1200ร—630 fits)
?format=svg or .svgvector twin โ€” real system font, any size
# light theme
curl -o card.png "https://mockbird.mockbird.workers.dev/m/demo/og?title=Light+mode&theme=light"

# brand colors + identicon logo
curl -o card.png "https://mockbird.mockbird.workers.dev/m/demo/og?title=Brand+colors&bg=0b1220&accent=22d3ee&logo=myapp&site=myapp.dev"

# other sizes: 800x418, square, whatever your platform wants
curl -o card.png "https://mockbird.mockbird.workers.dev/m/demo/og/800x418?title=Other+sizes"

light theme OG card brand colors OG card

Dynamic per page โ€” the actual point

Because the card is just a URL, "one og:image per page" stops being a build step. Interpolate the title in whatever renders your pages:

<!-- blog template (any templating language) -->
<meta property="og:image"
      content="https://mockbird.mockbird.workers.dev/m/demo/og?title={{ post.title | urlencode }}&site=blog.example.com&logo=blog">

Deterministic + Cache-Control: public means scrapers and CDNs cache each card and identical titles never re-render differently.

Testing link previews

The other use is the inverse: you're building the consumer โ€” a link-preview unfurler, a feed reader, a social app โ€” and need pages whose og:image is predictable. Point your test fixtures at /og URLs: any title you want, byte-identical on every fetch, no flaky third-party image host. (Your fixtures' pages can be mocked too: custom routes serve HTML with whatever meta tags you like.)

Honest comparison

Mockbird /og@vercel/og (satori)card-rendering SaaSstatic image per page
Setupnone โ€” paste a URLdeploy a function, JSX templates, font filessignup + template editor; free tiers are small, then paidimage editor every time
Typographyblocky pixel font on PNG (distinctive, legible โ€” see samples above)real fonts, full CSS โ€” wins on brand polishreal fonts, designed templatesanything you can draw
Images/screenshots in cardโœ˜ (identicon mark only)โœ”โœ”โœ”
Dynamic per URLโœ”โœ”โœ”โœ˜
Deterministic bytesโœ”depends on your codeusuallyโœ”
Costfree, no keyfree (your hosting)free tier โ†’ paidyour time

Being upfront: if you want brand-perfect typography, product screenshots in the card, or complex layouts, @vercel/og (or a paid template service) is the right tool โ€” satori renders real CSS with real fonts, and this endpoint doesn't try to compete with that. Mockbird's /og is the zero-setup placeholder tier: the dev/staging default, the side project that never got card art, the "unblock me today, polish later" URL. It's also honest about being a pixel font โ€” which reads as a deliberate aesthetic more often than you'd think.

Limits

โšก These URLs run on the shared demo project and work forever. Want your own namespace (and a full mock REST API + placeholder/avatar endpoints alongside it)? One click creates a project โ€” no signup.

Full reference in the docs. More image guides: placeholder image API ยท PNG placeholder API ยท chart image API ยท avatar API ยท identicon API ยท picsum alternative. Create your API โ†’