Screenshot API for Ruby: Net::HTTP, Faraday & Rails Integration
Capture screenshots, scrape web pages, and generate PDFs from Ruby applications. Works with Rails, Sinatra, and standalone scripts — no headless browser setup required.
Screenshot API for Ruby — Net::HTTP Quickstart
Ruby's standard library includes everything you need to call SnapAPI. The Net::HTTP class handles HTTPS requests without any gems. Here is a minimal function that returns a JPEG screenshot as a binary string:
require 'net/http'
require 'uri'
def capture_screenshot(url, api_key)
params = URI.encode_www_form(
url: url,
full_page: true,
format: 'jpeg',
block_ads: true
)
uri = URI("https://api.snapapi.pics/v1/screenshot?#{params}")
req = Net::HTTP::Get.new(uri)
req["X-Api-Key"] = api_key
Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
http.read_timeout = 30
response = http.request(req)
raise "SnapAPI #{response.code}: #{response.body}" unless response.is_a?(Net::HTTPSuccess)
response.body
end
end
# Save screenshot to file
image_data = capture_screenshot("https://example.com", ENV["SNAPAPI_KEY"])
File.write("screenshot.jpg", image_data, mode: "wb")
puts "Captured #{image_data.bytesize} bytes"
The use_ssl: true option enables HTTPS. Setting read_timeout to 30 seconds is appropriate for most screenshot requests. For video recording endpoints, increase the timeout to 120 seconds to accommodate longer render times.
Using Faraday for a Cleaner Interface
If your project already uses Faraday, the integration is even more concise. Faraday handles connection pooling, retries, and middleware transparently:
require 'faraday'
conn = Faraday.new(url: "https://api.snapapi.pics") do |f|
f.request :retry, max: 3, interval: 2, backoff_factor: 2,
exceptions: [Faraday::TimeoutError, Faraday::ConnectionFailed]
f.options.timeout = 30
end
response = conn.get("/v1/screenshot") do |req|
req.headers["X-Api-Key"] = ENV["SNAPAPI_KEY"]
req.params[:url] = "https://example.com"
req.params[:full_page] = true
req.params[:block_cookies] = true
end
raise "Error: #{response.status}" unless response.success?
File.write("screenshot.jpg", response.body, mode: "wb")
The retry middleware handles transient 5xx errors and network timeouts automatically. Exponential backoff via backoff_factor: 2 doubles the wait between each retry attempt, reducing load on the API during periods of high demand.
Rails Integration: ActiveJob, Background Workers & Active Storage
In a Rails application, screenshot generation typically happens asynchronously to avoid blocking web requests. Wrap the SnapAPI call in an ActiveJob class and enqueue it from your controller:
class ScreenshotJob < ApplicationJob
queue_as :default
def perform(record_id, target_url)
record = Page.find(record_id)
image_data = SnapApiClient.capture(target_url)
# Store using Active Storage
record.screenshot.attach(
io: StringIO.new(image_data),
filename: "screenshot-#{record_id}.jpg",
content_type: "image/jpeg"
)
record.update!(screenshot_taken_at: Time.current)
end
end
# In your controller:
ScreenshotJob.perform_later(page.id, page.url)
Active Storage handles the upload to S3, GCS, or Azure Blob Storage transparently. The StringIO wrapper converts the binary string returned by SnapAPI into an IO object that Active Storage can read.
Scraping and Data Extraction in Ruby
SnapAPI's scrape and extract endpoints return structured JSON, making them a natural fit for Ruby's hash-based data handling. The extract endpoint accepts a CSS selector and returns the matched text directly:
require 'net/http'
require 'json'
def extract_price(product_url, api_key)
uri = URI("https://api.snapapi.pics/v1/extract")
req = Net::HTTP::Post.new(uri, "Content-Type" => "application/json")
req["X-Api-Key"] = api_key
req.body = {
url: product_url,
selector: ".price, [data-price], .product-price",
wait_for: ".price"
}.to_json
Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
response = http.request(req)
JSON.parse(response.body)["text"]
end
end
The wait_for parameter tells the API to wait until the specified selector is present in the DOM before extracting. This handles JavaScript-rendered pages and lazy-loaded content that Nokogiri-based scrapers miss entirely.
PDF Generation in Ruby with SnapAPI
Generating PDFs from HTML templates is a common Rails use case: invoices, reports, certificates, account statements. SnapAPI's PDF endpoint accepts a URL or raw HTML and returns a binary PDF with full CSS support, custom page sizes, and optional headers and footers:
def generate_invoice_pdf(invoice_url, api_key)
uri = URI("https://api.snapapi.pics/v1/pdf")
req = Net::HTTP::Post.new(uri, "Content-Type" => "application/json")
req["X-Api-Key"] = api_key
req.body = {
url: invoice_url,
page_size: "A4",
margin_top: "20mm",
margin_bottom: "20mm",
print_background: true
}.to_json
Net::HTTP.start(uri.host, uri.port, use_ssl: true, read_timeout: 60) do |http|
response = http.request(req)
raise "PDF error: #{response.code}" unless response.is_a?(Net::HTTPSuccess)
response.body
end
end
PDF generation is typically slower than screenshots because the browser must lay out the entire document for print media. The 60-second timeout accommodates complex invoice templates with embedded charts or custom fonts. For simpler one-page PDFs, 30 seconds is usually sufficient.
Try SnapAPI free — 200 captures per month at snapapi.pics, no credit card required. Ruby integration requires zero additional gems when using Net::HTTP. Sign up, copy your API key from the dashboard, and make your first screenshot call in under five minutes.