Ruby Screenshot API
Screenshot API integration for Ruby and Rails applications using Net::HTTP or the Faraday gem. Streamline visual testing, content generation, and background job processing with Sidekiq. Includes production patterns for retry logic, file uploads to Active Storage, and integration with Rails controller actions.
Quick Start
Install dependencies
No extra gems needed — Net::HTTP is part of Ruby stdlib. Optionally run gem install faraday for a friendlier HTTP client.
Get your API key
Sign up for Screenshotly and get your API key from the dashboard.
Copy the code example
Use our Ruby code example as a starting point.
Customize and integrate
Modify the code to fit your specific use case and requirements.
Code Example
# Ruby with Net::HTTP
require 'net/http'
require 'json'
def capture_screenshot(url, output_path)
uri = URI('https://api.screenshotly.app/screenshot')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request['Authorization'] = "Bearer #{ENV['SCREENSHOTLY_API_KEY']}"
request['Content-Type'] = 'application/json'
request.body = {
url: url,
device: 'desktop',
format: 'png'
}.to_json
response = http.request(request)
File.write(output_path, response.body)
endWhen to Use Ruby with Screenshotly
Use the Ruby integration for Rails applications, Sidekiq background jobs, and Rake automation tasks. Ruby is the natural fit when you need to generate screenshots from a Rails admin panel, process captures in Sidekiq workers, or store results in Active Storage.
Ruby Best Practices
Use the Faraday gem with faraday-retry middleware for automatic retry with exponential backoff on transient failures.
In Rails, create a ScreenshotService PORO (Plain Old Ruby Object) and register it in an initializer for clean dependency injection.
Attach screenshots directly to Active Storage: record.screenshot.attach(io: StringIO.new(response.body), filename: 'capture.png').
Process large batches with Sidekiq workers — set concurrency limits to match your API plan's rate limit.
Ruby: Production Notes
In Rails, the non-negotiable rule is: captures happen in a background job, never in a controller action. Inline capture ties up a Puma/Unicorn worker for 2–5 seconds and destroys throughput under load. The typical shape: controller enqueues `ScreenshotJob.perform_later(post)`; the job runs Faraday against the API; ActiveStorage attaches the returned image to the model.
Faraday is the preferred HTTP client because its middleware stack handles retries, error normalization, and response parsing cleanly. Build a dedicated `ScreenshotlyClient` service object owning a single Faraday instance (retry middleware, timeout, error handling) and inject it into any job that needs captures.
Error Handling Recipes
Concrete strategies for each failure mode. Do not silently swallow errors — surface them to your monitoring so the pipeline is observable.
HTTP 429
For Sidekiq, raise a rate-limit error to trigger job retry with backoff. Configure sidekiq_retry_in to respect Retry-After.
class ScreenshotJob
include Sidekiq::Job
sidekiq_retry_in do |count, exception|
exception.is_a?(RateLimitError) ? exception.retry_after : (count ** 2) + 5
end
endFaraday::ServerError (5xx)
Faraday::Retry middleware handles this cleanly. Configure 3 retries with exponential backoff — do not hand-roll retry loops.
Large response body
Use Faraday's streaming response support or Net::HTTP#request with a block that writes chunks to a Tempfile. Avoid loading into a String.
Production Hardening Checklist
The difference between dev code and prod code. Work through these before putting Ruby captures on a critical path.
- Capture runs in a background job (Sidekiq/GoodJob/Delayed) — controllers never call the API directly.
- Faraday client instantiated once per process and reused.
- Faraday retry middleware configured with exponential backoff.
- ActiveStorage (or Shrine) handles image persistence; avoid raw filesystem writes.
- Sidekiq Web UI or GoodJob Dashboard monitors queue health.
- API key stored in Rails.credentials, not .env.
Rate-Limit Strategy
Sidekiq concurrency × plan QPS is the math to get right. A 10-thread Sidekiq × 3 replicas = 30 concurrent captures. Use the sidekiq-throttled gem to cap concurrency on ScreenshotJob specifically, independent of overall throughput.
When Ruby isn't the right fit
Ruby works well for most capture workloads, but these patterns are legitimate reasons to pick a different stack:
- You run Rails on Heroku and hit the 30-second request timeout on ActiveStorage uploads. Enable direct_upload: true on large images to bypass the Rails process entirely, or move to a longer-timeout host.
- Your app has no background job infrastructure and you are not willing to add Sidekiq or GoodJob. Inline capture in controllers is a reliability footgun at any meaningful scale.
- You need GIL-free parallel execution for CPU-bound processing of captures. Ruby MRI's GIL limits parallelism; evaluate JRuby or a different runtime if that is your bottleneck.
Want a step-by-step walkthrough?
Read the full Ruby tutorial →API Reference
POST /api/screenshotBearer tokenapplication/jsonFrequently Asked Questions
How do I use Screenshotly with Ruby on Rails?
Create a service object that wraps the API call. Use Rails credentials (Rails.application.credentials.screenshotly_api_key) to store your key securely. Save screenshots to Active Storage or upload directly to S3.
What's the best HTTP client for Ruby integrations?
The Faraday gem is recommended for production use — it supports retries, timeouts, and middleware out of the box. For simpler scripts, Net::HTTP (shown above) works fine without additional dependencies.
How do I handle rate limiting in Ruby?
Check the response status code for 429 (Too Many Requests). Implement exponential backoff with the retryable gem or a custom retry loop. The API returns Retry-After headers to indicate when you can make the next request.
Can I capture screenshots asynchronously in Rails?
Yes. Use Active Job with Sidekiq or Delayed Job to process screenshot captures in the background. This prevents HTTP timeouts and allows you to queue large batches of captures.
Start building with Ruby
Get your API key and start capturing screenshots in minutes.
Other Languages
JavaScript
Capture website screenshots from the browser using client-side JavaScript. Call the Screenshotly API with the Fetch API from React, Vue, Angular, or vanilla JS — no server required for basic workflows. This guide covers browser JavaScript screenshot API usage, async/await patterns, error handling, blob URLs for display, and best practices for CORS and API key security when calling from the client.
Node.js
Server-side screenshot capture with Node.js — for backend services, Express/Fastify APIs, CLI tools, and automation scripts. This guide covers the Node.js screenshot API for server-side use only: streaming responses to disk or S3, Express screenshot middleware, cron jobs, and integrating with Bull/BullMQ for batch processing. Keep API keys on the server where they belong.
Python
Integrate screenshot capture into Python applications using the requests library or httpx. Ideal for data pipelines, Django/Flask web apps, automation scripts, and web scraping projects. Includes examples for synchronous and async requests, saving images to files, and handling rate limits with exponential backoff.
PHP
Add screenshot capabilities to PHP applications using cURL or Guzzle HTTP. Perfect for WordPress plugins, Laravel apps, and REST-based web services. Covers authentication, error handling, saving to local storage or S3, and integrating with Laravel queues for background processing.