Install the SnapAPI Go module and capture your first screenshot in under a minute. Zero dependencies, idiomatic error handling, and full context support.
Install the official SnapAPI Go module:
go get github.com/snapapi/snapapi-go
Requires Go 1.21 or later. The module has zero external dependencies.
Get your API key from the SnapAPI dashboard and initialize the client:
package main
import "github.com/snapapi/snapapi-go"
func main() {
// Initialize with your API key
client := snapapi.NewClient("YOUR_API_KEY")
// Or use an environment variable (recommended)
client := snapapi.NewClient(os.Getenv("SNAPAPI_KEY"))
}package main
import (
"log"
"os"
"github.com/snapapi/snapapi-go"
)
func main() {
client := snapapi.NewClient(os.Getenv("SNAPAPI_KEY"))
screenshot, err := client.Screenshot(snapapi.ScreenshotOptions{
URL: "https://example.com",
Format: "png",
Width: 1280,
Height: 800,
})
if err != nil {
log.Fatal(err)
}
os.WriteFile("screenshot.png", screenshot, 0644)
log.Println("Screenshot saved!")
}screenshot, err := client.Screenshot(snapapi.ScreenshotOptions{
URL: "https://example.com",
Format: "png",
FullPage: true,
Width: 1280,
})screenshot, err := client.Screenshot(snapapi.ScreenshotOptions{
URL: "https://example.com",
Format: "avif", // png, jpeg, webp, avif
Width: 1440,
Height: 900,
FullPage: false,
BlockAds: true, // Block ads
BlockCookies: true, // Block cookie banners
Delay: 2000, // Wait 2s before capture
DevicePreset: "iPhone15", // Mobile device emulation
CSS: "body { background: white; }",
ResponseType: "url", // Get hosted URL instead of binary
})result, err := client.ScreenshotURL(snapapi.ScreenshotOptions{
URL: "https://example.com",
Format: "png",
})
if err != nil {
log.Fatal(err)
}
fmt.Println(result.URL)
// → https://cdn.snapapi.pics/screenshots/abc123.pngpdf, err := client.PDF(snapapi.PDFOptions{
URL: "https://example.com",
Format: "A4",
PrintBackground: true,
Margin: snapapi.Margin{
Top: "20mm",
Bottom: "20mm",
Left: "15mm",
Right: "15mm",
},
})
if err != nil {
log.Fatal(err)
}
os.WriteFile("page.pdf", pdf, 0644)pdf, err := client.PDF(snapapi.PDFOptions{
HTML: "<h1>Invoice #1234</h1><p>Total: $99.00</p>",
Format: "A4",
PrintBackground: true,
})Extract clean markdown or structured data from any webpage — perfect for LLM pipelines.
content, err := client.Extract(snapapi.ExtractOptions{
URL: "https://example.com/blog-post",
Format: "markdown",
})
if err != nil {
log.Fatal(err)
}
fmt.Println(content.Markdown)
// → # Blog Post Title\n\nArticle content here...data, err := client.Extract(snapapi.ExtractOptions{
URL: "https://example.com/product",
Format: "structured",
Schema: map[string]string{
"title": "string",
"price": "number",
"description": "string",
},
})Record a video of a webpage loading, scrolling, or interacting with elements.
video, err := client.Video(snapapi.VideoOptions{
URL: "https://example.com",
Duration: 5, // seconds
Width: 1280,
Height: 720,
Format: "mp4",
})
if err != nil {
log.Fatal(err)
}
os.WriteFile("recording.mp4", video, 0644)video, err := client.Video(snapapi.VideoOptions{
URL: "https://example.com",
Duration: 8,
Width: 1280,
Height: 720,
Format: "mp4",
Actions: []snapapi.Action{
{Type: "wait", Duration: 1000},
{Type: "scroll", Y: 500},
{Type: "wait", Duration: 2000},
{Type: "scroll", Y: 1000},
},
})The SDK returns typed errors for common issues:
import "errors"
screenshot, err := client.Screenshot(snapapi.ScreenshotOptions{
URL: "https://example.com",
})
if err != nil {
var apiErr *snapapi.APIError
if errors.As(err, &apiErr) {
switch apiErr.StatusCode {
case 401:
log.Fatal("Invalid API key")
case 429:
log.Printf("Rate limit exceeded. Retry after: %s", apiErr.RetryAfter)
case 400:
log.Printf("Bad request: %s", apiErr.Message)
default:
log.Printf("API error %d: %s", apiErr.StatusCode, apiErr.Message)
}
} else {
log.Printf("Network error: %v", err)
}
return
}
os.WriteFile("screenshot.png", screenshot, 0644)429 Too Many Requests with a Retry-After header. Upgrade your plan for higher limits.
The client is goroutine-safe. Use sync.WaitGroup or errgroup to capture multiple pages concurrently.
import (
"context"
"fmt"
"os"
"golang.org/x/sync/errgroup"
"github.com/snapapi/snapapi-go"
)
func main() {
client := snapapi.NewClient(os.Getenv("SNAPAPI_KEY"))
urls := []string{
"https://example.com",
"https://example.org",
"https://example.net",
}
g, ctx := errgroup.WithContext(context.Background())
for i, url := range urls {
i, url := i, url // capture loop vars
g.Go(func() error {
screenshot, err := client.ScreenshotWithContext(ctx, snapapi.ScreenshotOptions{
URL: url,
Format: "png",
Width: 1280,
})
if err != nil {
return fmt.Errorf("failed %s: %w", url, err)
}
return os.WriteFile(fmt.Sprintf("screenshot_%d.png", i), screenshot, 0644)
})
}
if err := g.Wait(); err != nil {
fmt.Println("Error:", err)
} else {
fmt.Println("All screenshots captured!")
}
}import (
"fmt"
"os"
"sync"
"github.com/snapapi/snapapi-go"
)
type Result struct {
Index int
Data []byte
Err error
}
func main() {
client := snapapi.NewClient(os.Getenv("SNAPAPI_KEY"))
urls := []string{"https://example.com", "https://example.org"}
results := make(chan Result, len(urls))
var wg sync.WaitGroup
for i, url := range urls {
wg.Add(1)
go func(i int, url string) {
defer wg.Done()
data, err := client.Screenshot(snapapi.ScreenshotOptions{
URL: url, Format: "png", Width: 1280,
})
results <- Result{Index: i, Data: data, Err: err}
}(i, url)
}
wg.Wait()
close(results)
for r := range results {
if r.Err != nil {
fmt.Printf("Error on %d: %v\n", r.Index, r.Err)
continue
}
os.WriteFile(fmt.Sprintf("shot_%d.png", r.Index), r.Data, 0644)
}
}All methods accept a context.Context via the WithContext variants. Use this for timeouts, cancellation, and deadline propagation.
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
screenshot, err := client.ScreenshotWithContext(ctx, snapapi.ScreenshotOptions{
URL: "https://example.com",
Format: "png",
})
if err != nil {
if errors.Is(err, context.DeadlineExceeded) {
log.Println("Request timed out after 30s")
} else {
log.Fatal(err)
}
}ctx, cancel := context.WithCancel(context.Background())
// Cancel from another goroutine
go func() {
time.Sleep(5 * time.Second)
cancel() // abort the request
}()
screenshot, err := client.ScreenshotWithContext(ctx, snapapi.ScreenshotOptions{
URL: "https://slow-website.com",
})
if errors.Is(err, context.Canceled) {
log.Println("Request was cancelled")
}func screenshotHandler(w http.ResponseWriter, r *http.Request) {
url := r.URL.Query().Get("url")
if url == "" {
http.Error(w, "missing url parameter", http.StatusBadRequest)
return
}
// Use the request context — auto-cancels if client disconnects
screenshot, err := client.ScreenshotWithContext(r.Context(), snapapi.ScreenshotOptions{
URL: url,
Format: "png",
Width: 1280,
})
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "image/png")
w.Write(screenshot)
}screenshot, err := client.Screenshot(snapapi.ScreenshotOptions{
URL: "https://example.com/dashboard",
Headers: map[string]string{
"Authorization": "Bearer your-token",
"Cookie": "session=abc123",
},
})// Use a device preset
mobile, err := client.Screenshot(snapapi.ScreenshotOptions{
URL: "https://example.com",
DevicePreset: "iPhone15", // 26+ presets available
})
// Or set custom viewport
custom, err := client.Screenshot(snapapi.ScreenshotOptions{
URL: "https://example.com",
Width: 375,
Height: 812,
DeviceScaleFactor: 3,
})import "net/http"
httpClient := &http.Client{
Timeout: 60 * time.Second,
}
client := snapapi.NewClientWithHTTP("YOUR_API_KEY", httpClient)