How to Capture Full Page Screenshots via API

Published: February 19, 2026 | By SnapAPI Team | 10 min read

Browser mockup showing a website screenshot being captured

Photo via Unsplash

A full page screenshot captures the entire length of a webpage — not just what's visible in the browser viewport. This includes content below the fold, lazy-loaded images, and everything down to the footer. It's essential for web archiving, visual testing, legal compliance, and documentation.

In this tutorial, you'll learn how to capture full page screenshots using the SnapAPI REST API with code examples in cURL, JavaScript, Python, PHP, and Go.

Prerequisites

  1. A free SnapAPI account — sign up here (no credit card required)
  2. Your API key from the dashboard
  3. Any HTTP client (browser, cURL, or your preferred programming language)

Quick Start: Your First Full Page Screenshot

cURL

curl -G "https://api.snapapi.pics/v1/screenshot" \
  --data-urlencode "url=https://github.com/microsoft/playwright" \
  --data-urlencode "full_page=true" \
  --data-urlencode "format=png" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -o full-page.png

That's it. One HTTP request, and you get back a PNG image of the entire page. The API renders the page in a real Chromium browser, scrolls to the bottom to trigger lazy-loaded content, and stitches everything into a single image.

JavaScript (Node.js)

const fs = require('fs');

async function captureFullPage(url) {
    const params = new URLSearchParams({
        url: url,
        full_page: 'true',
        format: 'png',
        viewport_width: '1280',
        block_cookie_banners: 'true'
    });

    const response = await fetch(
        `https://api.snapapi.pics/v1/screenshot?${params}`,
        {
            headers: { 'Authorization': 'Bearer YOUR_API_KEY' }
        }
    );

    if (!response.ok) {
        const error = await response.text();
        throw new Error(`Screenshot failed: ${response.status} - ${error}`);
    }

    const buffer = Buffer.from(await response.arrayBuffer());
    fs.writeFileSync('full-page.png', buffer);
    console.log(`Saved full-page screenshot (${buffer.length} bytes)`);
    return buffer;
}

// Usage
captureFullPage('https://github.com/microsoft/playwright');

JavaScript (Browser / Frontend)

async function captureAndDisplay(url) {
    const params = new URLSearchParams({
        url: url,
        full_page: 'true',
        format: 'png',
        viewport_width: '1280'
    });

    const response = await fetch(
        `https://api.snapapi.pics/v1/screenshot?${params}`,
        { headers: { 'Authorization': 'Bearer YOUR_API_KEY' } }
    );

    const blob = await response.blob();
    const imageUrl = URL.createObjectURL(blob);

    // Display in an img element
    document.getElementById('screenshot').src = imageUrl;
}

⚠️ Security note: Never expose your API key in client-side code. Use a backend proxy to keep your key safe.

Python

import requests

def capture_full_page(url: str, output_path: str = 'full-page.png'):
    response = requests.get(
        'https://api.snapapi.pics/v1/screenshot',
        params={
            'url': url,
            'full_page': True,
            'format': 'png',
            'viewport_width': 1280,
            'block_cookie_banners': True
        },
        headers={'Authorization': 'Bearer YOUR_API_KEY'}
    )
    response.raise_for_status()

    with open(output_path, 'wb') as f:
        f.write(response.content)

    print(f'Saved {output_path} ({len(response.content)} bytes)')
    return response.content

# Usage
capture_full_page('https://github.com/microsoft/playwright')

Python (async with httpx)

import httpx
import asyncio

async def capture_full_page_async(url: str, output_path: str = 'full-page.png'):
    async with httpx.AsyncClient(timeout=60) as client:
        response = await client.get(
            'https://api.snapapi.pics/v1/screenshot',
            params={
                'url': url,
                'full_page': True,
                'format': 'png',
                'viewport_width': 1280,
                'block_cookie_banners': True
            },
            headers={'Authorization': 'Bearer YOUR_API_KEY'}
        )
        response.raise_for_status()

        with open(output_path, 'wb') as f:
            f.write(response.content)

    return response.content

