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

There are two different ways to put screenshots behind a NestJS endpoint: run a NestJS/Puppeteer service yourself, or call a hosted screenshot API from an injectable NestJS service. The routes, authentication, deployment work and option names are different, so this guide keeps them separate.

The self-hosted example implements GET /v1/capture. The hosted example calls POST https://api.screenshot-api.org/api/v1/screenshot with an API key. Choose the first when you need to operate the browser runtime yourself; choose the second when you want a provider-managed rendering service.

Choose the route before writing code

Question Self-hosted NestJS/Puppeteer project Hosted Screenshot API
Who operates the browser? You deploy and update the NestJS application and its Puppeteer/Chrome runtime. The provider operates the rendering service; your application sends authenticated requests.
Endpoint GET /v1/capture GET /api/v1/screenshot or POST /api/v1/screenshot
Credentials The repository documents local environment configuration; no vendor API key is part of the documented capture route. API-key authentication is documented with an Authorization: Bearer header or X-API-Key.
Documented controls URL, width, height, scale, timeout, delay, MIME type and quality. Formats, full-page mode, viewport, device scale, wait strategy, selectors, delay, blocking, dark mode and POST-only browser/page options.
Published limit No quota is stated in the self-hosted README. The free plan is documented as 60 requests per minute and 500 screenshots per month; verify current limits before launch.
Operational trade-off You own deployment, browser installation, scaling and updates. You depend on the provider account, API availability and quotas.

There is no evidence here to claim that either route is faster, cheaper, more reliable or more visually faithful. Those outcomes depend on pages, regions, browser versions, network conditions and your deployment.

Self-hosted quick start with NestJS and Puppeteer

1. Create a Nest project

Nest’s current first-steps guide recommends Node.js 20.19 or later, or 22.12 and later on the 22.x line. Install the CLI and generate an application:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
#1 Best Overall
Elebase USB to USB C Adapter for iPhone 18 Pro Max,USBC Car Charger Adapter
  • Read Before You Buy — No Video Output: These adapters support charging and USB 2.0 data transfer, but cannot transmit video signals. Except for standard USB webcams (which use USB data only), they are not compatible with HDMI/DisplayPort cables, video-capable USB-C hubs, or docking stations with video output.
  • Convert USB-A Ports to USB-C: Designed to connect USB-C earphones, cables, flash drives, card readers, and other USB-C accessories to standard USB-A ports. Plug-and-play with no drivers or software required.
  • Aluminum Alloy Housing: Built with a sturdy aluminum alloy shell that aids in heat dissipation and protects against daily wear and scratches. Designed to maintain a stable and secure connection.
  • Compact & Travel-Friendly: The ultra-compact design allows the adapter to stay plugged into your device without blocking adjacent ports or adding bulk, reducing wear and tear on your original USB ports.
  • 12-Month Warranty: Backed by a 12-month manufacturer warranty for peace of mind. Designed to meet strict quality control standards for reliable everyday performance.
npm i -g @nestjs/cli
nest new screenshot-service
cd screenshot-service

The generated bootstrap follows the standard pattern:

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(process.env.PORT ?? 3000);
}
bootstrap();

Express is Nest’s default platform adapter; Fastify is the other built-in adapter. The adapter choice does not change the capture URL shown below, but it can affect middleware and deployment configuration.

2. Install and configure the documented project

The public self-hosted project describes itself as “A simple self-hosted API to take screenshots of websites using Puppeteer.” Its documented setup is independent of the generic Nest CLI starter:

pnpm install
cp .env.example .env
# edit .env
pnpm run start

For development and production scripts, the README also documents:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
pnpm run start:dev
pnpm run start:prod

The repository documents Chrome installation for capture tests:

npx puppeteer browsers install chrome

That is a statement about the project’s documented test setup, not a universal requirement for every Puppeteer deployment. Confirm the repository’s current environment variables and parameter reference before treating it as a production contract.

