Hermesforge Screenshot API vs ScreenshotOne: Pricing, Features, and When to Switch
ScreenshotOne is the most visible commercial screenshot API on the market. If you've searched for a screenshot API, you've seen it. This post does a straight feature and pricing comparison between Hermesforge and ScreenshotOne — not a marketing exercise, but the kind of comparison you'd do before committing to one for a production integration.
Pricing at a Glance
| Tier | Hermesforge | ScreenshotOne |
|---|---|---|
| Free | 50/day, no signup | 100/month (not/day) |
| Entry paid | $4/30-day (200/day) | ~$19/month (1,000/month) |
| Mid tier | $9/30-day (1,000/day) | ~$49/month (10,000/month) |
| High volume | $29/30-day (5,000/day) | ~$99/month (50,000/month) |
The pricing models differ in a way that matters for agent workloads: Hermesforge is daily-rate (calls reset every 24 hours), ScreenshotOne is monthly pool (calls accumulate and expire monthly).
For AI agent use cases — bursty consumption where 50 screenshots happen in one pipeline run, then nothing for 24 hours — daily-rate pricing aligns better. A monthly pool of 1,000 calls is 33/day average; if your agent needs 50 in one run, you either overprovision or get surprised mid-month.
API Design Comparison
Both APIs use GET requests with query parameters. The key parameters:
| Parameter | Hermesforge | ScreenshotOne |
|---|---|---|
| Target URL | url= |
url= |
| Full page | full_page=true |
full_page_screenshot=true |
| Viewport width | width= |
viewport_width= |
| Format | format=png\|webp |
format=png\|jpg\|webp |
| Wait condition | wait_for=networkidle\|load\|domcontentloaded |
delay= (seconds) + wait_for_selector= |
| Block ads | block_ads=true |
block_ads=true |
| Authentication | X-API-Key header |
access_key= query param |
Authentication is a meaningful difference for agent integrations. Hermesforge uses the X-API-Key header, which keeps credentials out of URL logs. ScreenshotOne passes access_key as a query parameter, which means API keys can appear in server access logs, proxy logs, and referrer headers when the request is forwarded.
The wait condition handling also differs. Hermesforge's wait_for=networkidle waits for network activity to settle — useful for SPAs and dynamically loaded content. ScreenshotOne's delay= parameter is a fixed-second sleep, which works but can be either too short (content not loaded) or too slow (unnecessary wait on fast pages).
Feature Coverage
| Feature | Hermesforge | ScreenshotOne |
|---|---|---|
| PNG output | ✓ | ✓ |
| WebP output | ✓ | ✓ |
| JPEG output | ✗ | ✓ |
| Full page capture | ✓ | ✓ |
| Custom viewport | ✓ | ✓ |
| JavaScript rendering | ✓ | ✓ |
| Ad blocking | ✓ | ✓ |
| Network idle wait | ✓ | Delay-based |
| CSS injection | ✓ | ✓ |
| Custom cookies | ✗ | ✓ |
| Custom headers | ✗ | ✓ |
| PDF output | ✗ | ✓ |
| Async/webhook | ✗ | ✓ |
| S3 upload | ✗ | ✓ |
| Signed URLs | ✗ | ✓ |
ScreenshotOne has more features in the "advanced workflow" category: PDF output, async webhooks, S3 upload, signed URLs, custom cookies, and custom headers. These matter for specific use cases (scraping behind auth, archival pipelines, storage-integrated workflows).
Hermesforge is more narrowly focused on the core screenshot use case: fast, clean captures of public web pages with good JavaScript rendering and sensible defaults. That narrower scope is a tradeoff, not a deficit — the API is simpler, the integration is faster, and the daily-rate pricing fits agent workloads better.
Integration Example: Same Task, Both APIs
For comparison, here's the same screenshot task against both APIs:
import requests
import base64
# Hermesforge
def hermesforge_capture(url: str) -> bytes:
resp = requests.get(
"https://hermesforge.dev/api/screenshot",
params={
"url": url,
"width": 1440,
"format": "png",
"full_page": True,
"wait_for": "networkidle"
},
headers={"X-API-Key": "your_hermesforge_key"}
)
resp.raise_for_status()
return resp.content
# ScreenshotOne
def screenshotone_capture(url: str) -> bytes:
resp = requests.get(
"https://api.screenshotone.com/take",
params={
"access_key": "your_screenshotone_key",
"url": url,
"viewport_width": 1440,
"format": "png",
"full_page_screenshot": True,
"delay": 2 # Fixed 2-second wait instead of networkidle
}
)
resp.raise_for_status()
return resp.content
Both return PNG bytes. The integration surface is nearly identical. Migration between the two is a parameter rename exercise plus the auth header change.
When Hermesforge Is the Better Fit
Agent and automation workloads: Daily-rate pricing means bursty runs don't exhaust a monthly pool. An agent that takes 40 screenshots in one pipeline run on Monday, then 40 again on Friday, uses 80 calls in a week — well within the daily limit, no surprise mid-month exhaustion.
Free tier evaluation: 50 calls per day with no signup lets you test a full integration pipeline before committing. ScreenshotOne's 100/month free tier works out to 3 calls per day — not enough to test a meaningful workflow.
Simple integrations: Fewer parameters means less to configure. For the common case (capture a public page at standard viewport), url= + wait_for=networkidle covers it.
API key security: Header-based auth keeps keys out of URL logs. Matters more in production than in testing.
When ScreenshotOne Is the Better Fit
PDF generation: If you need PDFs alongside screenshots, ScreenshotOne covers both. Hermesforge is PNG/WebP only.
Authenticated pages: Custom cookies and headers let ScreenshotOne capture pages behind login. Hermesforge is public pages only.
Async pipelines with storage: Webhook delivery and S3 upload are built in. Useful for high-volume batch pipelines where you don't want to hold an HTTP connection open for each capture.
Monthly pool economics: If your consumption is predictable and continuous (e.g., 200 screenshots spread evenly across a month), a monthly pool may be cheaper at high volume than a daily-rate tier.
Migration Notes
If you're evaluating a switch from ScreenshotOne to Hermesforge (or vice versa), the migration is straightforward:
# Parameter mapping: ScreenshotOne → Hermesforge
PARAM_MAP = {
"viewport_width": "width",
"full_page_screenshot": "full_page",
# wait handled differently — replace delay= with wait_for=networkidle
}
# Auth change:
# ScreenshotOne: params["access_key"] = key
# Hermesforge: headers["X-API-Key"] = key
The only breaking change is wait_for=networkidle vs delay=N: if your current integration relies on a fixed-second wait for a specific page, you'll want to test that networkidle fires correctly for that page before switching.
Hermesforge Screenshot API: JavaScript rendering, full-page capture, PNG/WebP output, network idle wait. Get a free API key — 50 calls/day, no signup required.