# Usage
asyncio.run(capture_full_page_async('https://example.com'))

PHP

<?php
function captureFullPage(string $url, string $outputPath = 'full-page.png'): void
{
    $params = http_build_query([
        'url' => $url,
        'full_page' => 'true',
        'format' => 'png',
        'viewport_width' => 1280,
        'block_cookie_banners' => 'true',
    ]);

    $context = stream_context_create([
        'http' => [
            'header' => "Authorization: Bearer YOUR_API_KEY\r\n",
            'timeout' => 60,
        ],
    ]);

    $image = file_get_contents(
        "https://api.snapapi.pics/v1/screenshot?{$params}",
        false,
        $context
    );

    if ($image === false) {
        throw new RuntimeException('Screenshot capture failed');
    }

    file_put_contents($outputPath, $image);
    echo "Saved {$outputPath} (" . strlen($image) . " bytes)\n";
}

// Usage
captureFullPage('https://github.com/microsoft/playwright');
?>

Go

package main

import (
    "fmt"
    "io"
    "net/http"
    "net/url"
    "os"
)

func captureFullPage(targetURL, outputPath string) error {
    params := url.Values{}
    params.Set("url", targetURL)
    params.Set("full_page", "true")
    params.Set("format", "png")
    params.Set("viewport_width", "1280")
    params.Set("block_cookie_banners", "true")

    req, err := http.NewRequest("GET",
        "https://api.snapapi.pics/v1/screenshot?"+params.Encode(), nil)
    if err != nil {
        return err
    }
    req.Header.Set("Authorization", "Bearer YOUR_API_KEY")

    client := &http.Client{Timeout: 60 * time.Second}
    resp, err := client.Do(req)
    if err != nil {
        return err
    }
    defer resp.Body.Close()

    if resp.StatusCode != http.StatusOK {
        body, _ := io.ReadAll(resp.Body)
        return fmt.Errorf("API error %d: %s", resp.StatusCode, body)
    }

    file, err := os.Create(outputPath)
    if err != nil {
        return err
    }
    defer file.Close()

    written, err := io.Copy(file, resp.Body)
    fmt.Printf("Saved %s (%d bytes)\n", outputPath, written)
    return err
}

func main() {
    captureFullPage("https://github.com/microsoft/playwright", "full-page.png")
}

Get Your Free API Key

200 free screenshots/month. All formats, full page, device emulation included.

Sign Up Free →

API Parameters for Full Page Screenshots

Here are the key parameters you can use to customize your full page captures:

Parameter Type Description
url string The URL to capture (required)
full_page boolean Capture the full scrollable page (default: false)
format string Output format: png, jpeg, webp, avif
viewport_width integer Browser viewport width in pixels (default: 1280)
viewport_height integer Browser viewport height in pixels (default: 720)
device string Device preset (e.g., iPhone15Pro, Pixel8)
block_cookie_banners boolean Hide cookie consent popups (50K+ rules)
dark_mode boolean Render in dark mode
wait_for string CSS selector to wait for before capturing
delay integer Extra delay in ms after page load
selector string Capture only a specific element

Choosing the Right Output Format

Full page screenshots can be large — a long page at 1280px wide might produce a 10,000+ pixel tall image. Format choice matters:

# Compare file sizes for the same page
curl "https://api.snapapi.pics/v1/screenshot?url=https://example.com&full_page=true&format=png" \
  -H "Authorization: Bearer YOUR_API_KEY" -o page.png

curl "https://api.snapapi.pics/v1/screenshot?url=https://example.com&full_page=true&format=avif" \
  -H "Authorization: Bearer YOUR_API_KEY" -o page.avif

# page.png: ~2.4 MB
# page.avif: ~1.1 MB  (54% smaller!)

Handling Common Challenges

Lazy-Loaded Images

Modern websites lazy-load images that are below the fold. SnapAPI automatically scrolls the page to trigger all lazy-loaded content before capturing. No extra configuration needed.

