Agent skill
browserless
Browserless API for headless Chrome. Use when user mentions "headless Chrome", "browserless", or needs browser automation.
Install this agent skill to your Project
npx add-skill https://github.com/vm0-ai/vm0-skills/tree/main/browserless
SKILL.md
Browserless
Headless Chrome browser as a service. Take screenshots, generate PDFs, scrape JS-rendered pages, and run Puppeteer/Playwright scripts without managing browser infrastructure.
Official docs: https://docs.browserless.io/
When to Use
Use this skill when you need to:
- Scrape JavaScript-heavy pages (React, Vue, Angular)
- Take full-page or element screenshots
- Generate PDFs from web pages
- Execute custom JavaScript in a browser context
- Bypass bot detection with stealth mode
- Run Puppeteer/Playwright scripts in the cloud
Prerequisites
- Create an account at https://www.browserless.io/
- Get your API token from https://account.browserless.io/
Set environment variable:
export BROWSERLESS_TOKEN="your-api-token-here"
How to Use
1. Scrape Data (CSS Selectors)
Extract structured JSON using CSS selectors:
Write to /tmp/browserless_request.json:
{
"url": "https://example.com",
"elements": [
{"selector": "h1"},
{"selector": "p"}
]
}
Then run:
curl -s -X POST "https://production-sfo.browserless.io/scrape?token=$(printenv BROWSERLESS_TOKEN)" --header "Content-Type: application/json" -d @/tmp/browserless_request.json
With wait options:
Write to /tmp/browserless_request.json:
{
"url": "https://news.ycombinator.com",
"elements": [{"selector": ".titleline > a"}],
"gotoOptions": {
"waitUntil": "networkidle2",
"timeout": 30000
}
}
Then run:
curl -s -X POST "https://production-sfo.browserless.io/scrape?token=$(printenv BROWSERLESS_TOKEN)" --header "Content-Type: application/json" -d @/tmp/browserless_request.json | jq '.data[0].results[:3]'
2. Take Screenshots
Full page screenshot:
Write to /tmp/browserless_request.json:
{
"url": "https://example.com",
"options": {
"fullPage": true,
"type": "png"
}
}
Then run:
curl -s -X POST "https://production-sfo.browserless.io/screenshot?token=$(printenv BROWSERLESS_TOKEN)" --header "Content-Type: application/json" -d @/tmp/browserless_request.json --output screenshot.png
Element screenshot:
Write to /tmp/browserless_request.json:
{
"url": "https://example.com",
"options": {
"type": "png"
},
"selector": "h1"
}
Then run:
curl -s -X POST "https://production-sfo.browserless.io/screenshot?token=$(printenv BROWSERLESS_TOKEN)" --header "Content-Type: application/json" -d @/tmp/browserless_request.json --output element.png
With viewport size:
Write to /tmp/browserless_request.json:
{
"url": "https://example.com",
"viewport": {
"width": 1920,
"height": 1080
},
"options": {
"type": "jpeg",
"quality": 80
}
}
Then run:
curl -s -X POST "https://production-sfo.browserless.io/screenshot?token=$(printenv BROWSERLESS_TOKEN)" --header "Content-Type: application/json" -d @/tmp/browserless_request.json --output screenshot.jpg
3. Generate PDF
Write to /tmp/browserless_request.json:
{
"url": "https://example.com",
"options": {
"format": "A4",
"printBackground": true,
"margin": {
"top": "1cm",
"bottom": "1cm"
}
}
}
Then run:
curl -s -X POST "https://production-sfo.browserless.io/pdf?token=$(printenv BROWSERLESS_TOKEN)" --header "Content-Type: application/json" -d @/tmp/browserless_request.json --output page.pdf
4. Get Rendered HTML
Get fully rendered HTML after JavaScript execution:
Write to /tmp/browserless_request.json:
{
"url": "https://example.com",
"gotoOptions": {
"waitUntil": "networkidle0"
}
}
Then run:
curl -s -X POST "https://production-sfo.browserless.io/content?token=$(printenv BROWSERLESS_TOKEN)" --header "Content-Type: application/json" -d @/tmp/browserless_request.json
5. Execute Custom JavaScript (Click, Type, etc.)
Run Puppeteer code with full interaction support:
Click element:
Write to /tmp/browserless_function.js:
export default async ({ page }) => {
await page.goto("https://example.com");
await page.click("a");
return { data: { url: page.url() }, type: "application/json" };
}
Then run:
curl -s -X POST "https://production-sfo.browserless.io/function?token=$(printenv BROWSERLESS_TOKEN)" -H "Content-Type: application/javascript" -d @/tmp/browserless_function.js
Type into input:
Write to /tmp/browserless_function.js:
export default async ({ page }) => {
await page.goto("https://duckduckgo.com");
await page.waitForSelector("input[name=q]");
await page.type("input[name=q]", "hello world");
const val = await page.$eval("input[name=q]", e => e.value);
return { data: { typed: val }, type: "application/json" };
}
Then run:
curl -s -X POST "https://production-sfo.browserless.io/function?token=$(printenv BROWSERLESS_TOKEN)" -H "Content-Type: application/javascript" -d @/tmp/browserless_function.js
Form submission:
Write to /tmp/browserless_function.js:
export default async ({ page }) => {
await page.goto("https://duckduckgo.com");
await page.type("input[name=q]", "test query");
await page.keyboard.press("Enter");
await page.waitForNavigation();
return { data: { title: await page.title() }, type: "application/json" };
}
Then run:
curl -s -X POST "https://production-sfo.browserless.io/function?token=$(printenv BROWSERLESS_TOKEN)" -H "Content-Type: application/javascript" -d @/tmp/browserless_function.js
Extract data with custom script:
Write to /tmp/browserless_function.js:
export default async ({ page }) => {
await page.goto("https://news.ycombinator.com");
const links = await page.$$eval(".titleline > a", els => els.slice(0,5).map(a => ({title: a.innerText, url: a.href})));
return { data: links, type: "application/json" };
}
Then run:
curl -s -X POST "https://production-sfo.browserless.io/function?token=$(printenv BROWSERLESS_TOKEN)" -H "Content-Type: application/javascript" -d @/tmp/browserless_function.js
6. Unblock Protected Sites
Bypass bot detection:
Write to /tmp/browserless_request.json:
{
"url": "https://example.com",
"browserWSEndpoint": false,
"cookies": false,
"content": true,
"screenshot": false
}
Then run:
curl -s -X POST "https://production-sfo.browserless.io/unblock?token=$(printenv BROWSERLESS_TOKEN)" --header "Content-Type: application/json" -d @/tmp/browserless_request.json
7. Stealth Mode
Enable stealth mode to avoid detection:
Write to /tmp/browserless_request.json:
{
"url": "https://example.com",
"elements": [{"selector": "body"}]
}
Then run:
curl -s -X POST "https://production-sfo.browserless.io/scrape?token=$(printenv BROWSERLESS_TOKEN)&stealth=true" --header "Content-Type: application/json" -d @/tmp/browserless_request.json
8. Export Page with Resources
Fetch a URL and get content in native format. Can bundle all resources (CSS, JS, images) as zip:
Basic export:
Write to /tmp/browserless_request.json:
{
"url": "https://example.com"
}
Then run:
curl -s -X POST "https://production-sfo.browserless.io/export?token=$(printenv BROWSERLESS_TOKEN)" --header "Content-Type: application/json" -d @/tmp/browserless_request.json --output page.html
Export with all resources as ZIP:
Write to /tmp/browserless_request.json:
{
"url": "https://example.com",
"includeResources": true
}
Then run:
curl -s -X POST "https://production-sfo.browserless.io/export?token=$(printenv BROWSERLESS_TOKEN)" --header "Content-Type: application/json" -d @/tmp/browserless_request.json --output webpage.zip
9. Performance Audit (Lighthouse)
Run Lighthouse audits for accessibility, performance, SEO, best practices:
Full audit:
Write to /tmp/browserless_request.json:
{
"url": "https://example.com"
}
Then run:
curl -s -X POST "https://production-sfo.browserless.io/performance?token=$(printenv BROWSERLESS_TOKEN)" --header "Content-Type: application/json" -d @/tmp/browserless_request.json | jq '.data.categories | to_entries[] | {category: .key, score: .value.score}'
Specific category (accessibility, performance, seo, best-practices, pwa):
Write to /tmp/browserless_request.json:
{
"url": "https://example.com",
"config": {
"extends": "lighthouse:default",
"settings": {
"onlyCategories": ["performance"]
}
}
}
Then run:
curl -s -X POST "https://production-sfo.browserless.io/performance?token=$(printenv BROWSERLESS_TOKEN)" --header "Content-Type: application/json" -d @/tmp/browserless_request.json | jq '.data.audits | to_entries[:5][] | {audit: .key, score: .value.score, display: .value.displayValue}'
Specific audit (e.g., unminified-css, first-contentful-paint):
Write to /tmp/browserless_request.json:
{
"url": "https://example.com",
"config": {
"extends": "lighthouse:default",
"settings": {
"onlyAudits": ["first-contentful-paint", "largest-contentful-paint"]
}
}
}
Then run:
curl -s -X POST "https://production-sfo.browserless.io/performance?token=$(printenv BROWSERLESS_TOKEN)" --header "Content-Type: application/json" -d @/tmp/browserless_request.json | jq '.data.audits'
10. Create Persistent Session
Create a persistent browser session that can be connected to via WebSocket:
Write to /tmp/browserless_request.json:
{
"ttl": 300000,
"stealth": false,
"headless": true
}
Then run:
curl -s -X POST "https://production-sfo.browserless.io/session?token=$(printenv BROWSERLESS_TOKEN)" --header "Content-Type: application/json" -d @/tmp/browserless_request.json
Response includes:
id- Session ID for subsequent operationsconnect- WebSocket URL for Puppeteer/Playwright connectionstop- Full URL to stop/delete the session (use this exact URL)browserQL- BrowserQL query endpointttl- Time-to-live in milliseconds (default: 300000 = 5 minutes)
Use the session with Puppeteer:
const puppeteer = require('puppeteer-core');
const browser = await puppeteer.connect({
browserWSEndpoint: '<connect-url-from-response>' // Use the 'connect' URL from response
});
11. Stop Persistent Session
Stop a running session before its timeout expires using the stop URL from the creation response:
curl -s -X DELETE "<stop-url-from-response>"
Example (replace <stop-url-from-response> with the actual stop URL from session creation):
curl -s -X DELETE "https://production-sfo.browserless.io/e/<encoded-path>/session/<session-id>?token=<your-token>"
Response:
{
"success": true,
"message": "Session <session-id> was successfully removed",
"sessionId": "<session-id>",
"timestamp": "2026-01-01T07:41:36.933Z"
}
API Endpoints
| Endpoint | Method | Description |
|---|---|---|
/scrape |
POST | Extract data with CSS selectors |
/screenshot |
POST | Capture screenshots (PNG/JPEG) |
/pdf |
POST | Generate PDF documents |
/content |
POST | Get rendered HTML |
/function |
POST | Execute custom Puppeteer code |
/unblock |
POST | Bypass bot protection |
/export |
POST | Export page with resources as ZIP |
/performance |
POST | Lighthouse audits (a11y, perf, SEO) |
/session |
POST | Create persistent browser session |
/session/{id} |
DELETE | Stop persistent session |
Common Options
gotoOptions
Control page navigation:
{
"gotoOptions": {
"waitUntil": "networkidle2",
"timeout": 30000
}
}
waitUntil values:
load- Wait for load eventdomcontentloaded- Wait for DOMContentLoadednetworkidle0- No network connections for 500msnetworkidle2- Max 2 network connections for 500ms
waitFor Options
{
"waitForTimeout": 1000,
"waitForSelector": {"selector": ".loaded", "timeout": 5000},
"waitForFunction": {"fn": "() => document.ready", "timeout": 5000}
}
Viewport
{
"viewport": {
"width": 1920,
"height": 1080,
"deviceScaleFactor": 2
}
}
Query Parameters
| Parameter | Description |
|---|---|
token |
API token (required) |
stealth |
Enable stealth mode (true/false) |
blockAds |
Block advertisements |
proxy |
Use proxy server |
Response Format
Scrape response:
{
"data": [
{
"selector": "h1",
"results": [
{
"text": "Example Domain",
"html": "Example Domain",
"attributes": [{"name": "class", "value": "title"}],
"width": 400,
"height": 50,
"top": 100,
"left": 50
}
]
}
]
}
Guidelines
- waitUntil: Use
networkidle2for most pages,networkidle0for SPAs - Timeouts: Default is 30s; increase for slow pages
- Stealth Mode: Enable for sites with bot detection
- Screenshots: Use
jpegwith quality 80 for smaller files - Rate Limits: Check your plan limits at https://account.browserless.io/
- Regions: Use region-specific endpoints for better latency:
production-sfo.browserless.io(US West)production-lon.browserless.io(Europe)
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
brave-search
Brave Search API for web search. Use when user says "search web", "Brave search", or asks to "find on web" without specifying Google.
supadata
Supadata API for YouTube/web data. Use when user mentions "Supadata", "YouTube data", "channel stats", or web scraping data.
roadmap-planning
Build and prioritize product roadmaps using scoring models like RICE, ICE, and value-effort matrices. Activate when creating a product roadmap, prioritizing features, sequencing initiatives, mapping dependencies, balancing team capacity, choosing between Now/Next/Later or quarterly planning, or communicating roadmap tradeoffs to executives and stakeholders.
qdrant
Qdrant API for vector search. Use when user mentions "Qdrant", "vector database", "semantic search", or embeddings storage.
calendly
Calendly scheduling API. Use when user mentions "Calendly", "calendly.com", "schedule a meeting", "booking link", "event types", or asks about interview scheduling.
stripe
Stripe API for payments. Use when user mentions "Stripe", "payment", "subscription", "billing", "invoice", or asks about payment processing.
Didn't find tool you were looking for?