DEV Community

Daniel Igel
Daniel Igel

Posted on

Auto-generate Open Graph preview images for any URL with the Website Screenshot API

Generating Open Graph preview images usually means running Playwright or Puppeteer on your own server — browser dependencies, a launch pool, queue management, and memory limits before you've written a single line of product logic.

One GET captures a screenshot of any public URL and returns it as base64 or raw binary:

curl --request GET \
  --url 'https://api.sprytools.com/v1/screenshot/api/v1/screenshot?url=https://example.com&format=png&viewport=desktop&fullPage=false&blockAds=true' \
  --header 'x-api-key: YOUR_API_KEY'
Enter fullscreen mode Exit fullscreen mode

You get { success, format, width, height, fullPage, image, size } where image is a base64-encoded PNG you can drop straight into an <img> src or write to a file.

For OG images the standard canvas is 1200 × 630 — pass a custom viewport instead of the desktop preset:

const res = await fetch('https://api.sprytools.com/v1/screenshot/api/v1/screenshot', {
  method: 'POST',
  headers: {
    'content-type': 'application/json',
    'x-api-key': process.env.SPRYTOOLS_API_KEY,
  },
  body: JSON.stringify({
    url: 'https://yourblog.com/posts/my-article',
    viewport: { width: 1200, height: 630 },
    format: 'png',
    blockAds: true,
    responseType: 'base64',
  }),
});
const { image } = await res.json();
// image is ready to store in S3, Cloudflare R2, or serve from a Next.js route handler
Enter fullscreen mode Exit fullscreen mode

Need to wait for a React or Vue page to finish hydrating before the screenshot fires? Add waitForSelector: '#hero-title' and the API holds until that element appears (up to the timeout you set, max 30 000 ms). format accepts png, jpeg, and webp; darkMode: true switches the OS colour scheme before capture.

Free key: 100 calls/day, no credit card — https://sprytools.com/apis/screenshot/

Do you generate OG images at build time or on-demand — and has one approach caused you more headaches than the other?

Top comments (0)