Ruby SDK
Create sessions, interact with pages, and extract structured data.
Installation #
Install the gem from RubyGems:
gem install browserbeam
Or add it to your Gemfile:
gem "browserbeam"
Then run:
bundle install
Quick Start #
Create a client, open a session, and interact with a page:
require "browserbeam"
client = Browserbeam::Client.new(api_key: "bb_your_key")
session = client.sessions.create(url: "https://example.com")
session.click(text: "More information")
result = session.extract(title: "string", paragraphs: ["string"])
puts result.extraction
session.close
Configuration #
Pass options when you create the client:
client = Browserbeam::Client.new(
api_key: "bb_your_key", # or set BROWSERBEAM_API_KEY env var
base_url: "https://api.browserbeam.com", # default
timeout: 120 # request timeout in seconds, default 120
)
| Option | Default | Description |
|---|---|---|
api_key |
ENV["BROWSERBEAM_API_KEY"] |
Your API key. The param takes priority over the env var. |
base_url |
https://api.browserbeam.com |
API base URL. |
timeout |
120 |
HTTP request timeout in seconds. |
api_key, the SDK reads BROWSERBEAM_API_KEY from the environment. If neither is set, it raises an ArgumentError.
Creating Sessions #
Call client.sessions.create to launch a browser session. It returns a Session object you use for all subsequent actions.
session = client.sessions.create(
url: "https://example.com",
viewport: { width: 1280, height: 720 },
locale: "en-US",
timezone: "America/New_York",
user_agent: "MyBot/1.0",
proxy: "http://user:pass@proxy.example.com:8080",
block_resources: ["image", "font"],
auto_dismiss_blockers: true,
cookies: [{ name: "session", value: "abc123", domain: ".example.com" }],
idempotency_key: "unique-request-id"
)
puts session.page.title
| Parameter | Type | Description |
|---|---|---|
url |
String | URL to navigate to after launch. |
viewport |
Hash | { width:, height: } — browser viewport size. |
locale |
String | Browser locale, e.g. "en-US". |
timezone |
String | IANA timezone, e.g. "America/New_York". |
user_agent |
String | Custom user-agent string. |
proxy |
String | HTTP proxy URL. |
block_resources |
Array | Resource types to block, e.g. ["image", "font"]. |
auto_dismiss_blockers |
Boolean | Auto-dismiss cookie banners and overlays. |
cookies |
Array | Cookies to set before navigation. |
idempotency_key |
String | Prevents duplicate session creation. |
Session Methods #
Every method below sends a step to the browser and returns the updated session envelope.
| Method | Description |
|---|---|
goto(url) | Navigate to a URL. |
observe | Get page content and interactive elements. |
click | Click an element by ref, text, or label. |
type | Type text character by character. |
select | Select a dropdown option. |
check | Toggle a checkbox. |
fill | Set the value of an input field; target by ref, text, or label. |
fill_form | Fill multiple form fields at once. |
extract | Extract structured data matching a schema. |
screenshot | Take a screenshot of the page. |
scroll_collect | Scroll the page and collect content. |
scroll | Scroll the page or to an element. |
wait | Wait for time, selector, text, or JS expression. |
upload | Upload files to a file input. |
pdf | Generate a PDF of the page. |
execute_js | Run JavaScript in the browser. |
close | Close the browser session. |
goto(url) #
Navigate the browser to a new URL.
session.goto("https://example.com/about")
# Wait for a CSS selector or JS expression
session.goto("https://example.com", wait_for: ".loaded", wait_timeout: 5000)
session.goto("https://example.com", wait_until: "document.readyState === 'complete'")
observe #
Read the page content and discover interactive elements. Use this to understand what you can click or fill.
result = session.observe(scope: "main", format: "markdown")
puts result.page.markdown.content
result.page.interactive_elements.each do |el|
puts "#{el.ref} — #{el.tag} — #{el.label}"
end
click #
Click an element. Target by ref (from observe), visible text, or label.
# By ref from observe results
session.click(ref: "a7")
# By visible text
session.click(text: "Sign in")
# By label (for buttons, links, inputs)
session.click(label: "Submit")
fill #
Set the value of an input field. Target by ref, text, or label. Clears existing content first.
# By ref
session.fill("hello@example.com", ref: "input3")
# By label
session.fill("hello@example.com", label: "Email")
# By visible text
session.fill("hello@example.com", text: "Email")
fill_form #
Fill multiple form fields in a single step. Optionally submit the form.
session.fill_form([
{ label: "Email", value: "hello@example.com" },
{ label: "Password", value: "s3cret" }
], submit: true)
extract #
Extract structured data from the page. Define a schema using Ruby keyword arguments.
result = session.extract(
title: "string",
price: "number",
features: ["string"]
)
puts result.extraction
# => { "title" => "Pro Plan", "price" => 29, "features" => ["API access", "Priority support"] }
screenshot #
Capture a screenshot. The image is returned as base64 in media.
result = session.screenshot(full_page: true)
# Save to file
require "base64"
File.write("page.png", Base64.decode64(result.media.first.data))
scroll_collect #
Scroll through the page and collect all content. Useful for infinite-scroll pages.
result = session.scroll_collect(max_scrolls: 10)
puts result.page.markdown.content
close #
Close the browser session and release resources.
session.close
type #
Type text character by character. Useful for inputs with autocomplete or client-side filtering. Target by ref, text, or label.
session.type("search query", ref: "input5", delay: 50)
session.type("hello", label: "Search")
select #
Select a dropdown option by value. Target the select element by ref, text, or label.
session.select("us", label: "Country")
check #
Toggle a checkbox or radio button. Target by ref, text, or label.
session.check(label: "I agree to the terms")
session.check(ref: "cb3", checked: false)
scroll #
Scroll the page or scroll an element into view. Target by ref, text, or label.
session.scroll(to: "bottom")
session.scroll(direction: "down", amount: 500)
session.scroll(text: "Footer section")
wait #
Wait for a duration, CSS selector, visible text, or a JavaScript expression to become truthy.
session.wait(ms: 2000)
session.wait(selector: ".loaded", timeout: 10000)
session.wait(until: "document.querySelectorAll('.item').length > 5")
upload #
Upload files to a file input. Target by ref, text, or label.
session.upload(["https://example.com/file.pdf"], ref: "file1")
session.upload(["https://example.com/photo.jpg"], label: "Upload photo")
pdf #
Generate a PDF of the page. Supports format, landscape, background, scale, and margin options.
result = session.pdf(format: "A4", landscape: true, scale: 0.8,
margin: { top: "1cm", bottom: "1cm" })
require "base64"
File.write("page.pdf", Base64.decode64(result.media.first.data))
execute_js #
Run JavaScript code in the browser. The result is stored in the extraction under the specified key.
result = session.execute_js("return document.title")
puts result.extraction["js_result"]
# With custom result key and timeout
result = session.execute_js("return document.querySelectorAll('a').length",
result_key: "link_count", timeout: 5000)
Session Management #
List, inspect, and destroy sessions through the client.sessions namespace.
List sessions
result = client.sessions.list(status: "active", limit: 10)
result.sessions.each do |s|
puts "#{s.session_id} — #{s.status} — #{s.started_at}"
end
# Pagination
if result.has_more
next_page = client.sessions.list(after: result.next_cursor)
end
Get session info
info = client.sessions.get("ses_abc123")
puts info.status # => "active"
puts info.expires_at # => "2026-03-24T12:00:00Z"
Destroy a session
client.sessions.destroy("ses_abc123")
Error Handling #
All errors inherit from Browserbeam::Error. Each error exposes message, code, status_code, context, and request_id.
| Class | HTTP | When |
|---|---|---|
AuthenticationError | 401 | Invalid or missing API key. |
InvalidRequestError | 400 | Malformed request or invalid parameters. |
SessionNotFoundError | 404 | Session does not exist or has expired. |
RateLimitError | 429 | Too many requests. Check retry_after. |
QuotaExceededError | 429 | Plan quota reached. Check retry_after. |
EngineUnavailableError | 503 | Service temporarily unavailable. Check retry_after. |
StepExecutionError | varies | A step failed. Check step_index and action. |
begin
session = client.sessions.create(url: "https://example.com")
session.click(ref: "missing")
session.close
rescue Browserbeam::RateLimitError => e
puts "Rate limited. Retry after #{e.retry_after}s"
rescue Browserbeam::SessionNotFoundError => e
puts "Session gone: #{e.message}"
rescue Browserbeam::AuthenticationError => e
puts "Bad API key: #{e.message}"
rescue Browserbeam::Error => e
puts "Error [#{e.code}]: #{e.message}"
puts "Request ID: #{e.request_id}"
end
Full Example #
Extract the top stories from Hacker News, search for a topic, and save a screenshot.
require "browserbeam"
require "base64"
require "json"
client = Browserbeam::Client.new
# Navigate to Hacker News
session = client.sessions.create(url: "https://news.ycombinator.com/")
# Extract top stories from the front page
result = session.extract(
stories: [{ "_parent": ".titleline", "title": "a >> text", "url": "a >> href" }]
)
result.extraction["stories"].first(5).each do |story|
puts "#{story['title']} — #{story['url']}"
end
# Fill the search form and submit
session.fill_form({ "q" => "browser automation" }, submit: true)
# Take a screenshot of search results
shot = session.screenshot(full_page: true)
File.write("hn-search.png", Base64.decode64(shot.media.first.data))
session.close
Source code on GitHub. Found an issue? Open a ticket.