Skip to content

API reference

This is the complete reference for the Santiago automation API: the set of endpoints the local daemon exposes for controlling a running browser profile. Every endpoint drives a real Playwright-backed page inside the anti-detect browser, so the same fingerprint and proxy you configured for the profile apply to every action.

For setup and high-level usage, see HTTP API basics and Best practices. For worked end-to-end flows, see the automation guides.

All automation endpoints live under the local daemon and target one running profile by id:

http://localhost:7891/api/automation/:profileId/<action>

The daemon listens on http://localhost:7891 only. Replace :profileId with the id of a running profile — launch it first (see Launch profiles for automation). Calls to a profile that is not running return 404 PROFILE_NOT_RUNNING.

Every endpoint returns the same envelope.

Success
{ "ok": true, "data": { ... } }
Error
{ "ok": false, "error": { "code": "ERROR_CODE", "message": "..." } }

Actions that only succeed or fail (click, hover, type, mouse moves, etc.) return { "ok": true } with no data. Endpoints that produce a value (snapshot, screenshot, navigate, tabs, evaluate, dialog) populate data.

ConstantValueApplies to
Navigation timeout30snavigate, back, forward, reload, opening a tab with a URL
Action timeout2sInteraction endpoints (click, hover, type, select-option, scroll-to, screenshots of an element)
Wait timeout15s (default)wait endpoint; override with the timeout field
MethodPathKey paramsPurpose
POST/:profileId/navigateurl (required)Navigate to a URL.
POST/:profileId/backnoneGo back in history.
POST/:profileId/forwardnoneGo forward in history.
POST/:profileId/reloadnoneReload the current page.

All four return { ok, data: { url, title } } with the resulting page URL and title.

Navigate to a URL
curl -X POST http://localhost:7891/api/automation/$PROFILE_ID/navigate \
-H 'Content-Type: application/json' \
-d '{"url": "https://example.com"}'
Response
{ "ok": true, "data": { "url": "https://example.com/", "title": "Example Domain" } }
MethodPathKey paramsPurpose
POST/:profileId/snapshotselector, depthCapture the accessibility tree of the page and get element refs.
POST/:profileId/screenshotfullPage, ref, selectorTake a base64-encoded PNG screenshot.

Capture the accessibility tree of the current page. This is the primary way to “see” page structure and obtain [ref=eN] ids for later actions.

FieldTypeDefaultDescription
selectorstringCSS selector to scope the snapshot to one element subtree
depthnumberLimit tree depth
Snapshot the page
curl -X POST http://localhost:7891/api/automation/$PROFILE_ID/snapshot \
-H 'Content-Type: application/json' \
-d '{}'
Response
{ "ok": true, "data": { "snapshot": "- heading \"Example\" [ref=e1]\n- textbox \"Email\" [ref=e2]\n..." } }

Take a screenshot. Returns a base64-encoded PNG string. Provide ref or selector to capture a single element; otherwise the viewport (or full page) is captured.

FieldTypeDefaultDescription
fullPagebooleanfalseCapture the full scrollable page (ignored when ref/selector is set)
refstringScreenshot a specific element by ref
selectorstringScreenshot a specific element by CSS selector
Response
{ "ok": true, "data": { "screenshot": "iVBORw0KGgo..." } }

All interaction endpoints below accept either ref (from snapshot) or selector (CSS); at least one is required.

MethodPathKey paramsPurpose
POST/:profileId/clickref/selector, button, doubleClick, modifiersClick an element.
POST/:profileId/hoverref/selectorHover over an element.
POST/:profileId/dragstartRef/startSelector, endRef/endSelectorDrag and drop between two elements.
POST/:profileId/scroll-toref/selectorScroll an element into view.
FieldTypeDefaultDescription
refstringElement ref from snapshot
selectorstringCSS selector
button"left" | "right" | "middle""left"Mouse button
doubleClickbooleanfalseDouble click
modifiersstring[]"Alt", "Control", "ControlOrMeta", "Meta", "Shift"
Click by ref
curl -X POST http://localhost:7891/api/automation/$PROFILE_ID/click \
-H 'Content-Type: application/json' \
-d '{"ref": "e20"}'
FieldTypeDescription
refstringElement ref
selectorstringCSS selector