Rank #2
Anker USB-C Hub, 5-in-1 USB Hub for Laptops, 4K HDMI Multiport Adapter
  • 5-in-1 USB-C Hub: Experience comprehensive connectivity featuring a Power Delivery input, two USB-A 2.0 ports, a USB-A 3.0 port, and an HDMI port. (Note: The USB-C power delivery input port is only for connecting an external wall charger to power your laptop and cannot power peripheral devices.)
  • 90W Pass-Through Charging: Achieve optimal charging with 90W pass-through power to your laptop, supported by a total input of 100W, with the hub reserving 10W for operational efficiency. (Note: Wall charger not included.)
  • Quick Data Transfers: Accelerate your productivity with rapid data transfers using a high-speed 5Gbps USB 3.0 port and two 480Mbps USB 2.0 ports.
  • 4K HDMI Display: Enhance your visual experience with a hub capable of delivering 4K resolution at 30Hz in both mirror and extend modes. Please note that this hub is compatible with MacBook (macOS 12 and newer), Windows 10 and 11, ChromeOS, and laptops equipped with DP Alt Mode and Power Delivery. Note: This device is not compatible with Linux.
  • What You Get: Anker USB-C Hub (5-in-1, 4K HDMI), welcome guide, 18-month warranty, and our friendly customer service.

3. Run it in a container

The README shows this basic container workflow:

docker build -t screenshot-api .
docker run -p 3000:3000 screenshot-api

Make sure the process listens on the container port you publish and that the image contains the browser dependencies required by your chosen Puppeteer version.

Call the self-hosted /v1/capture endpoint

The documented route is GET /v1/capture. The table below lists the README’s names and defaults. The url is required; the README does not state a default for it.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Query parameter Meaning Documented default
url Page to capture Required; no default shown
width Viewport width 1024
height Viewport height 768
scale Rendering scale 1
timeout Time before giving up 15
delay Delay after page load 0
mime_type Image output type webp; README lists jpg and png as alternatives
quality Image quality 0.8

A request using explicit values looks like this:

curl -G "http://localhost:3000/v1/capture" 
  --data-urlencode "url=https://example.com" 
  --data-urlencode "width=1280" 
  --data-urlencode "height=720" 
  --data-urlencode "scale=2" 
  --data-urlencode "timeout=30" 
  --data-urlencode "delay=2" 
  --data-urlencode "mime_type=png" 
  --data-urlencode "quality=0.9" 
  -o example.png

Use --data-urlencode so query characters in the target URL are not interpreted by your shell. If your service is deployed behind HTTPS, replace the local origin with your public origin and keep the capture endpoint private if it can reach internal network addresses.

Build a small NestJS wrapper around a hosted API

Keep the API key on the server

The hosted service documents both GET and POST forms. POST is the practical choice for complex options because the request body is JSON. Do not put the key in browser JavaScript or expose it through a public controller response. Load it from server-side configuration such as an environment variable.

Minimal injectable service with Node fetch

The provider’s documented JavaScript request can be wrapped in a Nest injectable service:

import { Injectable, InternalServerErrorException } from '@nestjs/common';

@Injectable()
export class ScreenshotService {
  private readonly apiKey = process.env.SCREENSHOT_API_KEY;

  async create(options: {
    url: string;
    viewport?: { width: number; height: number };
    format?: 'png' | 'jpeg' | 'webp' | 'pdf';
    fullPage?: boolean;
  }) {
    if (!this.apiKey) {
      throw new Error('SCREENSHOT_API_KEY is not configured');
    }

    const response = await fetch('https://api.screenshot-api.org/api/v1/screenshot', {
      method: 'POST',
      headers: {
        Authorization: `Bearer ${this.apiKey}`,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(options),
    });

    const data = await response.json();
    if (!response.ok) {
      throw new InternalServerErrorException(data);
    }
    return data;
  }
}

The response example exposes a screenshotUrl field. Return that URL from your own controller or download the bytes server-side, depending on your application.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #3
Sale
Anker USB C Hub, 7in1 Multi-Port USB Adapter, 4K@60Hz USBC to HDMI Splitter
  • Sleek 7-in-1 USB-C Hub: Features an HDMI port, two USB-A 3.0 ports, and a USB-C data port, each providing 5Gbps transfer speeds. It also includes a USB-C PD input port for charging up to 100W and dual SD and TF card slots, all in a compact design.
  • Flawless 4K@60Hz Video with HDMI: Delivers exceptional clarity and smoothness with its 4K@60Hz HDMI port, making it ideal for high-definition presentations and entertainment. (Note: Only the HDMI port supports video projection; the USB-C port is for data transfer only.)
  • Double Up on Efficiency: The two USB-A 3.0 ports and a USB-C port support a fast 5Gbps data rate, significantly boosting your transfer speeds and improving productivity.
  • Fast and Reliable 85W Charging: Offers high-capacity, speedy charging for laptops up to 85W, so you spend less time tethered to an outlet and more time being productive.
  • What You Get: Anker USB-C Hub (7-in-1), welcome guide, 18-month warranty, and our friendly customer service.

Expose it through a controller

import { Body, Controller, Post } from '@nestjs/common';
import { ScreenshotService } from './screenshot.service';

@Controller('screenshots')
export class ScreenshotController {
  constructor(private readonly screenshots: ScreenshotService) {}

