API Reference

Give LLMs and agents a real browser they can see and control.

Base URL https://api.browserbeam.com
Auth Authorization: Bearer sk_live_...
Format JSON request and response bodies

Endpoints

Method Path Description
POST/v1/sessionsCreate a browser session
GET/v1/sessions/:idGet session info
POST/v1/sessions/:id/actExecute steps on a session
DELETE/v1/sessions/:idDestroy a session
GET/v1/sessionsList active sessions

Key concepts

Session — an isolated browser tab with its own cookies, storage, and viewport. Billed by runtime (seconds between create and destroy).

Steps — sequential browser actions (click, fill, extract, etc.) sent as a JSON array. On failure, execution stops and the error is returned alongside current page state.

Refs — stable element identifiers (e1, e2, …) assigned during observation. Use refs to target elements in follow-up steps.

Auto-observe — every successful call returns fresh page state automatically: content, interactive elements with refs, scroll position, and a diff of what changed.

Quick Start

Create a session, navigate to a page, and get its content — all in one call:

POST/v1/sessionsRequest
{
  "url": "https://example.com"
}
201CreatedResponse
{
  "session_id": "ses_abc123",
  "expires_at": "2026-03-18T14:05:00Z",
  "completed": 1,
  "page": {
    "url": "https://example.com",
    "title": "Example Domain",
    "stable": true,
    "markdown": {
      "content": "# Example Domain\n\nThis domain is for use in illustrative examples..."
    },
    "interactive_elements": [
      {
        "ref": "e1",
        "tag": "a",
        "role": "link",
        "label": "More information..."
      }
    ],
    "forms": [],
    "changes": null,
    "scroll": {
      "y": 0,
      "height": 600,
      "viewport": 720,
      "percent": 100
    }
  },
  "screenshots": [],
  "blockers_dismissed": ["cookie_consent"],
  "error": null
}

Use the element refs to interact with the page:

POST/v1/sessions/ses_abc123/actRequest
{
  "steps": [
    {"click": {"ref": "e1"}}
  ]
}
200OKResponse
{
  "completed": 1,
  "page": {
    "url": "https://www.iana.org/help/example-domains",
    "title": "IANA — Example Domains",
    "stable": true,
    "markdown": {
      "content": "# IANA — Example Domains\n\n..."
    },
    "interactive_elements": [
      {"ref": "e1", "tag": "a", "role": "link", "label": "Home"},
      {"ref": "e2", "tag": "a", "role": "link", "label": "Domains"}
    ],
    "changes": {
      "content_changed": true,
      "elements_added": [{"ref": "e1"}, {"ref": "e2"}],
      "elements_removed": []
    }
  },
  "screenshots": [],
  "blockers_dismissed": [],
  "error": null
}

Destroy the session when done:

DELETE/v1/sessions/ses_abc123Request
# No request body
204No ContentResponse
# Empty response

Authentication

Every request requires an API key in the Authorization header:

Authorization: Bearer sk_live_your_api_key

Get your API key from the dashboard. Keys are prefixed sk_live_ for production and sk_test_ for sandbox.

Missing or invalid keys return 401:

401UnauthorizedResponse
{
  "error": {
    "code": "unauthorized",
    "message": "Invalid API key"
  }
}

POST /v1/sessions

Create a browser session. Optionally navigate to a URL and execute steps in the same call.

Parameters (all optional)

