Features Full Page Screenshot Wait for Selector & Delay Block Cookie Banners Custom Viewport & Device Website to PDF HTML to Image Markdown to Image Dark Mode Image Format & Quality MCP Server Webhook Screenshot to Base64 Pricing Docs Blog Log In Sign Up

Screenshot to Base64 — Get Images as Base64 Strings via API

Vitalii Holben Vitalii Holben

Most screenshot APIs return a URL. You download the file, store it somewhere, serve it later. For a lot of workflows, that's fine. But if you're generating screenshots inside a Lambda function, embedding them in an email template, or passing them between microservices, that download-store-serve chain adds moving parts you don't need. A screenshot API with base64 response cuts out all those steps.

The response_type=base64 parameter returns the screenshot as a base64-encoded string inside a JSON response. You get the image data directly and use it wherever you need it, without configuring storage or setting up a CDN.

This page covers how the base64 screenshot response works, when it makes sense over binary files, and where it doesn't.

How the screenshot API returns base64

Add response_type=base64 to any screenshot request and the API returns JSON instead of a binary file. The response includes the base64-encoded image, its MIME type, dimensions, and file size.

curl "https://api.screenshotrun.com/v1/screenshots/capture?url=https://example.com&format=png&response_type=base64" \
  -H "Authorization: Bearer YOUR_API_KEY"

Response:

{
  "data": {
    "base64": "iVBORw0KGgoAAAANSUhEUgAA...",
    "mime_type": "image/png",
    "file_size": 45230,
    "width": 1280,
    "height": 800
  }
}

The base64 field contains the full image. Decode it and you have the exact same PNG (or JPEG, WebP, AVIF) you'd get from a binary response. The metadata fields save you a second request to check dimensions or file size.

Where base64 actually saves you work

Binary file responses work well when you have a server with a filesystem, a place to store images, and a URL to serve them from. Base64 shines in the gaps where that infrastructure doesn't exist or doesn't make sense.

Serverless functions

AWS Lambda, Vercel Functions, Cloudflare Workers. These environments have no persistent filesystem. If you've ever wired up a Lambda-to-S3 pipeline just to use an image once, you know how tedious that dance gets. With a base64 image API response, the image lives in your function's memory as a string. Pass it to another service, embed it in a response, store it in a database column. The storage layer disappears.

// Cloudflare Worker example
const response = await fetch(
  'https://api.screenshotrun.com/v1/screenshots/capture?url=https://example.com&format=webp&response_type=base64',
  { headers: { 'Authorization': 'Bearer YOUR_API_KEY' } }
);
const { data } = await response.json();

// Use directly — skip the storage layer entirely
return new Response(JSON.stringify({ screenshot: data.base64 }), {
  headers: { 'Content-Type': 'application/json' }
});

Email templates with inline images

Email clients don't fetch external images reliably. Gmail, Outlook, and Apple Mail all handle remote images differently, and corporate firewalls often block them entirely. The workaround is embedding the image directly in the email as a base64 data URI or a CID attachment. Both need the raw base64 string, not a URL.

// Inline image in HTML email
const imgTag = `<img src="data:${data.mime_type};base64,${data.base64}" alt="Dashboard screenshot" />`;

One call, one string. Done.

Chat bots and Slack integrations

If your bot takes a screenshot and posts it to a Slack channel or Discord webhook, you need the image data in memory. With a binary response you'd save to a temp file, then upload it via multipart form data. With base64, you already have the data as a string. Decode it to a buffer and pass it straight to files.uploadV2 or the Discord attachment endpoint. No temp file, no disk I/O.

Database storage

Some applications store screenshots in the database alongside the record they belong to. A monitoring tool that captures a page state and stores it with the check result. A testing framework that saves failure screenshots in the test report. Base64 strings go straight into a TEXT or BLOB column without touching the filesystem.

Not the best pattern for high-volume storage (file systems and object stores are cheaper per byte), but for low-volume, tightly-coupled data it removes a layer of complexity.

Base64 screenshot response vs binary vs JSON

The API supports three response types. Each fits a different workflow.

Response type What you get Best for
image (default) Binary file with Content-Type header Direct display, saving to disk, piping to storage
json JSON with metadata and image link Async workflows, status checking, webhook pipelines
base64 JSON with base64-encoded image + metadata Serverless, email embedding, chat bots, DB storage

If you have a server with disk access, image is simpler and faster (smaller response, no encoding overhead). If you need the image data in-memory without touching a filesystem, base64 is the shorter path.

The file size tradeoff

Base64 encoding adds roughly 33% to the payload size. A 300 KB PNG becomes about 400 KB as a base64 string. For most screenshots this is fine. A typical webpage screenshot in WebP format is 200-500 KB, which means 270-670 KB base64. Well within normal API response sizes.

