Screenshot APIs for Digital Marketing: Monitor Campaigns and Track Competitor Ads
Screenshot APIs for Digital Marketing: Monitor Campaigns and Track Competitor Ads
Digital marketing teams live in a world of transient content. Ad creative runs for a week and disappears. Landing pages get A/B tested and swapped. Competitor promotions appear and vanish. Most of this content is never systematically captured — until something goes wrong or a client asks "what did that page look like before the redesign?"
Screenshot APIs give marketing teams a way to build continuous visual archives of campaigns, competitive activity, and client work — automatically.
Campaign Landing Page Archives
Every campaign has a beginning and an end. Before you redirect or take down a landing page, you want a record of what it looked like. More importantly, you want records throughout the campaign — to track changes, document performance context, and support future creative decisions.
import requests
from datetime import date
import os
SCREENSHOT_API = "https://hermesforge.dev/api/screenshot"
API_KEY = "YOUR_KEY"
CAMPAIGN_PAGES = [
{
"campaign": "summer-sale-2026",
"pages": [
"https://yoursite.com/summer-sale",
"https://yoursite.com/summer-sale/products",
"https://yoursite.com/summer-sale/checkout",
]
}
]
def capture_campaign_state(campaign_name, urls):
"""Capture all pages in a campaign at a point in time."""
today = date.today().isoformat()
base_dir = f"campaigns/{campaign_name}/{today}"
os.makedirs(base_dir, exist_ok=True)
for url in urls:
slug = url.split("/")[-1] or "index"
# Desktop capture
desktop = requests.get(SCREENSHOT_API, params={
"url": url,
"width": 1440,
"height": 900,
"delay": 1500,
"format": "webp"
}, headers={"X-API-Key": API_KEY})
with open(f"{base_dir}/{slug}-desktop.webp", "wb") as f:
f.write(desktop.content)
# Mobile capture
mobile = requests.get(SCREENSHOT_API, params={
"url": url,
"width": 390,
"height": 844,
"delay": 1500,
"format": "webp"
}, headers={"X-API-Key": API_KEY})
with open(f"{base_dir}/{slug}-mobile.webp", "wb") as f:
f.write(mobile.content)
print(f"Captured {slug} (desktop + mobile)")
# Run at campaign launch and weekly throughout
for campaign in CAMPAIGN_PAGES:
capture_campaign_state(campaign["campaign"], campaign["pages"])
Running both desktop and mobile captures is important — many campaigns have responsive designs that look substantially different at mobile viewport sizes.
Competitive Ad and Landing Page Intelligence
Paid search campaigns drive traffic to specific landing pages. Monitoring competitor landing pages gives you a window into their positioning, offers, and creative direction.
COMPETITOR_LANDING_PAGES = [
{
"competitor": "company-a",
"pages": [
"https://competitor-a.com/lp/product-keyword",
"https://competitor-a.com/lp/brand-keyword",
]
},
{
"competitor": "company-b",
"pages": [
"https://competitor-b.com/demo",
"https://competitor-b.com/pricing",
]
}
]
def weekly_competitive_capture():
"""Weekly competitive intelligence sweep."""
today = date.today().isoformat()
for competitor_data in COMPETITOR_LANDING_PAGES:
for url in competitor_data["pages"]:
slug = url.replace("https://", "").replace("/", "-")
save_path = f"competitive/{competitor_data['competitor']}/{today}-{slug}.png"
os.makedirs(os.path.dirname(save_path), exist_ok=True)
response = requests.get(SCREENSHOT_API, params={
"url": url,
"width": 1440,
"height": 1200,
"delay": 2000
}, headers={"X-API-Key": API_KEY})
with open(save_path, "wb") as f:
f.write(response.content)
weekly_competitive_capture()
The resulting archive shows how competitor landing pages evolve over time — new offers, messaging changes, design refreshes, and promotional emphasis.
Client Reporting Screenshots
Agencies routinely document their work for client reporting. Manually screenshotting client sites and campaigns before quarterly reviews is time that screenshot automation can reclaim.
CLIENT_REPORT_PAGES = {
"client-acme": {
"pages": [
"https://acme.com",
"https://acme.com/products",
"https://acme.com/contact",
],
"report_frequency": "monthly"
}
}
def generate_client_screenshots(client_name, pages):
"""Generate a set of screenshots for client reporting."""
today = date.today().isoformat()
report_dir = f"reports/{client_name}/{today}"
os.makedirs(report_dir, exist_ok=True)
for url in pages:
page_name = url.split("/")[-1] or "homepage"
for viewport in [(1440, 900, "desktop"), (390, 844, "mobile")]:
width, height, label = viewport
response = requests.get(SCREENSHOT_API, params={
"url": url,
"width": width,
"height": height,
"delay": 2000,
"format": "png"
}, headers={"X-API-Key": API_KEY})
with open(f"{report_dir}/{page_name}-{label}.png", "wb") as f:
f.write(response.content)
return report_dir
The output feeds directly into report templates or slide decks — no manual screenshotting required.
Before/After Campaign Comparisons
One of the most useful outputs for stakeholder communication is a visual before/after comparison. Screenshot archives make this trivial when they've been captured consistently:
from PIL import Image
import numpy as np
def create_comparison(before_path, after_path, output_path):
"""Create a side-by-side before/after comparison image."""
before = Image.open(before_path).resize((720, 500))
after = Image.open(after_path).resize((720, 500))
comparison = Image.new("RGB", (1440, 500))
comparison.paste(before, (0, 0))
comparison.paste(after, (720, 0))
from PIL import ImageDraw, ImageFont
draw = ImageDraw.Draw(comparison)
draw.text((10, 10), "BEFORE", fill="white")
draw.text((730, 10), "AFTER", fill="white")
comparison.save(output_path)
Before/after comparisons for a homepage redesign, a landing page optimization, or a pricing page update are immediately understandable to non-technical stakeholders.
UTM Parameter Preservation
Some landing pages render differently based on UTM parameters (showing specific offer copy for different traffic sources). Capture the parameter-specific versions:
UTM_VARIANTS = [
"?utm_source=google&utm_medium=cpc&utm_campaign=brand",
"?utm_source=facebook&utm_medium=paid_social&utm_campaign=retargeting",
"?utm_source=email&utm_medium=newsletter&utm_campaign=weekly",
]
base_url = "https://yoursite.com/offer"
for utm in UTM_VARIANTS:
full_url = base_url + utm
slug = utm.replace("?", "").replace("&", "-").replace("=", "_")
response = requests.get(SCREENSHOT_API, params={
"url": full_url,
"width": 1440,
"height": 900,
"delay": 2000
}, headers={"X-API-Key": API_KEY})
with open(f"utm-variants/{slug}.png", "wb") as f:
f.write(response.content)
This is particularly useful for validating that personalization and dynamic content is working correctly for each traffic source.
The screenshot API includes WebP format support for smaller file sizes — useful when building large campaign archives. Batch capturing multiple URLs in sequence keeps API usage efficient.