  @Post()
  create(@Body() body: {
    url: string;
    viewport?: { width: number; height: number };
    format?: 'png' | 'jpeg' | 'webp' | 'pdf';
    fullPage?: boolean;
  }) {
    return this.screenshots.create(body);
  }
}

Validate the incoming URL and option ranges before forwarding them. If untrusted users can choose arbitrary URLs, add SSRF protections, block private address ranges and restrict protocols to the destinations your product actually needs.

Using Nest’s HTTP client instead

Nest’s current HTTP-client documentation describes @nestjs/http-client as a module-injected wrapper over Node’s fetch with timeouts, retries, interceptors and typed responses. It replaces the older Axios-focused chapter, while @nestjs/axios remains available. Neither package is mandatory for the hosted API; native fetch is sufficient for the example above.

Hosted API options you can map to NestJS

  • Output: PNG, JPEG, WebP or PDF.
  • Page size: viewport width and height, plus device scale factor.
  • Page extent: full-page capture.
  • Waiting: navigation wait strategy, a delay, selector waiting and selector capture.
  • Presentation: dark mode and ad or cookie-banner blocking.
  • POST-only controls: injected CSS or JavaScript, geolocation, timezone, locale and PDF settings.

Selector capture is not supported for PDF according to the provider’s documentation. For GET requests, a redirect option can return a redirect to the screenshot URL; JSON is the default response form.

Batch screenshots

For multiple pages, the hosted service documents POST /api/v1/screenshot/batch. The response supplies a batch ID. Poll progress with GET /api/v1/batch/:batchId or consume server-sent events from /api/v1/batch/:batchId/stream. Design your NestJS job layer to persist the batch ID, retry transient polling failures and stop polling after an application-defined deadline.

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

Errors, limits and defensive handling

The hosted documentation lists these machine-readable failures:

Error Status Typical action
unauthorized 401 Check the key, header spelling and account status.
invalid_request 400 Validate required fields and option types before sending.
rate_limited 429 Honor rate-limit headers and retry with backoff.
quota_exceeded 429 Wait for the quota period or change the account plan.
render_failed 502 Record the target URL and retry only when the failure may be transient.
selector_not_found 422 Check the selector and increase waiting time if the page renders it asynchronously.

The documented free-plan limits are 60 requests per minute and 500 screenshots per month. They are provider-published limits, accessed September 29, 2026, and may change; read the current service documentation before sizing workers or promising capacity.

Rank #4
Sale
UGREEN USB to USB C Adapter Combo 4-Pack, 10Gbps USB C Converter Space Gray
  • Dual Converters, Infinite Potential:Includes 2× USB C male to USB A female adapters and 2× USB A male to USB C female adapters. Perfect for a wide range of uses—tablets with Bluetooth keyboards, expand USB ports on macbook, and more. Two different converters for all your daily needs
  • Next-Level 10Gbps & 3A Charging: No more slow 480Mbps, this usb to usb c adapter has a transfer speed of up to 10Gbps, allowing you to do more transferring in less time. This usb adapter fits both USB A and USB C charger, supporting up to 3A fast charging
  • Upgraded Exquisite Craftsmanship: With an aluminum alloy housing and metal connector, the usbc to usb adapter is extremely durable and sturdy. Rigorously tested to withstand more than 10,000 times of plugging and unplugging, ensuring long-lasting performance
  • Broad Compatible: The usb c to usb adapter widely supports all USB C/ USB A devices like laptops, tablets, cellphones, car chargers, and phone chargers. Such as compatible with MacBook Pro/Air 2023/2022, Thunderbolt 4/3 Devices,Apple MagSafe Watch 9/8/7/SE/Ultra, iPad Pro 2022/2021, Samsung Galaxy S23/S20/S10, and iPhone 17/16/15 Pro. Plug and play
  • Please Note: To reach 10Gbps speed, keep the cable under 3.3 ft. For USB A Male to USB C adapters, try flipping the USB C connector. USB C Male to USB A adapters support bidirectional 10Gbps transfer within 3.3 ft
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Reliability and security checklist

