DriversRecommendedOutdated drivers can make a good PC feel brokenScan driver issues before chasing fixes manually.Scan NowOctober DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsPC HealthRecommendedCrashes, freezes, slowdowns? Check your PC nowSpot repairable issues before they interrupt work.Check PC×
Skip to content
World desk5 min

How to Send a Screenshot API Request from a Chrome Extension

Use Chrome’s visible-tab capture API, convert the data URL to a Blob, and upload it from extension-owned code with the permissions and API contract set correctly.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

In a Chrome extension, call chrome.tabs.captureVisibleTab() after a user action, convert its returned data URL to a Blob, and upload it with fetch() from the extension’s service worker or an extension page. Declare the capture permission and permission for the API host in the manifest. The upload method, authentication, multipart field, accepted formats, size limit, and response parsing are determined by the receiving API—not by Chrome.

What the extension captures—and what the API receives

chrome.tabs.captureVisibleTab() captures the active tab’s visible viewport and returns a data URL. It does not produce a full-page image. Chrome documents a maximum of two calls per second for this method. See the Chrome tabs API reference.

As an Amazon Associate I earn from qualifying purchases.

The screenshot API is a separate part of the workflow. Before implementing the request, check its documentation for the exact endpoint, HTTP method, authorization scheme, accepted image formats, request body or multipart field name, payload limit, and response format. The example below uses multipart form data and a bearer token as a template; those details are not universal.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Declare the permissions in Manifest V3

For a capture initiated by the user, activeTab is usually narrower than granting access to every site. Add a host permission for the API origin so extension-owned code can make the cross-origin request. Replace api.example.com with the API host, narrowing the pattern as appropriate.

{
  "manifest_version": 3,
  "permissions": ["activeTab"],
  "host_permissions": ["https://api.example.com/*"],
  "background": {
    "service_worker": "service-worker.js"
  }
}

Chrome documents activeTab and <all_urls> as permission options for visible-tab capture. Use the broader permission only when the extension’s behavior requires it. Chrome also supports optional host permissions that can be requested at runtime; see Declare permissions.

Capture the visible tab and upload it

Put the capture and upload in extension-owned code, such as the service worker, then invoke it in response to an explicit extension UI action. This example expects a multipart field named screenshot, bearer-token authentication, and a JSON response. Change those parts to match the receiving service.

async function captureAndUpload(apiUrl, token) {
  const dataUrl = await chrome.tabs.captureVisibleTab({
    format: "png"
  });

  const imageBlob = await (await fetch(dataUrl)).blob();
  const form = new FormData();
  form.append("screenshot", imageBlob, "screenshot.png");

  const response = await fetch(apiUrl, {
    method: "POST",
    headers: {
      Authorization: `Bearer ${token}`
    },
    body: form
  });

  if (!response.ok) {
    throw new Error(`Screenshot upload failed: HTTP ${response.status}`);
  }
  return response.json();
}

When sending FormData, do not set the Content-Type header yourself. The browser must add the multipart boundary. If the API requires raw binary or JSON/base64 instead, follow its specification rather than sending this multipart body.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Check the response format before calling response.json(). If the endpoint returns an empty body, text, or binary data, parse it accordingly. An HTTP success status does not guarantee that the response is JSON.

Choose the right execution context and protect the request

Cross-origin extension requests need permission for the destination host. Make the request from the service worker or an extension page; a content script remains subject to the page’s same-origin restrictions. Chrome’s guidance is in Cross-origin network requests.

  • Use a fixed, trusted API URL in extension code. Do not let a webpage supply an arbitrary URL for the extension to fetch.
  • If a content script sends a message to the service worker, validate the sender and expose only a constrained capture-and-upload operation.
  • Use HTTPS. Avoid logging screenshot bytes, authorization tokens, or sensitive response contents.
  • Tell users when a screenshot is captured and uploaded; the visible tab may contain personal or confidential information.
  • Keep the operation tied to a user action and transmit only the image and metadata needed for its stated purpose.

Manifest V3 service workers are event-driven and may become dormant; they also have no DOM access. Handle capture and upload as part of the extension event, and return success or failure to the UI rather than depending on an open page or in-memory state to persist. See About extension service workers.

When visible-tab capture is not enough

The method captures only what is visible in the active tab at the time of the call. Content below the fold is not included. A full-page result needs a different design, such as scrolling and stitching captures, or another capture mechanism; validate that approach for the browser and pages involved. The Chrome capture call’s documented rate limit is two calls per second, so avoid rapid capture loops.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Troubleshoot common failures

  • Capture permission error: Confirm the extension has activeTab or <all_urls>, and that the call targets the active tab in the intended window.
  • Cross-origin fetch fails: Check that host_permissions covers the API host and that the request runs in extension-owned code, not a content script.
  • API rejects the upload: Verify the endpoint, method, multipart field name, authorization format, allowed image format, payload limit, and response requirements against that API’s documentation.
  • Multipart parsing fails: If using FormData, remove any manually set Content-Type header so the browser can supply the boundary.
  • JSON parsing throws after a successful response: Confirm the service actually returns JSON; parse the response as text or another format if its contract specifies that.
  • Calls are throttled: Keep captureVisibleTab() at or below Chrome’s documented two calls per second.
  • The image cuts off the page: This is expected for visible-tab capture; it does not include content below the viewport.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Or skip the browser setup

If your goal is to capture a website from code rather than capture the user’s current browser tab, ScreenshotNeo provides a screenshot API and MCP server. Its one-call API example is:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

See the ScreenshotNeo documentation for request details. It removes cookie banners, newsletter popups, and chat widgets before capture; bot checks, blank pages, and failed loads are never billed. Its MCP server lets AI agents take screenshots. The Free plan includes 1,000 screenshots per month with no card, and paid plans start at $5 for 3,000. Sign up for ScreenshotNeo’s free plan.

Frequently Asked Questions

Does captureVisibleTab() take a full-page screenshot?

No. It captures the active tab’s visible area; content below the viewport is excluded.

Can a content script upload the screenshot directly to another domain?

Extension host permissions do not remove a content script’s page-origin restrictions. Make the cross-origin request from the service worker or an extension page.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
Crashes, No Sound, or Screen Glitches?Free driver scan
PC Slower Than It Used to Be?Free scan - under a minute

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.