Drag from a source element to a target element. Each side accepts a ref or a selector.

FieldTypeDescription
startRefstringSource element ref
startSelectorstringSource CSS selector
endRefstringTarget element ref
endSelectorstringTarget CSS selector

Scroll an element into view.

FieldTypeDescription
refstringElement ref
selectorstringCSS selector

Two endpoints cover the two kinds of dropdowns you meet on the web: native <select> elements and custom ARIA combobox widgets.

MethodPathKey paramsPurpose
POST/:profileId/select-optionref/selector, values (required)Select option(s) in a native <select>.
POST/:profileId/select-comboboxref/selector, value (required), optionSelectorSmart selection for custom ARIA combobox dropdowns.

Select option(s) in a native <select> element.

FieldTypeRequiredDescription
ref / selectorstringyesTarget <select> element
valuesstring[]yesValues to select
Response
{ "ok": true, "data": { "selected": ["value1"] } }

Smart selection for ARIA combobox dropdowns — the custom <div role="combobox"> widgets used by many modern web apps. It performs the whole sequence: click to open, read aria-controls to find the listbox, wait for the listbox to become visible (5s), find the [role="option"] matching value (or your optionSelector), and click it.

FieldTypeRequiredDescription
ref / selectorstringyesTarget combobox element
valuestringyesOption text to select
optionSelectorstringCustom CSS selector for the option (overrides text matching)
Select a custom-dropdown option
curl -X POST http://localhost:7891/api/automation/$PROFILE_ID/select-combobox \
-H 'Content-Type: application/json' \
-d '{"ref": "e5", "value": "March"}'
Response
{ "ok": true, "data": { "selected": "March" } }
MethodPathKey paramsPurpose
POST/:profileId/typeref/selector, text (required)Clear a field and type a value (human-like per-key delay).
POST/:profileId/press-sequentiallyref/selector, text (required), delayType text key by key without clearing first.
POST/:profileId/press-keykey (required), modifiersPress a key or key combination.
POST/:profileId/fill-formfields (required)Fill multiple fields at once (ref/selector based).
POST/:profileId/fill-pagefields, submit, waitAfterSubmitHigh-level coordinate-based form fill + optional submit.

Focus a field, clear its existing value, then type the new value with a human-like per-key delay.

FieldTypeRequiredDescription
ref / selectorstringyesTarget input element
textstringyesText to type
Type into a field
curl -X POST http://localhost:7891/api/automation/$PROFILE_ID/type \
-H 'Content-Type: application/json' \
-d '{"ref": "e2", "text": "jane.doe@example.com"}'

Type text key by key into the targeted element (does not clear first). Useful for inputs that react to each keystroke.

FieldTypeDefaultDescription
ref / selectorstringrequiredTarget element
textstringrequiredText to type
delaynumber50Delay between keys in ms

Press a single keyboard key or a combination. With modifiers, the daemon joins them into a chord (for example Control+a).

FieldTypeDescription
keystringKey name: "Enter", "Tab", "Escape", "a", "F1", etc.
modifiersstring[]"Alt", "Control", "ControlOrMeta", "Meta", "Shift"
Submit a form with Enter
curl -X POST http://localhost:7891/api/automation/$PROFILE_ID/press-key \
-H 'Content-Type: application/json' \
-d '{"key": "Enter"}'

Fill multiple form fields in one call. Each field is filled via a Playwright locator (click, clear, type); if that fails, the daemon falls back to a coordinate-based strategy (resolve bounding box, click center, select-all, delete, type). Each field result reports the strategy used (locator or coords).

FieldTypeRequiredDescription
fieldsarrayyes[{ ref?, selector?, value }]
Fill several fields
curl -X POST http://localhost:7891/api/automation/$PROFILE_ID/fill-form \
-H 'Content-Type: application/json' \
-d '{
"fields": [
{"ref": "e2", "value": "Jane Doe"},
{"selector": "#email", "value": "jane@example.com"}
]
}'
Response
{
"ok": true,
"data": {
"results": [
{ "ref": "e1", "ok": true },
{ "selector": "#email", "ok": true },
{ "ref": "e3", "ok": false, "error": "Element not found" }
]
}
}

