Screenshot API Pricing: Plans, Credits and Free Tier

RenderScreenshot pricing: one credit per fresh render, free cache hits and failures, a free monthly plan, and a calculator for your screenshot volume.

By Simon Chiu · Updated

Plans

Free

$0

150 credits every month, no credit card

  • 10 requests per minute per API key
  • Batches of up to 5 URLs, 2 rendered at once
  • Screenshots stored on our CDN
Get a free API key

Starter

$10 / month

2,500 credits every month

  • $4.00 per 1,000 fresh renders
  • 60 requests per minute per API key
  • Batches of up to 20 URLs, 5 rendered at once
  • Our CDN, or upload to your own S3-compatible bucket
Start free, upgrade to Starter

Growth

$40 / month

12,000 credits every month

  • $3.33 per 1,000 fresh renders
  • 120 requests per minute per API key
  • Batches of up to 50 URLs, 10 rendered at once
  • Our CDN, or upload to your own S3-compatible bucket
Start free, upgrade to Growth

Scale

$100 / month

60,000 credits every month

  • $1.67 per 1,000 fresh renders
  • 200 requests per minute per API key
  • Batches of up to 100 URLs, 20 rendered at once
  • Our CDN, or upload to your own S3-compatible bucket
Start free, upgrade to Scale

Prices in USD, billed monthly through Stripe. Every plan has every rendering feature: all formats including PDF, full-page and element capture, presets, devices, ad and cookie-banner blocking, signed URLs, webhooks and batch. One fresh render uses one credit.

What 1,000, 10,000 and 100,000 screenshots cost

The cheapest plan that covers each monthly volume. The second column assumes half of your requests are repeats served from cache with cache.available, which use no credits.

Requests / month Every request renders fresh Half served from cache
1,000 Starter, $10 ($10.00 per 1,000 requests) Starter, $10 ($10.00 per 1,000 requests)
10,000 Growth, $40 ($4.00 per 1,000 requests) Growth, $40 ($4.00 per 1,000 requests)
100,000 Above the largest self-serve plan: email [email protected] Scale, $100 ($1.00 per 1,000 requests)

Estimate your plan

Fresh renders (credits used):

Last verified: October 15, 2026, against the billing code, the caching docs and the batch docs. The plan cards and tables above read from the same plan data that billing enforces, so they change when the plans change.

RenderScreenshot bills in credits. One fresh render uses one credit. It does not matter if the render is a thumbnail, a 1200x630 social card, a full-page capture of a long article or a multi-page PDF. Repeats served from cache, failed renders and rejected requests use no credits. Plans differ only in how many credits you get each month, your rate limit and your batch size. Every rendering feature is in every plan, the Free plan included.

The rest of this page explains what uses a credit, what does not, and how to keep repeat traffic at zero credits. If you want to compare our prices with other vendors, see the screenshot API pricing comparison. It puts ten vendors on one grid and reports the volumes where we are not the cheapest.

What uses a credit

Request Credits Notes
Screenshot of a URL (PNG, JPEG or WebP) 1 Any viewport, device, preset or quality
Full-page or element capture 1 Page height does not change the price
PDF (format: pdf) 1 Paper size, margins and page count do not change the price
Render from html or markdown input instead of a URL 1 Same price as a URL
Repeat request with cache.available, found in cache 0 Response has cache.hit: true
Repeat request with cache.available, not in cache 1 A normal render that refills the cache
Request with cache.refresh 1 Forces a new render
Batch request 1 per URL that renders Failed URLs use 0. The batch needs enough credits for all URLs before it starts
Render that fails in the browser (target error, timeout) 0 You get an error response
Validation error, bad API key, rate limit (429) 0 Rejected before any render
Image fetched through the X-Cache-URL CDN link 0 Served by the CDN, never reaches the API
Cache management, presets list, devices list 0 Read and admin endpoints
Webhook delivery or upload to your own bucket 0 Included in the render
Render from the dashboard playground 1 Uses your account credits like an API call

Two features depend on the plan, not on credits. Upload to your own S3-compatible bucket is on paid plans only. Batch size and batch concurrency increase with each plan.

Three rules that decide your bill

1. You pay per render, not per second or per byte

Our renderer runs headless Chromium on Cloudflare Browser Rendering, which bills us by browser time. A slow, heavy page costs us more than example.com. We decided that this variance is our problem, not yours. A credit is a credit, so you can predict your bill from your request count alone. If you prefer to pay for raw browser time and build the rest yourself, calling Cloudflare directly is a fair option, and that page shows what you would have to build.

2. Repeats are free only when you ask for the cache

By default, two identical requests make two renders and use two credits. Add cache.available: true (or cache_available=true on a GET) and the API first looks for a successful render from your account with the same rendering parameters inside the cache TTL. A hit returns the stored image at zero credits. A miss renders as normal. The default TTL is 24 hours, and you can set from 1 hour up to 30 days with cache.ttl. Cache entries belong to your account and are never shared with other accounts.

You still need at least one credit left to make a request, because the API cannot know in advance if the request will be a hit or a miss.

3. Credits reset each period, and there is no overage

The Free plan resets on the first day of every month. Paid plans reset when each monthly invoice is paid. Unused credits do not carry over. When you reach zero, requests fail with HTTP 403 and the code insufficient_credits. We do not bill extra usage automatically, so a loop or a crawler storm cannot produce a surprise invoice. If you upgrade in the middle of a period, your allowance goes up to the new plan at once, and the credits you already used still count.

The other side of this rule: a hard stop also stops your screenshots. If your product cannot accept failed captures at the end of a busy month, watch the remaining credits (code below) or choose a plan with headroom.

