screenshotfreeapi
Official Rust client for the ScreenshotFreeAPI — Screenshot-as-a-Service for developers.
Capture pixel-perfect screenshots of any website, mobile app listing, or raw HTML in under 10 lines of Rust.
Install
[]
= "1"
= { = "1", = ["full"] }
Quick start
use ScreenshotFreeAPIClient;
async
Features
- Web screenshots — any public URL, with optional AI element targeting
- AI targeting — describe what you want in plain English; Claude finds it
- PDF generation — convert any URL to a print-quality PDF
- HTML rendering — screenshot raw HTML strings (email templates, certificates)
- Mobile app screenshots — App Store and Google Play listings
- Full async/await — built on
tokio+reqwest - Automatic retries — 3 attempts with exponential back-off (1 s / 2 s / 4 s)
- Rate-limit handling — honours
Retry-Afterheader automatically - Webhook verification — HMAC-SHA256 in constant time
- Progress callbacks — hook into polling with
WaitOptions.on_progress - Zero-cost cloning —
ScreenshotFreeAPIClientisClone(Arc-backed)
Full API reference
Client construction
use ScreenshotFreeAPIClient;
// Production
let client = new;
// Custom base URL (development / staging)
let client = with_base_url;
Auth — client.auth
use ;
// Create an account (API key returned once — store it immediately)
let reg = client.auth.register.await?;
println!;
// Obtain a management JWT for billing / workspaces / monitors
let token = client.auth.token.await?;
let jwt = token.access_token;
// Refresh an access token
let refreshed = client.auth.refresh.await?;
Screenshots — client.screenshots
Web screenshot (non-blocking enqueue)
use WebScreenshotOptions;
let enq = client.screenshots.capture_web.await?;
println!;
Web screenshot (enqueue + wait for result)
use ;
let result = client.screenshots.capture_web_and_wait.await?;
println!;
Mobile app screenshot
use MobileScreenshotOptions;
let result = client.screenshots.capture_mobile_and_wait.await?;
HTML string rendering
use HtmlScreenshotOptions;
let result = client.screenshots.capture_html_and_wait.await?;
Jobs — client.jobs
// Poll status
let status = client.jobs.status.await?;
println!;
// Fetch result (only valid once status == "completed")
let result = client.jobs.result.await?;
Billing — client.billing
All billing methods require a management JWT (jwt: &str).
// List plans (public, no JWT required)
let plans = client.billing.plans.await?;
// Current subscription
let plan = client.billing.plan.await?;
// 30-day usage history
let usage = client.billing.usage.await?;
println!;
// Upgrade (returns Flutterwave checkout URL)
use UpgradeRequest;
let upgrade = client.billing.upgrade.await?;
if let Some = upgrade.redirect_url
// Verify payment after checkout redirect
let verified = client.billing.verify.await?;
// Cancel subscription
let cancelled = client.billing.cancel.await?;
Workspaces — client.workspaces
All workspace methods require a JWT.
use ;
// Create
let ws = client.workspaces.create.await?;
// List
let workspaces = client.workspaces.list.await?;
// Detail (includes members)
let detail = client.workspaces.get.await?;
// Invite
client.workspaces.invite.await?;
// Change role
client.workspaces.update_member_role.await?;
// Remove member
client.workspaces.remove_member.await?;
Monitors — client.monitors
use CreateMonitorRequest;
// Create a daily monitor
let monitor = client.monitors.create.await?;
// List monitors
let monitors = client.monitors.list.await?;
// Get one
let m = client.monitors.get.await?;
// History
let history = client.monitors.history.await?;
// Delete
client.monitors.delete.await?;
Integrations — client.integrations
use ZapierSubscribeRequest;
// Subscribe
let sub = client.integrations.zapier_subscribe.await?;
// Sample payload (for Zapier setup UI)
let sample = client.integrations.zapier_trigger_sample.await?;
// Unsubscribe
client.integrations.zapier_unsubscribe.await?;
Error handling
All methods return screenshotfreeapi::Result<T> — an alias for
std::result::Result<T, ScreenshotFreeAPIError>.
use ;
match client.capture.await
Error variants
| Variant | HTTP status | When |
|---|---|---|
Authentication |
401 | Invalid or missing API key |
Forbidden |
403 | Key revoked, account suspended |
NotFound |
404 | Job not found or not owned by this key |
Validation |
400 | Request body failed validation |
RateLimit |
429 | Per-minute rate limit hit |
QuotaExceeded |
429 | Monthly screenshot quota exhausted |
PaymentRequired |
402 | Subscription cancelled or overdue |
JobFailed |
— | Job reached failed terminal state |
JobTimeout |
— | Polling exceeded WaitOptions.timeout_ms |
InvalidSignature |
— | Webhook HMAC verification failed |
Unexpected |
other | Any other HTTP status |
Http |
— | reqwest transport error |
Webhook verification
Every webhook POST from the API includes an X-ScreenshotFree-Signature header
containing HMAC-SHA256(body, secret) as a lowercase hex string.
use verify_webhook_signature;
// In your HTTP handler (pseudocode):
let body: & = request.body_bytes;
let signature: &str = request.header;
let secret: &str = "your_webhook_signing_secret";
verify_webhook_signature?;
// Signature matched — safe to parse and process the event
The comparison is performed in constant time to prevent timing attacks.
WaitOptions with progress callback
use ;
let result = client.screenshots.capture_web_and_wait.await?;
Concurrent captures
Use tokio::join! for a fixed number of concurrent captures:
use ;
let client = new;
let c = client.clone;
let = join!;
println!;
println!;
println!;
For a dynamic list, collect futures and await them with futures::future::join_all:
// (add `futures = "0.3"` to Cargo.toml)
use join_all;
let urls = vec!;
let client = new;
let futures: = urls.iter
.map
.collect;
let results = join_all.await;
for result in results
License
MIT — see LICENSE.