A high-level, coordinate-based fill that bypasses Playwright locators entirely (evaluate to find centers, then mouse + keyboard). One call can fill a whole form, select comboboxes, and click submit — replacing many round-trips. Comboboxes are opened, the matching option is clicked, and the selection is verified (with one automatic retry).

FieldTypeDefaultDescription
fieldsarrayArray of field objects (see below)
submitobject{ selector?, text? } submit button (selector first, then text fallback)
waitAfterSubmitnumber2000Milliseconds to wait after clicking submit

Each entry in fields:

FieldTypeDefaultDescription
selectorstringrequiredCSS selector for the element
valuestringrequiredValue to type, or the option text to select
type"text" | "combobox""text"Field kind
nthnumber00-based index when the selector matches multiple elements
optionSelectorstringli[role=option]CSS for option elements (combobox only)

At least one of fields or submit is required (otherwise 400 BAD_REQUEST).

Fill and submit a form in one call
curl -X POST http://localhost:7891/api/automation/$PROFILE_ID/fill-page \
-H 'Content-Type: application/json' \
-d '{
"fields": [
{"selector": "#firstName", "value": "Jane"},
{"selector": "#month", "value": "March", "type": "combobox"}
],
"submit": {"text": "Submit"},
"waitAfterSubmit": 3000
}'
Response
{
"ok": true,
"data": {
"results": [
{ "selector": "#firstName", "type": "text", "ok": true },
{ "selector": "#month", "type": "combobox", "ok": true, "selectedValue": "March" }
],
"submit": { "ok": true, "url": "https://example.com/welcome" }
}
}

Low-level mouse control by viewport coordinates. Use these when locator-based interaction is blocked or unreliable.

MethodPathKey paramsPurpose
POST/:profileId/mouse/movex, y (required)Move the cursor to a point.
POST/:profileId/mouse/clickx, y (required), buttonClick at a point.
POST/:profileId/mouse/downbuttonPress a mouse button down.
POST/:profileId/mouse/upbuttonRelease a mouse button.
POST/:profileId/mouse/wheeldeltaX, deltaYScroll the wheel.
FieldTypeRequired
xnumberyes
ynumberyes
FieldTypeDefault
xnumberrequired
ynumberrequired
button"left" | "right" | "middle""left"

POST /:profileId/mouse/down and /:profileId/mouse/up

Section titled “POST /:profileId/mouse/down and /:profileId/mouse/up”
FieldTypeDefault
button"left" | "right" | "middle""left"
FieldTypeDefaultDescription
deltaXnumber0Horizontal scroll
deltaYnumber0Vertical scroll (positive = down)
Click at a coordinate
curl -X POST http://localhost:7891/api/automation/$PROFILE_ID/mouse/click \
-H 'Content-Type: application/json' \
-d '{"x": 480, "y": 320}'
MethodPathKey paramsPurpose
GET/:profileId/tabsnoneList open tabs.
POST/:profileId/tabs/newurlOpen a new tab (blank if url omitted).
POST/:profileId/tabs/selectindex (required)Switch to a tab by index.
POST/:profileId/tabs/closeindexClose a tab (defaults to the last; cannot close the last remaining tab).
List tabs
curl http://localhost:7891/api/automation/$PROFILE_ID/tabs
Response
{ "ok": true, "data": { "tabs": [{ "index": 0, "url": "https://...", "title": "..." }] } }
FieldTypeDefaultDescription
urlstringURL to open (blank tab if omitted)

Returns { ok, data: { index, url, title } }.

FieldTypeRequired
indexnumberyes

Returns { ok, data: { index, url, title } }. Out-of-range index returns 400 BAD_REQUEST.

FieldTypeDefaultDescription
indexnumberlast tabTab index to close

Returns { ok, data: { closedIndex } }. Closing the only remaining tab returns 400 LAST_TAB — stop the profile instead.

MethodPathKey paramsPurpose
POST/:profileId/evaluatecode (required)Run JavaScript in the page context and return the result.
FieldTypeRequired
codestringyes
Read the document title from the page
curl -X POST http://localhost:7891/api/automation/$PROFILE_ID/evaluate \
-H 'Content-Type: application/json' \
-d '{"code": "document.title"}'
Response
{ "ok": true, "data": { "result": "Example Domain" } }
MethodPathKey paramsPurpose
POST/:profileId/waittext, selector, state, timeoutWait for an element/text state, or a fixed time.

