Updated February 2026 · 8 min read

Website Screenshot API
for Go

Go's standard library makes HTTP calls trivial, which means calling a screenshot API is about 15 lines of code. If you need local browser control, chromedp and Rod are your options. Here's working code for all three.

1. GrabShot API (Standard Library Only)

Zero dependencies. Just net/http and os.

package main

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

func screenshot(targetURL, output string) error {
	apiKey := "YOUR_API_KEY" // Free at grabshot.dev

	params := url.Values{
		"url":    {targetURL},
		"format": {"webp"},
		"width":  {"1440"},
		"apiKey": {apiKey},
	}

	resp, err := http.Get("https://grabshot.dev/v1/screenshot?" + params.Encode())
	if err != nil {
		return fmt.Errorf("request failed: %w", err)
	}
	defer resp.Body.Close()

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

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

	written, err := io.Copy(f, resp.Body)
	if err != nil {
		return err
	}

	fmt.Printf("Saved %d bytes to %s\n", written, output)
	return nil
}

func main() {
	if err := screenshot("https://github.com", "github.webp"); err != nil {
		fmt.Fprintf(os.Stderr, "Error: %v\n", err)
		os.Exit(1)
	}
}

Pros: No dependencies, compiles to a single binary, works on any platform.
Cons: Can't interact with pages (click, scroll).

2. chromedp (Headless Chrome)

chromedp drives Chrome via the DevTools Protocol. Full browser control in Go.

go get github.com/chromedp/chromedp
package main

import (
	"context"
	"os"
	"time"

	"github.com/chromedp/chromedp"
)

func main() {
	ctx, cancel := chromedp.NewContext(context.Background())
	defer cancel()

	ctx, cancel = context.WithTimeout(ctx, 30*time.Second)
	defer cancel()

	var buf []byte
	err := chromedp.Run(ctx,
		chromedp.EmulateViewport(1440, 900),
		chromedp.Navigate("https://github.com"),
		chromedp.WaitReady("body"),
		chromedp.CaptureScreenshot(&buf),
	)
	if err != nil {
		panic(err)
	}

	os.WriteFile("github.png", buf, 0644)
}

Pros: Full browser control, can interact with pages, good Go API.
Cons: Needs Chrome installed. High memory usage. Complex error handling for production use.

3. Rod

Rod is a higher-level alternative to chromedp with auto-download of Chrome.

go get github.com/go-rod/rod
package main

import "github.com/go-rod/rod"

func main() {
	page := rod.New().MustConnect().MustPage("https://github.com")
	page.MustWaitStable()
	page.MustScreenshot("github.png")
}

Pros: Simpler API than chromedp, auto-manages browser binary.
Cons: Same RAM/Chrome requirements. "Must" methods panic on error (use non-Must for production).

Concurrent Screenshots

Go's goroutines make batch screenshots easy with the API approach:

package main

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

func main() {
	urls := []string{
		"https://github.com",
		"https://stripe.com",
		"https://vercel.com",
		"https://linear.app",
	}

	apiKey := "YOUR_API_KEY"
	var wg sync.WaitGroup

	for _, u := range urls {
		wg.Add(1)
		go func(targetURL string) {
			defer wg.Done()

			params := url.Values{
				"url": {targetURL}, "format": {"webp"},
				"width": {"1440"}, "apiKey": {apiKey},
			}

			resp, err := http.Get("https://grabshot.dev/v1/screenshot?" + params.Encode())
			if err != nil {
				fmt.Printf("Error for %s: %v\n", targetURL, err)
				return
			}
			defer resp.Body.Close()

			// Domain as filename
			name := strings.ReplaceAll(strings.TrimPrefix(
				strings.TrimPrefix(targetURL, "https://"), "http://"), ".", "-")
			f, _ := os.Create(name + ".webp")
			io.Copy(f, resp.Body)
			f.Close()
			fmt.Printf("Done: %s\n", targetURL)
		}(u)
	}

	wg.Wait()
	fmt.Println("All screenshots captured")
}

Comparison

Feature GrabShot API chromedp Rod
DependenciesNone (stdlib)Chrome + moduleAuto-downloads Chrome
Binary size impact~0~5MB~5MB
RAM per screenshot~1MB200-400MB200-400MB
Page interactionNoFullFull
Docker friendlyYes (tiny image)Needs Chrome layerAuto-downloads

See it in action

Try GrabShot right now — paste any URL and get a screenshot instantly. No signup needed.

Try Free Screenshot Tool →