Infinite Scroll Pages

For pages with infinite scroll (like social media feeds), use viewport_height to set a maximum capture height, or use the delay parameter to let more content load:

# Capture with a larger viewport to get more content
curl "https://api.snapapi.pics/v1/screenshot?url=https://news.ycombinator.com&full_page=true&delay=3000" \
  -H "Authorization: Bearer YOUR_API_KEY" -o hackernews.png

Fixed/Sticky Headers

Sticky headers can appear multiple times in full-page screenshots. SnapAPI handles this intelligently by keeping the header only at the top of the capture.

Cookie Consent Popups

Cookie banners ruin full-page screenshots. Always use block_cookie_banners=true:

curl "https://api.snapapi.pics/v1/screenshot?url=https://bbc.com&full_page=true&block_cookie_banners=true" \
  -H "Authorization: Bearer YOUR_API_KEY" -o bbc-clean.png

Authenticated Pages

Pass cookies or headers to capture pages behind login:

curl -G "https://api.snapapi.pics/v1/screenshot" \
  --data-urlencode "url=https://app.yoursite.com/dashboard" \
  --data-urlencode "full_page=true" \
  --data-urlencode "cookies=session_id=abc123; auth_token=xyz789" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -o dashboard.png

Batch Capture: Multiple Pages at Once

Need to capture many pages? Parallelize your requests:

// Node.js - Capture 10 pages in parallel
const urls = [
    'https://example.com',
    'https://example.com/about',
    'https://example.com/pricing',
    'https://example.com/docs',
    'https://example.com/blog',
    // ... more URLs
];

const API_KEY = process.env.SNAPAPI_KEY;

async function captureOne(url) {
    const params = new URLSearchParams({
        url,
        full_page: 'true',
        format: 'avif',  // Smallest file size
        viewport_width: '1280',
        block_cookie_banners: 'true'
    });

    const response = await fetch(
        `https://api.snapapi.pics/v1/screenshot?${params}`,
        { headers: { 'Authorization': `Bearer ${API_KEY}` } }
    );

    if (!response.ok) throw new Error(`Failed: ${url}`);
    return {
        url,
        buffer: Buffer.from(await response.arrayBuffer())
    };
}

// Capture all in parallel (respect rate limits)
const results = await Promise.allSettled(
    urls.map(url => captureOne(url))
);

results.forEach(result => {
    if (result.status === 'fulfilled') {
        const { url, buffer } = result.value;
        const filename = new URL(url).pathname.replace(/\//g, '_') + '.avif';
        fs.writeFileSync(filename, buffer);
        console.log(`✓ ${url} → ${filename}`);
    } else {
        console.error(`✗ ${result.reason.message}`);
    }
});

Full Page Screenshot as PDF

Sometimes a PDF is better than an image — especially for documents, invoices, and legal archiving. SnapAPI's PDF endpoint captures the full page as a paginated document:

curl "https://api.snapapi.pics/v1/pdf?url=https://example.com" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -o page.pdf

Use Cases for Full Page Screenshots

Tips for Best Results

  1. Set an appropriate viewport width — 1280px is standard for desktop. Use device presets for mobile.
  2. Use AVIF format to minimize file size without sacrificing quality.
  3. Always block cookie banners for clean captures.
  4. Add a delay for pages with heavy JavaScript or animations.
  5. Use wait_for to ensure critical content is loaded before capture.
  6. Handle errors gracefully — check HTTP status codes and implement retries.

Conclusion

Capturing full page screenshots via API is the easiest way to get complete webpage captures without managing browser infrastructure. With SnapAPI, you get reliable full-page rendering, automatic lazy-load handling, cookie banner blocking, and support for modern formats like AVIF — all through a simple HTTP request.

Whether you're building screenshot automation, visual monitoring, or archiving systems, the API approach gives you production-ready captures from day one.

Try Full Page Screenshots Free

200 free captures/month. Full page, viewport, element — all included.

Get Free API Key →

Last updated: February 19, 2026