ParamTypeDefaultDescription
urlstringNavigate to this URL after creation
stepsarraySteps to execute after navigation
timeoutinteger300Session lifetime in seconds (10–1800)
viewportobject{1280, 720}{width, height}
user_agentstringCustom User-Agent string
localestringBrowser locale (e.g. en-US)
timezonestringTimezone (e.g. America/New_York)
proxystringProxy URL (e.g. http://user:pass@proxy:8080)
block_resourcesarrayimage, font, media, stylesheet, script
auto_dismiss_blockersbooleantrueAuto-dismiss cookie banners and popups

Behavior

urlstepsResult
Bare session, no page loaded
setNavigate → auto-observe → page state returned
setsetNavigate → run steps → auto-observe
setRun steps (first should be goto)

Example — navigate to a page

POST/v1/sessionsRequest
{
  "url": "https://example.com"
}
201CreatedResponse
{
  "session_id": "ses_abc123",
  "expires_at": "2026-03-18T14:05:00Z",
  "completed": 1,
  "page": {
    "url": "https://example.com",
    "title": "Example Domain",
    "stable": true,
    "markdown": {
      "content": "# Example Domain\n\nThis domain is for use in illustrative examples..."
    },
    "interactive_elements": [
      {
        "ref": "e1",
        "tag": "a",
        "role": "link",
        "label": "More information..."
      }
    ],
    "forms": [],
    "changes": null,
    "scroll": {
      "y": 0,
      "height": 600,
      "viewport": 720,
      "percent": 100
    }
  },
  "screenshots": [],
  "blockers_dismissed": ["cookie_consent"],
  "error": null
}

Example — navigate + steps in one call

POST/v1/sessionsRequest
{
  "url": "https://example.com/login",
  "steps": [
    {
      "fill_form": {
        "fields": {
          "Email": "user@test.com",
          "Password": "secret"
        },
        "submit": true
      }
    },
    {"screenshot": {}},
    {"close": {}}
  ]
}
201CreatedResponse
{
  "session_id": "ses_def456",
  "expires_at": "2026-03-18T14:05:00Z",
  "completed": 3,
  "page": {
    "url": "https://example.com/dashboard",
    "title": "Dashboard",
    "stable": true,
    "markdown": {
      "content": "# Welcome back\n\nYou have 3 new notifications..."
    },
    "interactive_elements": [
      {"ref": "e1", "tag": "a", "role": "link", "label": "Notifications"},
      {"ref": "e2", "tag": "button", "label": "Logout"}
    ],
    "changes": {
      "content_changed": true,
      "elements_added": [{"ref": "e1"}, {"ref": "e2"}],
      "elements_removed": []
    },
    "scroll": {
      "y": 0,
      "height": 1200,
      "viewport": 720,
      "percent": 60
    }
  },
  "screenshots": [
    {
      "format": "png",
      "data": ""
    }
  ],
  "blockers_dismissed": [],
  "error": null
}

Example — session with custom options

POST/v1/sessionsRequest
{
  "url": "https://example.com",
  "timeout": 600,
  "viewport": {
    "width": 1920,
    "height": 1080
  },
  "locale": "en-US",
  "timezone": "America/New_York",
  "block_resources": ["image", "font"],
  "auto_dismiss_blockers": true
}

GET /v1/sessions/:id

Get session status and metadata from the database.

GET/v1/sessions/ses_abc123Request
# No request body
200OKResponse
{
  "session_id": "ses_abc123",
  "status": "active",
  "started_at": "2026-03-18T13:55:00Z",
  "ended_at": null,
  "duration_seconds": null,
  "worker": "81.17.98.100:3001"
}

Response fields

FieldTypeDescription
session_idstringSession identifier
statusstringactive or ended
started_atstringISO 8601 creation timestamp
ended_atstring|nullISO 8601 end timestamp, or null if active
duration_secondsinteger|nullTotal runtime in seconds, or null if active
workerstringEngine worker host:port

POST /v1/sessions/:id/act

Execute steps on an existing session. Steps run sequentially. On failure, execution stops and the error is returned alongside current page state. Auto-observe runs at the end.

POST/v1/sessions/ses_abc123/actRequest
{
  "steps": [
    {
      "fill": {
        "ref": "e1",
        "value": "search query"
      }
    },
    {"click": {"ref": "e3"}},
    {"screenshot": {}}
  ]
}
200OKResponse
{
  "completed": 3,
  "page": {
    "url": "https://example.com/results?q=search+query",
    "title": "Search Results",
    "stable": true,
    "markdown": {
      "content": "# Search Results\n\n## 1. First result..."
    },
    "interactive_elements": [
      {
        "ref": "e1",
        "tag": "input",
        "role": "search",
        "label": "Search",
        "value": "search query"
      },
      {"ref": "e2", "tag": "a", "role": "link", "label": "First result"},
      {"ref": "e3", "tag": "a", "role": "link", "label": "Second result"}
    ],
    "forms": [],
    "changes": {
      "content_changed": true,
      "elements_added": [{"ref": "e2"}, {"ref": "e3"}],
      "elements_removed": []
    },
    "scroll": {
      "y": 0,
      "height": 3000,
      "viewport": 720,
      "percent": 24
    }
  },
  "screenshots": [
    {
      "format": "png",
      "data": ""
    }
  ],
  "blockers_dismissed": [],
  "error": null
}

DELETE /v1/sessions/:id

Destroy a session and release browser resources. Runtime is recorded for billing.

DELETE/v1/sessions/ses_abc123Request
# No request body
204No ContentResponse
# Empty response — session destroyed

Always destroy sessions when done. This frees resources and stops the billing clock. Sessions also auto-expire based on their timeout.

GET /v1/sessions

List all your active sessions.

GET/v1/sessionsRequest
# No request body
200OKResponse
{
  "sessions": [
    {
      "session_id": "ses_abc123",
      "status": "active",
      "started_at": "2026-03-18T13:55:00Z",
      "worker": "81.17.98.100:3001"
    },
    {
      "session_id": "ses_def456",
      "status": "active",
      "started_at": "2026-03-18T14:00:00Z",
      "worker": "81.17.98.100:3002"
    }
  ]
}

Step Types

Each step is a JSON object with one key (the step type) and its params as the value. Send steps in the steps array of a create or act call.

Steps execute sequentially. On failure, execution stops and the error is returned. An auto-observe runs at the end of every call.

goto

Navigate to a URL. Waits for page load and stability checks.

ParamTypeRequiredDefaultDescription
urlstringyesURL to navigate to
wait_forstringnoCSS selector to wait for
wait_timeoutintegerno10000Max ms to wait for selector
{"goto": {"url": "https://example.com"}}

{"goto": {"url": "https://example.com", "wait_for": "#main-content", "wait_timeout": 15000}}

On failure (DNS error, timeout, SSL), returns error code navigation_failed.

observe

Force a page observation. Auto-observe runs at the end of every call, so explicit observe is only needed to change format or scope mid-pipeline.

ParamTypeDefaultDescription
formatstringmarkdownmarkdown or html
scopestringCSS selector to limit observation
include_linksbooleanfalseInclude links as interactive elements
max_text_lengthinteger12000Content length limit
{"observe": {}}

{"observe": {"format": "html"}}

{"observe": {"scope": "#content", "include_links": true}}

click

Click an element. Exactly one targeting param required (see Element Targeting).

{"click": {"ref": "e3"}}

{"click": {"text": "Submit"}}

{"click": {"label": "Sign in"}}

fill

Clear and replace the value of an input. For character-by-character typing, use type instead.

{"fill": {"ref": "e1", "value": "hello world"}}

{"fill": {"label": "Email", "value": "user@example.com"}}

type

Type character-by-character with a delay. Use for autocomplete and search-as-you-type inputs.

ParamTypeDefaultDescription
valuestringRequired — text to type
delayinteger50Milliseconds between keystrokes
{
  "type": {
    "label": "Search",
    "value": "browserbeam api",
    "delay": 100
  }
}

select

Select an option from a <select> dropdown.

{"select": {"label": "Country", "value": "US"}}

{"select": {"ref": "e4", "value": "option_value"}}

check

Check or uncheck a checkbox/radio button.

{"check": {"label": "Remember me"}}

{"check": {"label": "Terms", "checked": false}}

scroll

Scroll the page or scroll an element into view.

ParamTypeDefaultDescription
tostringbottom or top
directionstringup or down
amountinteger500Pixels per scroll step
timesinteger1Repeat scroll N times
{"scroll": {"to": "bottom"}}

{"scroll": {"direction": "down", "amount": 500, "times": 3}}

{"scroll": {"ref": "e6"}}

scroll_collect

Scroll through the entire page, wait for lazy-loaded content at each position, and return a unified observation. Ideal for infinite scroll and long pages.

ParamTypeDefaultDescription
max_scrollsinteger50Safety limit on scroll iterations
wait_msinteger500Pause between scrolls (ms)
timeout_msinteger60000Total time budget (ms)
max_text_lengthinteger100000Content length limit
{"scroll_collect": {}}

{"scroll_collect": {"max_scrolls": 30, "max_text_length": 50000}}

screenshot

Capture a screenshot. Base64 data appears in the screenshots array of the response.

ParamTypeDefaultDescription
full_pagebooleanfalseFull scrollable page
selectorstringCSS selector to screenshot a specific element
formatstringpngpng or jpeg
qualityinteger80JPEG quality (1–100)
{"screenshot": {}}

{"screenshot": {"full_page": true, "format": "jpeg", "quality": 80}}

{"screenshot": {"selector": "#chart"}}

wait

Wait for a condition. Exactly one of ms, selector, or text is required.

{"wait": {"ms": 2000}}

{"wait": {"selector": "#results", "timeout": 10000}}

{"wait": {"text": "Loading complete", "timeout": 5000}}

extract

Structured data extraction. Keys are your field names, values are CSS/XPath selectors. Results appear in the extraction object of the response.

Selector syntax

// Pattern: "selector >> function"
// Functions: text, href (any attr), json, or omit for raw HTML

"title":      "h1 >> text"
"link":       "a.main >> href"
"image":      "img.hero >> src"
"meta":       "meta[name=description] >> content"
"html_block": "div.content"

Arrays

// Wrap in [ ] to collect all matches
"all_links": ["a >> href"]
"headings":  ["h2 >> text"]

Repeating structures

// Use [{_parent}] for repeating items like product cards
"products": [
  {
    "_parent": ".product-card",
    "name":    "h2 >> text",
    "price":   ".price >> text",
    "url":     "a >> href"
  }
]

Tables

// Tables are auto-parsed into arrays using headers as keys
"people": "table.contacts"
// → [{"Name": "Alice", "Email": "alice@example.com"}, ...]

JavaScript expressions

// Use js >> prefix to run JavaScript in the browser
"count": "js >> document.querySelectorAll('.item').length"
"title": "js >> document.querySelector('h1').textContent.trim()"

Full example

POST/v1/sessionsRequest
{
  "url": "https://example.com/products",
  "steps": [
    {
      "extract": {
        "page_title": "h1 >> text",
        "description": "meta[name=description] >> content",
        "nav_links": ["nav a >> text"],
        "articles": [
          {
            "_parent": ".article-card",
            "title": "h2 >> text",
            "url": "a >> href",
            "author": ".byline >> text"
          }
        ],
        "stats_table": "table.statistics"
      }
    },
    {"close": {}}
  ]
}
201CreatedResponse
{
  "session_id": "ses_xyz789",
  "completed": 2,
  "page": { "..." : "..." },
  "extraction": {
    "page_title": "Our Products",
    "description": "Browse our full catalog",
    "nav_links": ["Home", "Products", "About", "Contact"],
    "articles": [
      {
        "title": "Widget Pro",
        "url": "https://example.com/widget-pro",
        "author": "Jane"
      },
      {
        "title": "Gadget X",
        "url": "https://example.com/gadget-x",
        "author": "John"
      }
    ],
    "stats_table": [
      {"Product": "Widget Pro", "Sales": "1,234", "Rating": "4.8"},
      {"Product": "Gadget X", "Sales": "567", "Rating": "4.5"}
    ]
  },
  "screenshots": [],
  "error": null
}

fill_form

Fill multiple form fields by label and optionally submit. Auto-detects field types (text, select, checkbox).

ParamTypeRequiredDefaultDescription
fieldsobjectyes{label: value} pairs
submitbooleannofalseAuto-click submit button
{
  "fill_form": {
    "fields": {
      "Email": "user@example.com",
      "Password": "secret",
      "Country": "US",
      "Remember me": true
    },
    "submit": true
  }
}

upload

Upload files to a file input. Downloads from provided URLs and attaches them.

{
  "upload": {
    "ref": "e5",
    "files": ["https://example.com/doc.pdf"]
  }
}

{
  "upload": {
    "label": "Resume",
    "files": ["https://example.com/resume.pdf"]
  }
}

pdf

Generate a PDF of the current page. Base64 data in screenshots array with format: "pdf".

ParamTypeDefaultDescription
formatstringA4Paper size (A4, Letter, Legal)
landscapebooleanfalseLandscape orientation
print_backgroundbooleantrueInclude backgrounds
scalenumber1Scale factor (0.1–2)
marginobject{top, right, bottom, left} in CSS units
{"pdf": {}}

{
  "pdf": {
    "format": "A4",
    "landscape": true,
    "margin": {
      "top": "1cm",
      "bottom": "1cm"
    }
  }
}

close

Destroy the session at the end of step execution. Must be the last step. Useful for fire-and-forget workflows.

{"close": {}}

Element Targeting

Steps that interact with elements (click, fill, type, select, check, scroll, upload) accept exactly one targeting param:

KeyExampleBest for
ref"ref": "e3"Known elements from prior observe — most precise
text"text": "Submit"Buttons and links by visible text
label"label": "Email"Input fields by label/placeholder/aria-label

Label matching checks (in order): aria-label, placeholder, associated <label>, name attribute, nearby text.

Response Format

Create and act calls return the same response structure. Create also includes session_id and expires_at.

FieldTypeDescription
session_idstringSession ID (create only)
expires_atstringISO 8601 expiry (create only)
completedintegerNumber of steps successfully executed
pageobject|nullCurrent page state (see below)
page.urlstringCurrent URL
page.titlestringPage title
page.stablebooleanPage passed stability checks
page.markdownobject{content, length?} — page content
page.interactive_elementsarrayElements with assigned refs
page.formsarrayDetected form structures
page.changesobject|nullDiff from previous observe. null on first.
page.scrollobject{y, height, viewport, percent}
screenshotsarray{format, data} objects (base64)
extractionobjectPresent when extract steps are used
blockers_dismissedarrayAuto-dismissed blockers (e.g. cookie_consent)
errorobject|nullnull on success. On failure: error details.

Errors

All errors follow a consistent JSON format. On step failure, the response includes both the error and the current page state so you can decide what to do next:

200OK — with step errorResponse
{
  "completed": 1,
  "page": {
    "url": "https://example.com",
    "title": "Example Domain",
    "interactive_elements": ["..."]
  },
  "screenshots": [],
  "error": {
    "step": 1,
    "action": "click",
    "code": "element_not_found",
    "message": "No visible element found matching text \"Submit\"",
    "context": {}
  }
}

HTTP errors

StatusCodeWhen
401unauthorizedMissing or invalid API key
403quota_exceededRuntime quota exhausted
404session_not_foundSession doesn't exist or expired
429rate_limitedToo many requests
503engine_unavailableBrowser engine temporarily down

HTTP error examples

403ForbiddenResponse
{
  "error": {
    "code": "quota_exceeded",
    "message": "Runtime quota exceeded. Upgrade your plan or wait for the next billing cycle."
  }
}
429Too Many RequestsResponse
{
  "error": {
    "code": "rate_limited",
    "message": "Rate limit exceeded. Retry after a moment."
  }
}

Step error codes

CodeDescription
element_not_foundNo visible element matches the target
navigation_failedGoto failed (timeout, DNS, SSL, etc.)
captcha_detectedCAPTCHA detected on page
action_failedElement detached, intercepted, etc.
extract_failedExtraction step failed
invalid_requestUnknown step type or invalid params

Rate Limits & Quotas

Limits depend on your plan. Runtime is metered by session duration — the seconds between create and destroy.

PlanRuntime / moConcurrentMax SessionRate Limit
Trial1 hour15 min60 req/min
Starter100 hours2515 min600 req/min
Pro500 hours10030 min1,200 req/min
Scale1,500 hours20060 min3,000 req/min

Workflows

Common patterns showing how to combine sessions and steps.

Explore then act — 2 calls

Get page state first, then use element refs to interact.

POST/v1/sessionsStep 1
{
  "url": "https://example.com"
}
POST/v1/sessions/ses_abc123/actStep 2
{
  "steps": [
    {"fill": {"ref": "e1", "value": "search query"}},
    {"click": {"ref": "e3"}}
  ]
}

Login + screenshot — 1 call

Fill a login form, take a screenshot, destroy the session — all at once.

POST/v1/sessionsRequest
{
  "url": "https://example.com/login",
  "steps": [
    {
      "fill_form": {
        "fields": {
          "Email": "user@test.com",
          "Password": "pass"
        },
        "submit": true
      }
    },
    {"wait": {"ms": 2000}},
    {"screenshot": {"full_page": true}},
    {"close": {}}
  ]
}

Full-page scrape — 1 call

Scroll through the entire page, collecting all lazy-loaded content.

POST/v1/sessionsRequest
{
  "url": "https://example.com/long-article",
  "steps": [
    {"scroll_collect": {"max_text_length": 50000}}
  ]
}

Structured extraction — 1 call

Extract structured data and close the session in one request.

POST/v1/sessionsRequest
{
  "url": "https://example.com/products",
  "steps": [
    {
      "extract": {
        "products": [
          {
            "_parent": ".product",
            "name": "h2 >> text",
            "price": ".price >> text",
            "url": "a >> href"
          }
        ]
      }
    },
    {"close": {}}
  ]
}

PDF generation — 1 call

Generate a PDF and close the session.

POST/v1/sessionsRequest
{
  "url": "https://example.com/report",
  "steps": [
    {
      "pdf": {
        "format": "A4",
        "landscape": true
      }
    },
    {"close": {}}
  ]
}

Search + extract — 2 calls

Navigate, perform a search, then extract results.

POST/v1/sessionsStep 1
{
  "url": "https://example.com",
  "steps": [
    {"fill": {"label": "Search", "value": "browser automation"}},
    {"click": {"text": "Search"}}
  ]
}
POST/v1/sessions/ses_abc123/actStep 2
{
  "steps": [
    {
      "extract": {
        "results": [
          {
            "_parent": ".result",
            "title": "h3 >> text",
            "url": "a >> href"
          }
        ]
      }
    },
    {"close": {}}
  ]
}

Give your AI agent a faster, leaner browser

Structured page data instead of raw HTML. Your agent processes less, decides faster, and costs less to run.

Stability detection built in
Fraction of the payload size
Diffs after every action
No credit card required. 1 hour of free runtime included.