Keep repeat traffic at zero credits

These three requests do the same thing. Each asks for an og_card render of a page with cache.available set, then reports whether it was a cache hit, the credits it used and the credits left. Run one of them twice: the second run reports a cache hit and zero credits used.

cURL

curl -s -o og.png -D - \
  "https://api.renderscreenshot.com/v1/screenshot?url=https%3A%2F%2Fexample.com&preset=og_card&cache_available=true" \
  -H "Authorization: Bearer $RS_API_KEY" | grep -iE '^x-(cache|credits)'
# X-Cache-Hit, X-Cache-URL, X-Credits-Used and X-Credits-Remaining come back on every image response

Node.js

// credits.mjs (Node 22+). Usage: RS_API_KEY=rs_live_... node credits.mjs https://example.com
const target = process.argv[2] ?? 'https://example.com';

const res = await fetch('https://api.renderscreenshot.com/v1/screenshot', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.RS_API_KEY}`,
    'Content-Type': 'application/json',
    Accept: 'application/json', // JSON metadata instead of the image bytes
  },
  body: JSON.stringify({ url: target, preset: 'og_card', cache: { available: true } }),
});

const body = await res.json();
if (!res.ok) {
  console.error(`${res.status} ${body.error?.code}: ${body.error?.message}`);
  process.exit(1);
}

const { hit, url } = body.cache;
const { credits, remaining } = body.usage;
console.log(`cache hit: ${hit} | credits used: ${credits} | credits left: ${remaining}`);
console.log(`public CDN URL: ${url}`);
if (remaining < 100) console.warn('Fewer than 100 credits left in this period.');

Python

# credits.py (Python 3.10+, standard library only).
# Usage: RS_API_KEY=rs_live_... python credits.py https://example.com
import json
import os
import sys
import urllib.error
import urllib.request

target = sys.argv[1] if len(sys.argv) > 1 else "https://example.com"
payload = {"url": target, "preset": "og_card", "cache": {"available": True}}

req = urllib.request.Request(
    "https://api.renderscreenshot.com/v1/screenshot",
    data=json.dumps(payload).encode(),
    headers={
        "Authorization": f"Bearer {os.environ['RS_API_KEY']}",
        "Content-Type": "application/json",
        "Accept": "application/json",  # JSON metadata instead of the image bytes
    },
    method="POST",
)

try:
    with urllib.request.urlopen(req, timeout=60) as res:
        body = json.load(res)
except urllib.error.HTTPError as err:
    error = json.load(err).get("error", {})
    sys.exit(f"{err.code} {error.get('code')}: {error.get('message')}")

usage, cache = body["usage"], body["cache"]
print(f"cache hit: {cache['hit']} | credits used: {usage['credits']} | credits left: {usage['remaining']}")
print(f"public CDN URL: {cache['url']}")
if usage["remaining"] < 100:
    print("Fewer than 100 credits left in this period.", file=sys.stderr)

Checked on October 15, 2026 with Node 22.18 and Python 3.14 against a local stub that returns the documented response shape and the insufficient_credits error. The stub confirms the parsing and the non-zero exit code on errors; it is not a live render.

The value of the 100-credit warning is yours to choose. Put it where your monitoring can see it: a log line, a metric or a message to your team channel.

Where credits leak, and how to stop it

Public image URLs. If you put an API URL in an <img> tag or an og:image meta tag, every fetch by a browser or a social crawler is a new GET request. Without cache_available=true, each fetch is a fresh render. Two fixes:

  • Use the X-Cache-URL link (or cache.url in JSON). It is a public CDN link that needs no key, and fetches of it never reach the API, so they use no credits. It stays valid until the cache entry expires.
  • If you use signed URLs, put cache_available=true in the query string before you sign it. The signature covers every query parameter. The SDK builders expose cache TTL and refresh but not this flag, so sign the query yourself as the signed URL docs show.

Retries that are not retries. A retry after a 429 or a failed render costs nothing, because neither used a credit. A retry after a timeout in your client can cost a second credit if the first render succeeded on our side. Set cache.available on retries, and the second call returns the first render at zero credits.

Batch loops. A batch uses the same credits as single requests, one per URL. The gain is throughput, not price: one request, your plan's batch concurrency, and an optional webhook when the batch finishes.

When the API costs more than running a browser yourself

At high, steady volume, a self-hosted browser fleet can cost less per screenshot than any per-render plan. The trade is your time: fonts, memory leaks, timeouts, retries, storage and a CDN. Our guide to choosing a screenshot API covers that decision. If your volume is above our largest self-serve plan, email [email protected] before you build anything.

To start, get a free API key. You need no credit card, and the free credits renew every month.

Frequently asked questions

Do failed screenshots use credits?
No. A credit is deducted only after a render succeeds. Validation errors, authentication errors, rate-limited requests and renders that fail in the browser use no credits. In a batch, only the URLs that render use credits.
Is a PDF or a full-page screenshot more expensive than a normal screenshot?
No. Every fresh render uses one credit, whatever the format (PNG, JPEG, WebP or PDF), the viewport, the device or the page height.
Do unused credits roll over to the next month?
No. On the Free plan the allowance resets on the first day of each month. On paid plans it resets when each monthly invoice is paid.
What happens when I run out of credits?
Requests return HTTP 403 with the error code insufficient_credits until your allowance resets or you upgrade. There are no automatic overage charges, so your bill never goes above your plan price.
Do I need a credit card for the free plan?
No. Sign up with an email address and you get an API key and a monthly allowance of free credits. You add a card only when you upgrade.

Related in this topic

Try RenderScreenshot free

150 free credits every month, no credit card required.