Where it starts to matter: full-page screenshots of long pages in PNG format. These can reach 5-10 MB as binary files, which means 6.7-13.4 MB as base64. That's a large JSON response. If you're capturing long pages at high resolution, binary responses with direct storage might be the better choice.

A practical rule: if your screenshots are consistently under 2 MB, base64 works without issues. Above that, consider using response_type=image and streaming to storage.

Pairs well with these parameters

Since base64 only changes how the result is delivered, you can combine it with any capture setting. A few combinations worth trying:

WebP + base64 for minimal payload. WebP typically produces files 25-40% smaller than PNG at the same visual quality. Smaller file means smaller base64 string, faster response.

curl "https://api.screenshotrun.com/v1/screenshots/capture?url=https://example.com&format=webp&quality=80&response_type=base64" \
  -H "Authorization: Bearer YOUR_API_KEY"

Selector + base64 for component screenshots. Capture just a specific element (a chart, a card, a hero section) and get it back as base64. Much smaller payload than a full page.

curl "https://api.screenshotrun.com/v1/screenshots/capture?url=https://example.com&selector=.pricing-table&response_type=base64" \
  -H "Authorization: Bearer YOUR_API_KEY"

HTML to image + base64 for dynamic templates. Send HTML markup, get a base64 image back. Useful for generating email headers, social cards, or report visuals from templates without hosting anything. You can also pass Markdown instead of HTML.

What other screenshot APIs don't offer

I checked the major screenshot APIs while building this, and it surprised me that converting a screenshot to a base64 string is almost always a DIY step. Most APIs return either a binary file or a URL pointing to a hosted image. If you need the data as a string, you download the file and encode it yourself. Two requests instead of one, plus temporary storage in between.

Browserless supports base64 output, but it's a headless browser service, not a screenshot API. You're writing Puppeteer scripts, managing browser contexts, handling timeouts. Different tool for a different problem.

With ScreenshotRun's screenshot API, base64 is a parameter on the same endpoint. All the capture features work exactly the same: full-page capture, dark mode, cookie blocking, format options, webhooks. You're just choosing a different delivery format.

When not to use base64

Honest answer: base64 isn't always the right choice. Skip it when:

  • You're capturing many pages in a loop and storing them long-term. Object storage (S3, R2, GCS) with binary uploads will be more efficient.
  • Screenshots are large (full-page, retina, PNG). The 33% overhead mentioned above adds up at volume.
  • You're serving the image to end users via a URL. A hosted file with a CDN in front is faster than decoding base64 on every request.
  • Your language or framework has built-in file handling that makes binary responses trivial. Python's requests library, for instance, saves a binary response to disk in two lines.

Base64 is best for short-lived, in-memory use cases. If the screenshot needs to persist beyond the current request, binary is usually simpler.

Quick reference

Parameter Value Description
response_type base64 Returns the screenshot as a base64-encoded string inside a JSON response

Works with all capture parameters: url, html, markdown, format, width, height, full_page, selector, dark_mode, retina, and everything else. For PDF output (format=pdf), the base64 string contains the raw PDF data, not an image. Complete parameter list in the API docs.

Response fields

Field Type Description
data.base64 string Base64-encoded image data
data.mime_type string MIME type of the image (image/png, image/webp, etc.)
data.file_size integer Original file size in bytes (before base64 encoding)
data.width integer Image width in pixels
data.height integer Image height in pixels

Start with one request. Take a URL you're already capturing, add response_type=base64, and see what the response looks like. If the JSON size works for your use case and you don't need the file beyond the current request, base64 will stay in your code. If the payload turns out too large, switching back to binary is one parameter.

Get screenshots as base64 strings. No storage needed.

Get your free API key

Frequently asked questions

Instead of returning a binary image file, the API returns the screenshot as a base64-encoded string inside a JSON response. You can use this string directly — embed it in HTML as a data URI, store it in a database, or pass it between services without downloading a file first.

Base64 encoding adds roughly 33% to the payload size. A 300 KB screenshot becomes about 400 KB as a base64 string. For most captures (under 2 MB), this is a practical tradeoff for not needing intermediate file storage.

Yes. The response_type=base64 parameter works with PNG, JPEG, WebP, AVIF, and TIFF. The mime_type field in the response tells you which format the base64 string contains, so you can decode it correctly.

Most don't. Urlbox, ScreenshotOne, ApiFlash, and Screenshotlayer return binary files or hosted URLs. If you need base64, you typically download the file and encode it yourself. ScreenshotRun returns base64 natively in a single request.

Use binary (response_type=image) when storing screenshots long-term in object storage, serving them via CDN to end users, or capturing large full-page screenshots where the 33% size increase matters. Base64 is best for short-lived, in-memory use cases like serverless functions and email embedding.