How to Automate Website Screenshots for Social Media Posts

February 24, 2026 · 7 min read

You've built something cool and want to share it on Twitter, LinkedIn, or Reddit. The fastest way to show it off? A clean screenshot of your website. But manually screenshotting, cropping, and uploading gets old fast, especially if you're sharing multiple pages, tracking competitors, or running a content calendar.

A website screenshot API lets you turn any URL into a share-ready image with a single HTTP request. In this guide, we'll walk through practical workflows for generating social media content from screenshots automatically.

Why Use an API Instead of Manual Screenshots?

Manual screenshots work fine for one-off posts. But they fall apart when you need to:

With an API, you define the URL, dimensions, and format once - then let your code handle the rest.

Quick Start: Capture a Screenshot

Let's start with the basics. Here's how to capture a website screenshot using GrabShot:

curl

curl "https://grabshot.dev/api/screenshot?url=https://example.com&width=1200&height=675&format=png" \
  -H "X-API-Key: YOUR_API_KEY" \
  -o screenshot.png

Node.js

const fetch = require('node-fetch');
const fs = require('fs');

async function captureForSocial(url, platform = 'twitter') {
  const dimensions = {
    twitter:   { width: 1200, height: 675 },
    linkedin:  { width: 1200, height: 627 },
    instagram: { width: 1080, height: 1080 },
    facebook:  { width: 1200, height: 630 },
  };

  const { width, height } = dimensions[platform] || dimensions.twitter;

  const apiUrl = new URL('https://grabshot.dev/api/screenshot');
  apiUrl.searchParams.set('url', url);
  apiUrl.searchParams.set('width', width);
  apiUrl.searchParams.set('height', height);
  apiUrl.searchParams.set('format', 'png');

  const response = await fetch(apiUrl, {
    headers: { 'X-API-Key': process.env.GRABSHOT_API_KEY }
  });

  const buffer = Buffer.from(await response.arrayBuffer());
  const filename = `screenshot-${platform}-${Date.now()}.png`;
  fs.writeFileSync(filename, buffer);
  console.log(`Saved ${filename} (${width}x${height})`);
  return filename;
}

// Capture for all platforms at once
async function captureAllPlatforms(url) {
  const platforms = ['twitter', 'linkedin', 'facebook'];
  return Promise.all(platforms.map(p => captureForSocial(url, p)));
}

captureAllPlatforms('https://your-site.com');

Python

import requests
import os

def capture_for_social(url, platform='twitter'):
    dimensions = {
        'twitter':   (1200, 675),
        'linkedin':  (1200, 627),
        'instagram': (1080, 1080),
        'facebook':  (1200, 630),
    }

    width, height = dimensions.get(platform, (1200, 675))

    response = requests.get(
        'https://grabshot.dev/api/screenshot',
        params={'url': url, 'width': width, 'height': height, 'format': 'png'},
        headers={'X-API-Key': os.environ['GRABSHOT_API_KEY']}
    )

    filename = f'screenshot-{platform}.png'
    with open(filename, 'wb') as f:
        f.write(response.content)

    print(f'Saved {filename} ({width}x{height})')
    return filename

# Example: capture for Twitter
capture_for_social('https://your-site.com', 'twitter')

Social Media Image Dimensions Reference

Each platform has different optimal image sizes. Here's a quick reference:

PlatformFormatWidthHeightAspect Ratio
Twitter/XCard image120067516:9
LinkedInPost image12006271.91:1
FacebookShared image12006301.91:1
InstagramSquare post108010801:1
RedditPost image12006281.91:1
Product HuntGallery1270760~5:3

Practical Use Case: Weekly Competitor Roundup

Say you track 5 competitors and want to post a weekly "what changed" thread. Here's a Node.js script that captures all their homepages and saves them for comparison:

const fetch = require('node-fetch');
const fs = require('fs');

const competitors = [
  { name: 'competitor-a', url: 'https://competitor-a.com' },
  { name: 'competitor-b', url: 'https://competitor-b.com' },
  { name: 'competitor-c', url: 'https://competitor-c.com' },
];

async function weeklyCapture() {
  const date = new Date().toISOString().slice(0, 10);
  const dir = `captures/${date}`;
  fs.mkdirSync(dir, { recursive: true });

  for (const comp of competitors) {
    const apiUrl = `https://grabshot.dev/api/screenshot?url=${encodeURIComponent(comp.url)}&width=1200&height=675&full_page=true&format=png`;

    const res = await fetch(apiUrl, {
      headers: { 'X-API-Key': process.env.GRABSHOT_API_KEY }
    });

    const buffer = Buffer.from(await res.arrayBuffer());
    fs.writeFileSync(`${dir}/${comp.name}.png`, buffer);
    console.log(`Captured ${comp.name}`);
  }

  console.log(`All captures saved to ${dir}/`);
}

weeklyCapture();

You can pair this with the GrabShot full-page screenshot option to capture entire landing pages, then use the images in a Twitter thread or LinkedIn carousel.

Use Case: Automated Changelog Posts

Every time you ship a feature, capture a screenshot and post it automatically. Here's a simplified flow:

  1. Deploy your app (CI/CD pipeline finishes)
  2. Hit the screenshot API to capture the new feature page
  3. Post to Twitter/LinkedIn with the image and a short description
import requests
import os

def post_changelog_screenshot(feature_url, description):
    # Step 1: Capture the screenshot
    screenshot = requests.get(
        'https://grabshot.dev/api/screenshot',
        params={
            'url': feature_url,
            'width': 1200,
            'height': 675,
            'format': 'png'
        },
        headers={'X-API-Key': os.environ['GRABSHOT_API_KEY']}
    )

    with open('/tmp/changelog.png', 'wb') as f:
        f.write(screenshot.content)

    # Step 2: Upload to your social media tool of choice
    # (Tweepy, LinkedIn API, Buffer, etc.)
    print(f'Screenshot ready for: {description}')
    return '/tmp/changelog.png'

# After deploying your new pricing page:
post_changelog_screenshot(
    'https://your-app.com/pricing',
    'Just shipped our new pricing page with annual discounts!'
)

Tips for Better Social Media Screenshots

Raw screenshots work, but a few tweaks make them look much more professional:

Start Capturing Screenshots for Social Media

GrabShot's free plan includes 25 screenshots per month. No credit card required.

Try It Free

Automating with Cron Jobs

The real power comes from running captures on a schedule. A simple cron job can capture your landing page every Monday and save it for your weekly social post:

# crontab -e
# Every Monday at 9am, capture and save
0 9 * * 1 curl "https://grabshot.dev/api/screenshot?url=https://your-site.com&width=1200&height=675&format=png" \
  -H "X-API-Key: $GRABSHOT_API_KEY" \
  -o ~/screenshots/weekly-$(date +\%Y-\%m-\%d).png

Combine this with a posting script (using the Twitter API, LinkedIn API, or a tool like Buffer), and you have a fully automated social media pipeline for website screenshots.

Wrapping Up

A screenshot API turns the tedious process of manually capturing, resizing, and uploading website images into a single HTTP call. Whether you're building a changelog bot, a competitor tracking dashboard, or just want consistent social media content, automating screenshots saves real time.

If you want to try it out, GrabShot's free tier gives you 25 captures per month to experiment with. The API docs cover all the parameters for viewport sizes, delays, formats, and more.