REST API & Automation Node Reference Guide
Complete REST, WebSocket, and MCP API documentation for BrowserMesh. Explore endpoints for browser pooling, local node routing, and workflow telemetry.
The BrowserMesh REST API provides programmatic control over your distributed browser automation fleet. You can dispatch automation workflows, poll real-time node telemetry, retrieve structured dataset results, and spin up remote debugging sessions without touching the graphical Cloud Dashboard.
All API requests communicate over HTTPS with JSON request and response payloads. The API is designed around RESTful resource conventions and incorporates strict rate-limiting guardrails to protect your local device nodes.
Authentication & API Keys
Every request to the BrowserMesh API requires authentication using an API bearer token passed in the standard Authorization HTTP header.
curl -X GET "https://api.browsermesh.in/v1/nodes" \
-H "Authorization: Bearer bm_live_your_api_key_here" \
-H "Content-Type: application/json"
You can generate, revoke, and rotate API keys directly from the Settings > Developer Settings panel in your Cloud Studio. We recommend maintaining separate keys for production workflow dispatchers and local development environments.
How Do Developers Integrate with the BrowserMesh REST API?
The BrowserMesh REST API enables developers and CI/CD pipelines to programmatically provision automation nodes, dispatch dynamic scraping jobs, observe real-time execution status, and retrieve extracted JSON datasets. All API requests authenticate using standard Bearer tokens over secure HTTPS connections with predictable JSON error responses.
What Endpoints Are Available for Fleet Management and Task Execution?
Core API endpoints include node fleet inventory management, asynchronous workflow execution dispatchers, real-time job status polling, and encrypted result retrieval endpoints. Each resource provides full pagination parameters, RFC-compliant HTTP status codes, and deterministic schema responses for seamless integration with custom backend architectures.
1. List Fleet Nodes
GET /v1/nodes
Returns an inventory of all active physical and virtual automation nodes linked to your account.
Query Parameters:
status(string, optional): Filter byonline,busy, oroffline.os(string, optional): Filter by operating system (windows,linux,android).limit(integer, optional): Maximum results to return (default:20, max:100).
Example Response:
{
"nodes": [
{
"id": "node_win_89f2a1b",
"name": "Office-Workstation-01",
"os": "windows",
"version": "1.4.0",
"status": "online",
"ipType": "residential",
"activeTabs": 2,
"maxConcurrency": 5,
"cpuUsage": 18.4,
"memoryAvailableMb": 12450,
"lastHeartbeat": "2026-10-27T12:00:00Z"
}
],
"total": 1
}
2. Dispatch Automation Job
POST /v1/jobs
Dispatches a new browser automation task to the optimal connected device node.
Request Payload:
{
"url": "https://example.com/products/catalog",
"workflow": "ecommerce-catalog-extractor",
"nodeId": "node_win_89f2a1b",
"stealth": true,
"timeout": 30000,
"options": {
"waitForSelector": ".product-card",
"extractPagination": true,
"maxPages": 5
}
}
Parameters Explained:
url(string, required): The target webpage URL to navigate and automate.workflow(string, required): The marketplace workflow identifier or custom plugin slug.nodeId(string, optional): Specify a target node. If omitted, the scheduler assigns the task to the least-utilized online node.stealth(boolean, optional): Enables AutomationEngine anti-bot evasion and canvas fingerprint masking (default:true).timeout(integer, optional): Maximum runtime in milliseconds before aborting (default:30000).
Response (HTTP 202 Accepted):
{
"jobId": "job_e71b83d9",
"status": "queued",
"assignedNode": "node_win_89f2a1b",
"estimatedWaitMs": 150,
"createdAt": "2026-10-27T12:05:00Z"
}
3. Check Job Status
GET /v1/jobs/:jobId
Poll the real-time execution status, progress percentage, and memory footprint of an active automation task.
Response (HTTP 200 OK):
{
"jobId": "job_e71b83d9",
"status": "completed",
"progress": 100,
"durationMs": 4820,
"extractedRecords": 48,
"exitCode": 0,
"completedAt": "2026-10-27T12:05:05Z"
}
4. Retrieve Extracted Results
GET /v1/jobs/:jobId/results
Downloads the structured dataset generated by the completed workflow.
Query Parameters:
format(string, optional): Desired serialization format (json,csv,xlsx). Defaults tojson.
Response (HTTP 200 OK):
{
"jobId": "job_e71b83d9",
"url": "https://example.com/products/catalog",
"recordCount": 2,
"data": [
{
"title": "Ultra-Light Laptop Pro 15",
"price": "999.00",
"currency": "USD",
"inStock": true,
"sku": "LAP-991"
},
{
"title": "Wireless Noise-Cancelling Headphones",
"price": "199.50",
"currency": "USD",
"inStock": true,
"sku": "AUD-442"
}
]
}
Code Examples
TypeScript / Node.js Implementation
import axios from "axios";
const API_KEY = process.env.BROWSERMESH_API_KEY || "bm_live_your_key";
const client = axios.create({
baseURL: "https://api.browsermesh.in/v1",
headers: {
Authorization: `Bearer ${API_KEY}`,
"Content-Type": "application/json",
},
timeout: 45000,
});
async function runAutomation() {
try {
// 1. Dispatch Job
const dispatchRes = await client.post("/jobs", {
url: "https://news.ycombinator.com",
workflow: "generic-content-extractor",
stealth: true,
});
const { jobId } = dispatchRes.data;
console.log(`Job queued: ${jobId}`);
// 2. Poll for Completion
let completed = false;
while (!completed) {
await new Promise((r) => setTimeout(r, 2000));
const statusRes = await client.get(`/jobs/${jobId}`);
if (statusRes.data.status === "completed") {
completed = true;
} else if (statusRes.data.status === "failed") {
throw new Error(`Job execution failed: ${statusRes.data.error}`);
}
}
// 3. Fetch Structured Results
const resultsRes = await client.get(`/jobs/${jobId}/results?format=json`);
console.log("Scraped Data:", resultsRes.data.data);
} catch (error) {
console.error("API Error:", error);
}
}
runAutomation();
Python Implementation
import time
import requests
API_KEY = "bm_live_your_key"
HEADERS = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}
BASE_URL = "https://api.browsermesh.in/v1"
def trigger_browser_workflow(target_url: str):
payload = {
"url": target_url,
"workflow": "ecommerce-catalog-extractor",
"stealth": True
}
response = requests.post(f"{BASE_URL}/jobs", json=payload, headers=HEADERS)
response.raise_for_status()
job_id = response.json()["jobId"]
print(f"Dispatched job {job_id}")
# Polling loop
while True:
time.sleep(2)
status_res = requests.get(f"{BASE_URL}/jobs/{job_id}", headers=HEADERS)
status_data = status_res.json()
if status_data["status"] == "completed":
break
elif status_data["status"] == "failed":
raise RuntimeError("Workflow failed during execution")
results_res = requests.get(f"{BASE_URL}/jobs/{job_id}/results", headers=HEADERS)
return results_res.json()
if __name__ == "__main__":
records = trigger_browser_workflow("https://example.com/store")
print(f"Retrieved {records['recordCount']} items")
HTTP Status Codes & Error Responses
Related Developer & Platform Resources
- Deploy Your First Node: Download Client Apps (
/download) - Explore 250+ Workflow Templates: Browse Marketplace (
/marketplace) - Pricing & API Limits: Transparent Pricing Plans (
/pricing) - Custom Playwright Workflows: Playwright SDK Guide (
/docs/playwright) - Engine Architecture: AutomationEngine Features (
/features) - Writing DOM Selectors: Resilient Selectors Guide (
/docs/writing-selectors)