SDKs & Libraries
Integrate ScreenshotAPI into your application using the language or framework of your choice. Below you'll find complete, production-ready examples for popular platforms.
PHP
Laravel / PHP (with Guzzle)
Create a reusable service class for your Laravel application:
php
namespace App\Services;
use Illuminate\Support\Facades\Http;
class ScreenshotApiClient
{
private string $baseUrl = 'https://screenshotrun.com/api/v1';
private string $apiKey;
public function __construct()
{
$this->apiKey = config('services.screenshotapi.key');
}
/**
* Take a screenshot of a URL.
*/
public function capture(string $url, array $options = []): array
{
$response = Http::withToken($this->apiKey)
->post("{$this->baseUrl}/screenshots", array_merge(
['url' => $url],
$options,
));
$response->throw();
return $response->json('data');
}
/**
* Get screenshot details by ID.
*/
public function get(string $id): array
{
$response = Http::withToken($this->apiKey)
->get("{$this->baseUrl}/screenshots/{$id}");
$response->throw();
return $response->json('data');
}
/**
* Download the screenshot image.
*/
public function download(string $id, string $savePath): void
{
$response = Http::withToken($this->apiKey)
->get("{$this->baseUrl}/screenshots/{$id}/image");
$response->throw();
file_put_contents($savePath, $response->body());
}
/**
* List screenshots with optional filters.
*/
public function list(array $filters = []): array
{
$response = Http::withToken($this->apiKey)
->get("{$this->baseUrl}/screenshots", $filters);
$response->throw();
return $response->json();
}
/**
* Delete a screenshot.
*/
public function delete(string $id): bool
{
$response = Http::withToken($this->apiKey)
->delete("{$this->baseUrl}/screenshots/{$id}");
return $response->status() === 204;
}
/**
* Wait for a screenshot to complete (polling).
*/
public function captureAndWait(string $url, array $options = [], int $timeout = 60): array
{
$screenshot = $this->capture($url, $options);
$startTime = time();
while (time() - $startTime < $timeout) {
$screenshot = $this->get($screenshot['id']);
if ($screenshot['status'] === 'completed') {
return $screenshot;
}
if ($screenshot['status'] === 'failed') {
throw new \RuntimeException(
"Screenshot failed: " . ($screenshot['error']['message'] ?? 'Unknown error')
);
}
sleep(2);
}
throw new \RuntimeException("Screenshot timed out after {$timeout} seconds");
}
}
Usage
php
// config/services.php
'screenshotapi' => [
'key' => env('SCREENSHOT_API_KEY'),
],
// In your controller or service
$client = new ScreenshotApiClient();
// Simple capture
$screenshot = $client->capture('https://example.com', [
'format' => 'webp',
'full_page' => true,
]);
// Capture and wait for result
$screenshot = $client->captureAndWait('https://example.com');
$client->download($screenshot['id'], storage_path('screenshots/example.png'));
Python
Python (requests)
python
import os
import time
import requests
class ScreenshotAPI:
def __init__(self, api_key=None):
self.api_key = api_key or os.environ.get("SCREENSHOT_API_KEY")
self.base_url = "https://screenshotrun.com/api/v1"
self.session = requests.Session()
self.session.headers.update({
"Authorization": f"Bearer {self.api_key}",
"Content-Type": "application/json",
})
def capture(self, url, **options):
"""Take a screenshot of a URL."""
response = self.session.post(
f"{self.base_url}/screenshots",
json={"url": url, **options},
)
response.raise_for_status()
return response.json()["data"]
def get(self, screenshot_id):
"""Get screenshot details by ID."""
response = self.session.get(f"{self.base_url}/screenshots/{screenshot_id}")
response.raise_for_status()
return response.json()["data"]
def download(self, screenshot_id, save_path):
"""Download the screenshot image to a file."""
response = self.session.get(f"{self.base_url}/screenshots/{screenshot_id}/image")
response.raise_for_status()
with open(save_path, "wb") as f:
f.write(response.content)
def list(self, **filters):
"""List screenshots with optional filters."""
response = self.session.get(f"{self.base_url}/screenshots", params=filters)
response.raise_for_status()
return response.json()
def delete(self, screenshot_id):
"""Delete a screenshot."""
response = self.session.delete(f"{self.base_url}/screenshots/{screenshot_id}")
return response.status_code == 204
def capture_and_wait(self, url, timeout=60, **options):
"""Take a screenshot and wait for it to complete."""
screenshot = self.capture(url, **options)
start_time = time.time()
while time.time() - start_time < timeout:
screenshot = self.get(screenshot["id"])
if screenshot["status"] == "completed":
return screenshot
if screenshot["status"] == "failed":
raise Exception(f"Screenshot failed: {screenshot['error']['message']}")
time.sleep(2)
raise TimeoutError(f"Screenshot timed out after {timeout} seconds")
def get_usage(self):
"""Get current usage statistics."""
response = self.session.get(f"{self.base_url}/account/usage")
response.raise_for_status()
return response.json()["data"]
Usage
python
api = ScreenshotAPI("sk_live_your_key_here")
# Simple capture
screenshot = api.capture("https://example.com", format="webp", full_page=True)
print(f"Screenshot ID: {screenshot['id']}")
# Capture and wait
screenshot = api.capture_and_wait("https://example.com")
api.download(screenshot["id"], "example.png")
# List completed screenshots
result = api.list(status="completed", per_page=10)
for s in result["data"]:
print(f"{s['id']}: {s['url']}")
# Check usage
usage = api.get_usage()
print(f"Used: {usage['screenshots_used']}/{usage['screenshots_limit']}")
JavaScript / TypeScript
Node.js (Fetch API)
javascript
import fs from "fs";
class ScreenshotAPI {
constructor(apiKey) {
this.apiKey = apiKey || process.env.SCREENSHOT_API_KEY;
this.baseUrl = "https://screenshotrun.com/api/v1";
}
async #request(method, path, { body, params } = {}) {
const url = new URL(`${this.baseUrl}${path}`);
if (params) {
Object.entries(params).forEach(([k, v]) => url.searchParams.set(k, v));
}
const response = await fetch(url.toString(), {
method,
headers: {
Authorization: `Bearer ${this.apiKey}`,
"Content-Type": "application/json",
},
body: body ? JSON.stringify(body) : undefined,
});
if (!response.ok) {
const error = await response.json();
throw new Error(`[${error.error.code}] ${error.error.message}`);
}
if (response.status === 204) return null;
return response;
}
async capture(url, options = {}) {
const response = await this.#request("POST", "/screenshots", {
body: { url, ...options },
});
return (await response.json()).data;
}
async get(id) {
const response = await this.#request("GET", `/screenshots/${id}`);
return (await response.json()).data;
}
async download(id, savePath) {
const response = await this.#request("GET", `/screenshots/${id}/image`);
const buffer = Buffer.from(await response.arrayBuffer());
fs.writeFileSync(savePath, buffer);
}
async list(filters = {}) {
const response = await this.#request("GET", "/screenshots", { params: filters });
return await response.json();
}
async delete(id) {
await this.#request("DELETE", `/screenshots/${id}`);
return true;
}
async captureAndWait(url, options = {}, timeout = 60000) {
let screenshot = await this.capture(url, options);
const startTime = Date.now();
while (Date.now() - startTime < timeout) {
screenshot = await this.get(screenshot.id);
if (screenshot.status === "completed") return screenshot;
if (screenshot.status === "failed") {
throw new Error(`Screenshot failed: ${screenshot.error.message}`);
}
await new Promise((r) => setTimeout(r, 2000));
}
throw new Error(`Screenshot timed out after ${timeout}ms`);
}
}
Usage
javascript
const api = new ScreenshotAPI("sk_live_your_key_here");
// Simple capture
const screenshot = await api.capture("https://example.com", {
format: "webp",
full_page: true,
});
console.log(`Screenshot ID: ${screenshot.id}`);
// Capture and wait
const completed = await api.captureAndWait("https://example.com");
await api.download(completed.id, "example.png");
// List screenshots
const { data } = await api.list({ status: "completed", per_page: 10 });
data.forEach((s) => console.log(`${s.id}: ${s.url}`));
Ruby
Ruby (net/http)
ruby
require "net/http"
require "json"
require "uri"
class ScreenshotAPI
BASE_URL = "https://screenshotrun.com/api/v1"
def initialize(api_key = nil)
@api_key = api_key || ENV["SCREENSHOT_API_KEY"]
end
def capture(url, **options)
response = post("/screenshots", { url: url, **options })
JSON.parse(response.body)["data"]
end
def get(id)
response = request(:get, "/screenshots/#{id}")
JSON.parse(response.body)["data"]
end
def download(id, save_path)
response = request(:get, "/screenshots/#{id}/image")
File.binwrite(save_path, response.body)
end
def list(**filters)
query = URI.encode_www_form(filters)
response = request(:get, "/screenshots?#{query}")
JSON.parse(response.body)
end
def delete(id)
response = request(:delete, "/screenshots/#{id}")
response.code == "204"
end
def capture_and_wait(url, timeout: 60, **options)
screenshot = capture(url, **options)
start_time = Time.now
loop do
screenshot = get(screenshot["id"])
return screenshot if screenshot["status"] == "completed"
if screenshot["status"] == "failed"
raise "Screenshot failed: #{screenshot['error']['message']}"
end
raise "Timeout after #{timeout}s" if Time.now - start_time > timeout
sleep 2
end
end
private
def request(method, path)
uri = URI("#{BASE_URL}#{path}")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = uri.scheme == "https"
req = case method
when :get then Net::HTTP::Get.new(uri)
when :delete then Net::HTTP::Delete.new(uri)
end
req["Authorization"] = "Bearer #{@api_key}"
http.request(req)
end
def post(path, body)
uri = URI("#{BASE_URL}#{path}")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = uri.scheme == "https"
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer #{@api_key}"
req["Content-Type"] = "application/json"
req.body = body.to_json
http.request(req)
end
end
Usage
ruby
api = ScreenshotAPI.new("sk_live_your_key_here")
# Capture and wait
screenshot = api.capture_and_wait("https://example.com", format: "webp")
api.download(screenshot["id"], "example.webp")
# List completed screenshots
result = api.list(status: "completed", per_page: 10)
result["data"].each { |s| puts "#{s['id']}: #{s['url']}" }
Go
Go (net/http)
go
package screenshotapi
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"time"
)
const baseURL = "https://screenshotrun.com/api/v1"
type Client struct {
APIKey string
HTTPClient *http.Client
}
type Screenshot struct {
ID string `json:"id"`
Status string `json:"status"`
URL string `json:"url"`
Options map[string]interface{} `json:"options"`
FileSize int64 `json:"file_size,omitempty"`
MimeType string `json:"mime_type,omitempty"`
Width int `json:"width,omitempty"`
Height int `json:"height,omitempty"`
ProcessingTime int `json:"processing_time_ms,omitempty"`
Error *ErrorInfo `json:"error,omitempty"`
CreatedAt string `json:"created_at"`
}
type ErrorInfo struct {
Message string `json:"message"`
Code string `json:"code"`
}
func NewClient(apiKey string) *Client {
return &Client{
APIKey: apiKey,
HTTPClient: &http.Client{Timeout: 30 * time.Second},
}
}
func (c *Client) Capture(url string, options map[string]interface{}) (*Screenshot, error) {
if options == nil {
options = make(map[string]interface{})
}
options["url"] = url
body, _ := json.Marshal(options)
req, _ := http.NewRequest("POST", baseURL+"/screenshots", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+c.APIKey)
req.Header.Set("Content-Type", "application/json")
resp, err := c.HTTPClient.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
var result struct{ Data Screenshot `json:"data"` }
json.NewDecoder(resp.Body).Decode(&result)
return &result.Data, nil
}
func (c *Client) Get(id string) (*Screenshot, error) {
req, _ := http.NewRequest("GET", baseURL+"/screenshots/"+id, nil)
req.Header.Set("Authorization", "Bearer "+c.APIKey)
resp, err := c.HTTPClient.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
var result struct{ Data Screenshot `json:"data"` }
json.NewDecoder(resp.Body).Decode(&result)
return &result.Data, nil
}
func (c *Client) Download(id, savePath string) error {
req, _ := http.NewRequest("GET", baseURL+"/screenshots/"+id+"/image", nil)
req.Header.Set("Authorization", "Bearer "+c.APIKey)
resp, err := c.HTTPClient.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
file, err := os.Create(savePath)
if err != nil {
return err
}
defer file.Close()
_, err = io.Copy(file, resp.Body)
return err
}
func (c *Client) CaptureAndWait(url string, options map[string]interface{}, timeout time.Duration) (*Screenshot, error) {
screenshot, err := c.Capture(url, options)
if err != nil {
return nil, err
}
deadline := time.Now().Add(timeout)
for time.Now().Before(deadline) {
screenshot, err = c.Get(screenshot.ID)
if err != nil {
return nil, err
}
if screenshot.Status == "completed" {
return screenshot, nil
}
if screenshot.Status == "failed" {
return nil, fmt.Errorf("screenshot failed: %s", screenshot.Error.Message)
}
time.Sleep(2 * time.Second)
}
return nil, fmt.Errorf("screenshot timed out after %v", timeout)
}
Usage
go
client := screenshotapi.NewClient("sk_live_your_key_here")
// Capture and wait
screenshot, err := client.CaptureAndWait("https://example.com", map[string]interface{}{
"format": "webp",
"full_page": true,
}, 60*time.Second)
if err != nil {
log.Fatal(err)
}
// Download the image
err = client.Download(screenshot.ID, "example.webp")
if err != nil {
log.Fatal(err)
}
fmt.Printf("Screenshot saved! Size: %d bytes\n", screenshot.FileSize)
cURL
For quick testing and scripting, cURL is the simplest way to interact with the API:
Complete workflow
bash
#!/bin/bash
API_KEY="sk_live_your_key_here"
BASE_URL="https://screenshotrun.com/api/v1"
# 1. Create screenshot
RESPONSE=$(curl -s -X POST "$BASE_URL/screenshots" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com", "format": "png", "full_page": true}')
SCREENSHOT_ID=$(echo $RESPONSE | python3 -c "import sys,json; print(json.load(sys.stdin)['data']['id'])")
echo "Screenshot ID: $SCREENSHOT_ID"
# 2. Poll until ready
while true; do
STATUS_RESPONSE=$(curl -s "$BASE_URL/screenshots/$SCREENSHOT_ID" \
-H "Authorization: Bearer $API_KEY")
STATUS=$(echo $STATUS_RESPONSE | python3 -c "import sys,json; print(json.load(sys.stdin)['data']['status'])")
if [ "$STATUS" = "completed" ]; then
echo "Screenshot ready!"
break
elif [ "$STATUS" = "failed" ]; then
echo "Screenshot failed!"
exit 1
fi
echo "Status: $STATUS, waiting..."
sleep 2
done
# 3. Download the image
curl -s "$BASE_URL/screenshots/$SCREENSHOT_ID/image" \
-H "Authorization: Bearer $API_KEY" \
-o screenshot.png
echo "Saved to screenshot.png"