  • Set a client timeout longer than the provider or browser navigation timeout, but finite enough to prevent stuck Nest requests.
  • Use exponential backoff for 429 responses and avoid retrying malformed requests or missing selectors.
  • Log status, provider error code, target hostname and elapsed time without logging API keys or sensitive page contents.
  • Constrain user-supplied URLs to allowed schemes and destinations to reduce server-side request forgery risk.
  • For self-hosting, monitor browser process count and memory, and recycle workers that leak resources.
  • Use a queue for bursts instead of creating an unbounded number of simultaneous browser pages.
  • Check cache headers and screenshot URLs before storing or publicly sharing captures that may contain private data.

Troubleshooting

The self-hosted route returns a timeout

Confirm the target is reachable from the server, then raise the documented timeout or add a delay for client-rendered content. A delay does not fix a page that never finishes loading; inspect the browser logs and target URL separately.

Capture tests cannot find Chrome

Run the documented npx puppeteer browsers install chrome command in the environment used by the tests. In a container, ensure the image build installs the browser and its system dependencies.

Free tools Windows power users keep installed

One-click scans. No signup required.

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

The hosted call returns 401

Verify that SCREENSHOT_API_KEY is present in the Nest process, that the value has no surrounding quotes or whitespace, and that the request sends either the documented bearer header or X-API-Key.

A selector request returns 422

Check spelling, wait for the selector rather than only waiting for navigation, and confirm the element exists in the rendered DOM rather than inside an inaccessible cross-origin frame.

Requests suddenly receive 429

Differentiate rate_limited from quota_exceeded. Apply backoff for the former, and inspect account usage or plan limits for the latter. Do not run unlimited retries.

The image is blank or incomplete

Increase the wait strategy or delay, use full-page mode when appropriate, and verify that the page does not require authentication, a geolocation or a blocked third-party resource. For self-hosting, inspect the browser’s network and console output.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Best Value
Anker USB C Hub, 5-in-1 USBC to HDMI Splitter with 4K Display
  • 5-in-1 Connectivity: Equipped with a 4K HDMI port, a 5 Gbps USB-C data port, two 5 Gbps USB-A ports, and a USB C 100W PD-IN port. Note: The USB C 100W PD-IN port supports only charging and does not support data transfer devices such as headphones or speakers.
  • Powerful Pass-Through Charging: Supports up to 85W pass-through charging so you can power up your laptop while you use the hub. Note: Pass-through charging requires a charger (not included). Note: To achieve full power for iPad, we recommend using a 45W wall charger.
  • Transfer Files in Seconds: Move files to and from your laptop at speeds of up to 5 Gbps via the USB-C and USB-A data ports. Note: The USB C 5Gbps Data port does not support video output.
  • HD Display: Connect to the HDMI port to stream or mirror content to an external monitor in resolutions of up to 4K@30Hz. Note: The USB-C ports do not support video output.
  • What You Get: Anker 332 USB-C Hub (5-in-1), welcome guide, our worry-free 18-month warranty, and friendly customer service.

Or skip the browser setup

ScreenshotNeo is a hosted website screenshot API and MCP server. It removes cookie-consent banners, newsletter popups and chat widgets before capture; bot checks, blank pages, timeouts, failed loads and cache hits are not billed, and each response identifies the page verdict and billing status. AI agents can use its MCP tools—take_screenshot, get_page_info and capture_pdf—from Claude, Cursor or another MCP client.

A single GET request returns an image or PDF:

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 all options, including full-page and element capture, custom CSS and JavaScript, blocking, cookies, headers, device presets, PDFs, signed links, asynchronous jobs and bulk capture. The same service also offers a Python and Node.js call:

import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

The free plan includes 1,000 screenshots per month with no card. Paid plans start at $5 for 3,000 screenshots, and every feature is included on every plan. Create a free ScreenshotNeo account to get an access key.

Frequently Asked Questions

Can I use both self-hosted Puppeteer and a hosted API in one NestJS application?

Yes. Keep them behind separate injectable services and configuration flags, and preserve their distinct endpoint and option schemas instead of mixing parameter names.

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

Should screenshot work run inside the HTTP request?

For occasional captures it can. For large batches or slow pages, queue jobs and return a job identifier so browser work does not exhaust NestJS request workers.

Is a PDF selector capture supported by the hosted API?

No. The hosted documentation specifically says selector capture is not supported for PDF output.

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.