ScreenshotAPI

Go

Official screenshotapi-go SDK — capture screenshots, PDFs, and rendered HTML from Go with a typed, context-aware, standard-library client.

The official screenshotapi-go SDK is a typed, context-aware client built on the standard library — no third-party dependencies. It uses typed constants for enums and errors.As for error handling.

Module: github.com/miketromba/screenshotapi-go · Reference: pkg.go.dev · Requires Go 1.21+.

Installation

go get github.com/miketromba/screenshotapi-go
import screenshotapi "github.com/miketromba/screenshotapi-go"

Authentication

Create an API key in the dashboard and keep it in an environment variable. The SDK sends it in the x-api-key header.

export SCREENSHOTAPI_KEY="sk_live_your_key_here"
client := screenshotapi.NewClient(os.Getenv("SCREENSHOTAPI_KEY"))

Quick Start

Capture a URL and save it to disk

Save captures the screenshot, writes the file, and returns the response metadata. Every call takes a context.Context so you can apply deadlines and cancellation.

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	screenshotapi "github.com/miketromba/screenshotapi-go"
)

func main() {
	apiKey := os.Getenv("SCREENSHOTAPI_KEY")
	if apiKey == "" {
		log.Fatal("SCREENSHOTAPI_KEY is required")
	}

	client := screenshotapi.NewClient(apiKey)

	metadata, err := client.Save(context.Background(), screenshotapi.ScreenshotOptions{
		URL: "https://example.com",
	}, "screenshot.png")
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("Saved screenshot.png — credits remaining: %d\n", metadata.CreditsRemaining)
}

Or work with the raw image bytes

Screenshot returns a *Result with the image bytes in memory.

result, err := client.Screenshot(ctx, screenshotapi.ScreenshotOptions{
	URL:     "https://example.com",
	Type:    screenshotapi.WebP,
	Quality: 85,
})
if err != nil {
	return err
}

fmt.Println(result.ContentType)             // "image/webp"
fmt.Println(len(result.Image))               // image size in bytes
fmt.Println(result.Metadata.ScreenshotID)

Methods

screenshotapi.NewClient(apiKey, ...Option)

Configure the client with functional options:

