Capture website screenshots in Ruby without managing headless Chrome. Works with Rails, Sinatra, and any Ruby application.
Get Free API Key →require 'net/http'
require 'uri'
uri = URI("https://grabshot.dev/v1/screenshot")
uri.query = URI.encode_www_form(
url: "https://example.com",
key: "YOUR_API_KEY"
)
response = Net::HTTP.get_response(uri)
File.write("screenshot.png", response.body)
# app/services/screenshot_service.rb
class ScreenshotService
API_URL = "https://grabshot.dev/v1/screenshot"
def capture(url, options = {})
uri = URI(API_URL)
uri.query = URI.encode_www_form({
url: url,
key: Rails.application.credentials.grabshot_api_key,
width: options[:width] || "1440",
format: options[:format] || "png",
fullPage: options[:full_page] || "false"
}.compact)
response = Net::HTTP.get_response(uri)
raise "Screenshot failed: #{response.code}" unless response.is_a?(Net::HTTPSuccess)
response.body
end
end
# Usage in a controller:
class ScreenshotsController < ApplicationController
def create
service = ScreenshotService.new
image = service.capture(params[:url])
send_data image, type: "image/png", disposition: "inline"
end
end
require 'faraday'
conn = Faraday.new("https://grabshot.dev") do |f|
f.request :url_encoded
end
response = conn.get("/v1/screenshot", {
url: "https://github.com",
key: ENV["GRABSHOT_API_KEY"],
width: "1920",
deviceFrame: "macbook"
})
File.write("github.png", response.body)
# Attach a website screenshot to a model
class Website < ApplicationRecord
has_one_attached :screenshot
def capture_screenshot!
service = ScreenshotService.new
image = service.capture(self.url)
screenshot.attach(
io: StringIO.new(image),
filename: "#{URI.parse(url).host}.png",
content_type: "image/png"
)
end
end
Free: 25 screenshots/month. No credit card.
Starter: $9/mo for 2,500 screenshots.
Pro: $29/mo for 10,000 screenshots with AI cleanup.
Start Free — No Credit Card →