If you pass selector or text, the call waits for that element to reach state. If you pass neither, it just waits for timeout milliseconds.

FieldTypeDefaultDescription
textstringWait for this text to appear
selectorstringWait for this CSS selector
state"visible" | "hidden" | "attached" | "detached""visible"Target state
timeoutnumber15000Timeout in ms. With no text/selector, waits this long unconditionally
Wait for an element to appear
curl -X POST http://localhost:7891/api/automation/$PROFILE_ID/wait \
-H 'Content-Type: application/json' \
-d '{"selector": "#dashboard", "state": "visible", "timeout": 20000}'
MethodPathKey paramsPurpose
POST/:profileId/dialogaction (required), promptTextAccept or dismiss a pending alert/confirm/prompt.

The daemon tracks native dialogs (alert, confirm, prompt) per profile as they open. Call this endpoint to handle the oldest pending one.

FieldTypeRequiredDescription
action"accept" | "dismiss"yesAccept or dismiss the dialog
promptTextstringText to enter for prompt dialogs (used on accept)
Response
{ "ok": true, "data": { "type": "confirm", "message": "Are you sure?", "defaultValue": "" } }

If there is no pending dialog, the call returns 404 NO_DIALOG.

MethodPathKey paramsPurpose
POST/:profileId/batchactions (required)Run multiple actions in one HTTP call, with human-like pacing.

Execute several actions sequentially in a single request. The daemon inserts a random 80–250ms delay between actions for human-like pacing. It stops on the first error — remaining actions are skipped (so they never run on stale state).

Type, select, then click in one call
curl -X POST http://localhost:7891/api/automation/$PROFILE_ID/batch \
-H 'Content-Type: application/json' \
-d '{
"actions": [
{"action": "type", "ref": "e1", "text": "Jane Doe"},
{"action": "select-combobox", "ref": "e5", "value": "March"},
{"action": "click", "ref": "e20"}
]
}'

Available actions and the fields each one uses (same as the matching individual endpoint):

ActionFields
clickref/selector, button, doubleClick, modifiers
typeref/selector, text
press-sequentiallyref/selector, text, delay
press-keykey, modifiers
select-optionref/selector, values
select-comboboxref/selector, value, optionSelector
hoverref/selector
scroll-toref/selector
waittext, selector, state, timeout
navigateurl
snapshotselector, depth
screenshotref, selector, fullPage
evaluatecode
Response
{
"ok": true,
"data": {
"results": [
{ "index": 0, "action": "type", "ok": true },
{ "index": 1, "action": "select-combobox", "ok": true, "data": { "selected": "March" } },
{ "index": 2, "action": "click", "ok": true }
]
}
}

An empty actions array returns 400 BAD_REQUEST.

CodeWhen
PROFILE_NOT_RUNNINGThe profile id is not a running profile (HTTP 404).
BAD_REQUESTMissing required body fields, or an out-of-range tab index (HTTP 400).
LAST_TABAttempt to close the only remaining tab (HTTP 400).
NO_DIALOGdialog called with no pending dialog (HTTP 404).
NAVIGATE_FAILEDnavigate / back / forward / reload failed.
SNAPSHOT_FAILED / SCREENSHOT_FAILEDSnapshot or screenshot failed.
CLICK_FAILED / HOVER_FAILED / DRAG_FAILED / SCROLL_FAILEDThe corresponding interaction failed (often a 2s action timeout).
SELECT_FAILED / SELECT_COMBOBOX_FAILEDDropdown selection failed.
TYPE_FAILED / PRESS_SEQ_FAILED / KEY_PRESS_FAILED / FILL_FORM_FAILED / FILL_PAGE_FAILEDText input failed.
MOUSE_FAILEDA coordinate mouse action failed.
TABS_FAILED / TAB_NEW_FAILED / TAB_SELECT_FAILED / TAB_CLOSE_FAILEDA tab action failed.
EVALUATE_FAILEDThe page script threw.
WAIT_FAILEDThe wait condition timed out.
DIALOG_FAILEDHandling the dialog failed.
BATCH_FAILEDThe batch request could not run (e.g. profile not running).