client := screenshotapi.NewClient(apiKey,
	screenshotapi.WithTimeout(30*time.Second),
	screenshotapi.WithBaseURL("https://screenshotapi.to"),
	screenshotapi.WithHTTPClient(&http.Client{Timeout: 30 * time.Second}),
)
OptionDescription
WithTimeout(time.Duration)HTTP client timeout (default 60s)
WithBaseURL(string)API base URL — for proxies, gateways, tests (default https://screenshotapi.to)
WithHTTPClient(*http.Client)Supply your own *http.Client

client.Screenshot(ctx, opts) (*Result, error)

type Result struct {
	Image       []byte    // raw image or PDF bytes
	ContentType string    // "image/png", "image/webp", "application/pdf", …
	Metadata    Metadata
}

type Metadata struct {
	CreditsRemaining int
	ScreenshotID     string // include this when contacting support
	DurationMs       int
}

client.Save(ctx, opts, path) (*Metadata, error)

Captures, writes the bytes to path, and returns the *Metadata shown above.

Options

ScreenshotOptions uses typed constants for enum fields, so the compiler catches invalid values.

FieldTypeDescription
URLstringURL to capture (required unless HTML is set)
HTMLstringHTML document to render (switches to POST)
WidthintViewport width in pixels (max 1920)
HeightintViewport height in pixels (max 10000)
FullPageboolCapture the full scrollable page
TypeImageTypePNG, JPEG, WebP, or PDF
QualityintJPEG/WebP quality, 1–100
ColorSchemeColorSchemeLight or Dark
WaitUntilWaitUntilLoad, DOMContentLoaded, NetworkIdle0, NetworkIdle2
WaitForSelectorstringCSS selector to wait for
DelayintExtra wait after load (ms, max 30000)
BlockAdsboolBlock common ad networks
RemoveCookieBannersboolAuto-remove cookie consent dialogs
CSSInjectstringCSS injected before capture
JSInjectstringJavaScript evaluated before capture
StealthModeboolAnti-bot-detection browser fingerprint
DevicePixelRatiointRetina/HiDPI scale (1, 2, or 3)
TimezonestringIANA timezone, e.g. America/New_York
LocalestringBCP 47 locale, e.g. en-US
CacheTTLintCache identical captures for N seconds
PreloadFontsboolPreload Google Fonts before capture
RemoveElements[]stringCSS selectors to remove
RemovePopupsboolRemove common modals/overlays
MockupDeviceMockupDeviceBrowserMockup, IPhoneMockup, MacBookMockup (PNG output)
Geolocation*Geolocation&screenshotapi.Geolocation{Latitude, Longitude, Accuracy}
result, err := client.Screenshot(ctx, screenshotapi.ScreenshotOptions{
	URL:                 "https://example.com",
	Width:               1440,
	Height:              900,
	FullPage:            true,
	Type:                screenshotapi.WebP,
	Quality:             85,
	ColorScheme:         screenshotapi.Dark,
	WaitUntil:           screenshotapi.NetworkIdle2,
	WaitForSelector:     "#app-ready",
	Delay:               250,
	BlockAds:            true,
	RemoveCookieBanners: true,
	DevicePixelRatio:    2,
	CacheTTL:            300,
	RemoveElements:      []string{".popup", "#promo-banner"},
	Geolocation: &screenshotapi.Geolocation{
		Latitude:  37.7749,
		Longitude: -122.4194,
		Accuracy:  25,
	},
})

Device mockups (MockupDevice) always output PNG. Don't combine a mockup with FullPage or Type: screenshotapi.PDF.

Render HTML & generate PDFs

Set HTML to render a raw string — the SDK automatically issues a POST request. Combine with Type: screenshotapi.PDF for documents.

result, err := client.Screenshot(ctx, screenshotapi.ScreenshotOptions{
	HTML: "<main><h1>Hello from Go</h1></main>",
	Type: screenshotapi.PDF,
})

Error Handling

The SDK returns typed errors. Use errors.As to match them.

import "errors"

result, err := client.Screenshot(ctx, screenshotapi.ScreenshotOptions{
	URL: "https://example.com",
})
if err != nil {
	var authErr *screenshotapi.AuthenticationError
	var creditsErr *screenshotapi.InsufficientCreditsError
	var keyErr *screenshotapi.InvalidAPIKeyError
	var failedErr *screenshotapi.ScreenshotFailedError

	switch {
	case errors.As(err, &authErr):
		// 401: API key missing or malformed.
	case errors.As(err, &creditsErr):
		fmt.Printf("Out of credits, balance: %d\n", creditsErr.Balance)
	case errors.As(err, &keyErr):
		// 403: API key revoked or invalid.
	case errors.As(err, &failedErr):
		// 500: capture failed server-side.
	default:
		// Network errors, validation errors, or other API responses.
	}
	return err
}
_ = result
ErrorWhen
*AuthenticationError401 — API key missing or malformed
*InsufficientCreditsError402 — no credits remaining (exposes .Balance)
*InvalidAPIKeyError403 — API key revoked or invalid
*ScreenshotFailedError500 — capture failed server-side
*APIErrorBase type for other API responses (exposes .StatusCode, .Code, .Message)

Framework Recipe

net/http handler

Screenshot accepts the request context, so cancellation propagates automatically.

func screenshotHandler(client *screenshotapi.Client) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		url := r.URL.Query().Get("url")
		if url == "" {
			http.Error(w, `{"error":"url is required"}`, http.StatusBadRequest)
			return
		}

		result, err := client.Screenshot(r.Context(), screenshotapi.ScreenshotOptions{
			URL:     url,
			Type:    screenshotapi.WebP,
			Quality: 80,
		})
		if err != nil {
			http.Error(w, `{"error":"screenshot failed"}`, http.StatusBadGateway)
			return
		}

		w.Header().Set("Content-Type", result.ContentType)
		w.Header().Set("Cache-Control", "public, max-age=3600")
		w.Write(result.Image)
	}
}

Next steps

On this page