Points Controlled Browser
The Points Controlled Browser lets AI operators control a real browser session from within a code point. Built on ArcSurf — MelodyArc's browser automation service — it runs a full Playwright-backed Chromium, Firefox, or WebKit instance that your code can navigate, interact with, and extract content from.
This fills a gap that API integrations cannot: websites that have no API, pages that require a login flow before exposing data, and content rendered dynamically by JavaScript that isn't present in a raw HTTP response.
When to use it
Use the Points Controlled Browser when a task requires information or actions that aren't reachable through a standard API integration:
| Scenario | Example |
|---|---|
| No public API | A supplier portal publishes inventory updates only on a web dashboard |
| JavaScript-rendered pages | Pricing or availability data is loaded dynamically and absent from the raw HTML |
| Multi-step web workflows | Submitting a form, waiting for a confirmation page, then extracting a reference number |
| Visual capture | Taking a screenshot of a report or dashboard to attach to a task |
For straightforward data retrieval over a documented API, use a standard fetch call in a code point instead — the browser adds overhead that isn't necessary when an API is available.
How it works
ArcSurf runs as a separate service alongside the MelodyArc platform. When a code point calls the browser helper, the following happens:
- A temporary browser session is created (Chromium by default).
- The Point Engine executes your command sequence — navigating pages, interacting with elements, extracting content.
- Results, screenshots, and any captured HTML are returned to the code point and written to the data token.
- The session is torn down automatically. Sessions also expire after 15 minutes if not explicitly closed.
The browser runs headless by default. No persistent state is carried between sessions unless you explicitly manage it.
Configuration
Before using the Points Controlled Browser in a code point, set the following value points in your configuration:
| Value point | Description |
|---|---|
__arcsurf_api_token | API token for the ArcSurf service |
arcsurf_api_endpoint | Full URL of the ArcSurf service, including protocol (e.g. https://arcsurf.example.com) |
arcsurf_api_org_id | Your MelodyArc organization ID |
These are read automatically by the browser helper — you do not pass them as arguments in your code point.
Using in a code point
Load the browser helper at the start of your code point, then call _arcsurf.runSingleSession() with a list of commands.
async function execute_process() {
await get_arcsurf_helper();
const result = await _arcsurf.runSingleSession({
session: {
browser: "chromium",
headless: true,
viewport: { width: 1280, height: 720 },
},
commands: [
{ name: "goto", args: { url: "https://example.com/inventory" } },
{ name: "waitForSelector", args: { selector: ".inventory-table" } },
{ name: "getHTML", args: { selector: ".inventory-table" } },
],
});
// result.outputs[0].results contains the command responses
// result.screenshot contains a PNG of the final page state
return result;
}runSingleSession() handles the full lifecycle: it creates the session, runs all commands in sequence, optionally captures a screenshot and page state, then tears the session down and returns all outputs.
The extracted HTML or other command results can then be written to the data token and processed by downstream points.
Common patterns
Extract content from a page
Use getHTML to retrieve the rendered HTML of a specific element. Pass the result to a code point that parses or summarises it.
commands: [
{ name: "goto", args: { url: "https://example.com/status" } },
{ name: "waitForSelector", args: { selector: "#status-panel" } },
{ name: "getHTML", args: { selector: "#status-panel" } },
]Submit a form and capture the result
commands: [
{ name: "goto", args: { url: "https://example.com/lookup" } },
{ name: "fill", args: { selector: "#order-id", value: _token.order_id } },
{ name: "click", args: { selector: "button[type=submit]" } },
{ name: "waitForSelector", args: { selector: ".confirmation" } },
{ name: "getHTML", args: { selector: ".confirmation" } },
]Take a screenshot
runSingleSession() captures a screenshot of the final page state automatically. To capture at a specific point mid-sequence, add an explicit command:
{ name: "screenshot", args: { name: "report-snapshot" } }Screenshots are returned in result.screenshot (on-demand PNG) and result.assets (named captures from screenshot commands).
Available commands
| Command | Description | Key arguments |
|---|---|---|
goto | Navigate to a URL | url |
click | Click an element | selector |
fill | Fill an input field | selector, value |
press | Press a key on an element | selector, key |
waitForSelector | Wait for an element to appear | selector |
scroll | Scroll the page or an element | selector (optional), x, y |
executeScript | Run JavaScript in the page context | script, arg (optional) |
focus | Focus an element | selector |
validate | Assert element values or states | assertions[] |
pause | Delay execution | duration (ms) |
screenshot | Capture and store a screenshot | name (optional) |
getHTML | Retrieve HTML from an element or the full page | selector (optional), outer (boolean) |
Updated about 2 hours ago
