OG Pilot
OG image API comparison

Hosted OG image API vs @vercel/og vs DIY Satori

Choosing an OG image API (or rolling your own) decides how every link preview looks on Slack, X, LinkedIn, and iMessage. This guide compares three real paths teams use in 2026: a hosted OG image generator API (OG Pilot), @vercel/og / Next.js ImageResponse, and DIY Satori. No invented benchmarks—capabilities below cite official docs; anything unverified is marked.

Who this is for

Developers and product teams deciding how to generate Open Graph images for:

  • Next.js apps already on Vercel
  • Multi-framework stacks (Rails, Astro, WordPress, static sites)
  • Agent / MCP workflows that should create social images from a URL

If you only need one static card, design it once and ship a PNG. If every route needs a branded preview, you need an og image generator API or an in-app renderer.

Comparison matrix: hosted API vs @vercel/og vs DIY Satori

DimensionHosted OG Pilot API@vercel/og / ImageResponseDIY Satori
Where it runsHosted API + CDN URL you put in og:imageYour Next.js/Vercel function (or compatible host)Your own worker/server + CDN
How you author layoutsReady templates (page, blog_post, product, …) + JWT paramsJSX + limited CSS via ImageResponseJSX/HTML subset via Satori; you wire PNG/SVG pipeline
Auth modelSign JWT locally with API key; key never leaves your server (docs)App-owned route; you secure query params yourselfYou own auth, abuse controls, and signing
Framework fitJS, Ruby, Python, PHP SDKs + WordPress plugin + MCPBest for Next.js App Router (next/og); @vercel/og elsewhereAny stack that can host a renderer
CSS / layout limitsTemplate system (no per-request CSS authoring)Flexbox + subset of CSS; no display: grid; max 500KB bundle incl. fonts/assets (Next.js ImageResponse, Vercel OG)Same Satori CSS subset unless you change engines
FontsHandled by templates / productttf / otf / woff (prefer ttf/otf) per Vercel/Next docsYou load and subset fonts
CachingCDN URLs; optional iat for daily bust (docs)@vercel/og sets cache headers for CDN reuse (Vercel)You configure CDN + cache keys
Agent / MCPPublic MCP at https://ogpilot.com/mcp (docs/mcp)Not productized as MCP; you’d wrap your routeBuild your own tool surface
Ops burdenDomain verify + API key; rendering ops hostedMaintain route, fonts, payload size, runtime limitsFull: Satori + Resvg (or similar), fonts, CDN, monitoring, abuse
Latency (p50 cold/warm)NEED VERIFY — measure against your domains and templatesNEED VERIFY — depends on function region, fonts, and asset fetchesNEED VERIFY — depends on your infra
Cost modelAccount credits / subscription (see in-app billing after signup) — NEED CITE for public list pricesFunction + bandwidth on your host; image compute billed as your platform bills edge/serverless — NEED CITE for your planInfra + engineering time — NEED CITE

Recommended OG size: 1200×630 is the size Vercel documents as the recommended OG image size (Vercel OG Image Generation).

When to pick hosted API, @vercel/og, or DIY

Pick a hosted OG image API (OG Pilot) when:

  • You need the same branded cards across Next.js, Rails, Astro, WordPress, or no-code pages
  • You want JWT-signed URLs and SDKs instead of maintaining a renderer
  • You want MCP tools (generate_og_image, debug_open_graph, …) for agent workflows (docs)
  • Editors should not own Edge Function CSS

Pick @vercel/og / ImageResponse when:

  • You are deep in Next.js App Router and want layouts as JSX next to the page
  • You accept Satori CSS limits and the 500KB bundle cap (Next.js docs)
  • One deployables-with-the-app pipeline is enough; no multi-CMS requirement

Pick DIY Satori when:

  • You need a custom rendering pipeline or non-Vercel runtime with full ownership
  • You already operate image workers and want zero SaaS dependency
  • You will maintain fonts, PNG conversion (e.g. Resvg), caching, and abuse protection yourself (Satori)

How Next.js ImageResponse and @vercel/og work

Official Next.js docs: import ImageResponse from next/og. It uses @vercel/og, Satori, and Resvg to turn JSX into PNG. Default size is 1200×630. Only flexbox and a CSS subset are supported; advanced layouts like display: grid will not work. Bundle size (JSX, CSS, fonts, images) must stay under 500KB. Font formats: ttf, otf, woff.

Sources: Next.js ImageResponse, Vercel OG Image Generation, Vercel OG image API.

Code sample — Next.js App Router route

import { ImageResponse } from 'next/og'
// App Router includes @vercel/og — no separate install required.

export async function GET() {
  return new ImageResponse(
    (
      <div
        style={{
          fontSize: 48,
          color: '#0f172a',
          background: '#fff7ed',
          width: '100%',
          height: '100%',
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'center',
          padding: 64,
        }}
      >
        Hello from ImageResponse
      </div>
    ),
    { width: 1200, height: 630 },
  )
}

Runtime note from Vercel: Pages Router + Node.js runtime does not support return new Response(…) with vercel/og; App Router and Edge combinations listed in their matrix are supported (Vercel OG docs).

How the OG Pilot OG image API works

  1. Sign up and verify your domain (DNS TXT) — https://ogpilot.com/sign_up
  2. Create an API key in Settings → API Keys
  3. Sign a JWT locally (HS256) with claims like iss (domain), sub (API key prefix), template, title, …
  4. POST https://ogpilot.com/api/v1/images with {"token":"<jwt>"} — response is a CDN image URL for og:image
  5. Or use SDKs: og-pilot-js, og_pilot_ruby, og-pilot (Python), og-pilot-php

Source: https://ogpilot.com/docs

Code sample — JavaScript SDK (server-side only)

import { configure, createImage } from "og-pilot-js"

configure((config) => {
  config.apiKey = process.env.OG_PILOT_API_KEY
  config.domain = process.env.OG_PILOT_DOMAIN
})

export async function blogOgImage(post: {
  title: string
  description: string
  path: string
  imageUrl?: string
}) {
  return createImage(
    {
      template: "blog_post",
      title: post.title,
      description: post.description,
      image_url: post.imageUrl,
      path: post.path,
    },
    { iat: Math.floor(Date.now() / 1000) },
  )
}

// Next.js metadata example
export async function generateMetadata({ params }) {
  const post = await getPost(params.slug)
  const ogImage = await blogOgImage({
    title: post.title,
    description: post.excerpt,
    path: `/blog/${post.slug}`,
  })
  return {
    openGraph: { images: [ogImage] },
    twitter: { card: "summary_large_image", images: [ogImage] },
  }
}

Raw HTTP shape (from docs)

POST https://ogpilot.com/api/v1/images
Content-Type: application/json

{"token":"YOUR_JWT_TOKEN"}

Never hardcode the API key in the browser. Sign on the server.

MCP: generate OG images from an agent

OG Pilot exposes a remote MCP endpoint at https://ogpilot.com/mcp. Documented tools include generate_og_image, debug_open_graph, compress_image, and extract_color_palette. Generation takes a page URL and returns an Open Graph image. Debug / compress / palette do not spend credits. Setup guide: https://ogpilot.com/docs/mcp

Connect MCP · Validate a URL

Copy-paste pointer for assistants (keep accurate to product docs; if exact Claude/ChatGPT JSON config differs by client, link /docs/mcp rather than inventing a connector JSON):

MCP endpoint pointer

Remote MCP URL: https://ogpilot.com/mcp
Docs: https://ogpilot.com/docs/mcp
OAuth: follow the custom connector guide on /docs/mcp (OAuth 2.1 + PKCE)

What “DIY Satori” actually means

Satori converts a limited HTML/CSS tree to SVG. @vercel/og already wraps Satori + Resvg for PNG. A DIY path means you choose:

  • Where Satori runs (Node worker, edge-compatible runtime, container)
  • How you convert SVG → PNG (Resvg or another engine)
  • Font loading / subsetting
  • URL design, signing, rate limits, and CDN cache keys
  • Monitoring when social crawlers hammer a popular post

That flexibility is real. So is the ongoing ops cost. NEED VERIFY any claim that DIY is “always cheaper” than hosted or Vercel Functions—it depends on volume, eng time, and failure modes.

Latency and cost — what we will not invent

  • Cold vs warm latency: NEED VERIFY with your own timings for OG Pilot CDN hits, Vercel Function regions, and DIY workers. Social crawlers also cache aggressively; first-fetch latency ≠ what users see after a platform cache is warm.
  • Cost per 1,000 images: NEED CITE from your host’s function/bandwidth pricing and from OG Pilot’s in-app plan after signup. Do not publish a round number here without a source.
  • Engineering cost: DIY and heavy custom @vercel/og layouts trade SaaS fees for design-system maintenance inside Edge bundles (watch the 500KB cap).

Use /open-graph-debugger after deploy to confirm crawlers see the URL you intended.

Decision checklist

  1. One framework on Vercel with JSX layouts you control? Start with ImageResponse.
  2. Multiple apps/CMS and one brand system? Prefer a hosted OG image API.
  3. Need agents to generate/debug cards? Prefer a product with MCP (/docs/mcp).
  4. Extreme custom rendering and you already run image infra? DIY Satori can win—budget for ops.
  5. Always put absolute og:image URLs in HTML and re-scrape after changes.

Ship the API path that matches your stack

Compare the matrix above, then activate: create an API key for signed CDN URLs, or connect MCP for agent-driven generation. If you are standardizing Next.js metadata only, keep ImageResponse—and still use the debugger before you trust a share. When brand templates must match across Rails, WordPress, and Next, one hosted OG image generator API keeps layouts from drifting.

OG image API questions

What is an OG image API?

A service or route that returns a social preview image (usually ~1200×630) for the og:image / Twitter card meta tags. Hosted APIs give you a CDN URL; @vercel/og returns the image from your function; DIY Satori means you run that pipeline yourself.

Is @vercel/og the same as Satori?

Closely related: Next.js documents that ImageResponse uses @vercel/og, Satori, and Resvg to produce PNG (https://nextjs.org/docs/app/api-reference/functions/image-response). Satori alone outputs SVG; you still need rasterization and hosting for most crawlers.

Can I use OG Pilot from Next.js instead of ImageResponse?

Yes. Sign requests server-side with og-pilot-js and pass the CDN URL into generateMetadata / openGraph.images. See /nextjs-og-image-generator and /docs.

Does OG Pilot support MCP?

Yes. Remote endpoint https://ogpilot.com/mcp with documented tools for generate and debug. Setup: /docs/mcp.

Will this page publish latency or price benchmarks?

Not without sources. Figures that are not from official docs or measured runs are labeled NEED CITE / NEED VERIFY. Check in-app billing after /sign_up for current OG Pilot plans.

Get an API key or connect MCP

Create a signed OG image generator API workflow in minutes—or keep @vercel/og for a single Next.js app and use the debugger before you ship.