Introduction

JuliuS exposes a local HTTP server based on Indy TIdHTTPServer that enables remote control of the scripting engine and the embedded browser (Chromium CEF). All endpoints use a single route with parameters in the query string.

The endpoints are divided into three macro-areas: Browser CEF (operations inside the embedded browser), Page Inspection / DevTools (reading the DOM, frames, network), OS (operating-system-level mouse and keyboard, for native windows outside the browser).

Base URL & Authentication

http://<host>:<port>/
โš  Warning: JuliuS currently does not provide authentication. Expose the server only on localhost or trusted networks.

Load script from file

GET/?loadscript={filename}Loads a script from disk
Loads a script file from the folder configured in Settings.Data.scriptPath and opens it in JuliuS's graphical editor. Use this endpoint when the script to run already resides on the disk of the machine hosting JuliuS. The .js extension is added automatically if the file is not found without it, making it optional to specify it in the call. Loading is asynchronous: the response arrives immediately, but the editor opens on the main thread shortly after.
async
200OK
200*Errore, file non trovato [...]
GET /?loadscript=login_flow HTTP/1.1

Load script from stream

POST/?operation=readscritpfromstreamSends a script via the body
Sends the script source directly in the body of the POST request, without needing a file on disk. This is the ideal mode for external orchestration systems (e.g. ScrapManager) that generate or modify scripts at runtime before sending them to JuliuS. The script is opened in the editor with the title "Script from remote". If the body is missing or reading fails, an error message is returned but the server does not raise an exception.
async
200OK
200*Errore nello scritp โ€” missing body or read error
POST /?operation=readscritpfromstream HTTP/1.1 Content-Type: text/plain // remote script var x = doSomething();

Read current script

GET/?operation=getscriptReturns the source of the script loaded in the editor
Returns, in the response body, the text of the script currently present in the frmScript editor. Reading happens directly from SynSynaScript.Text via TThread.Synchronize, so it also includes any manual edits made by the user in the editor after the initial load, not just the last value set via loadscript or readscritpfromstream. This is a pure read endpoint: it does not modify the editor state nor the current execution. Useful for checking what is about to be executed before a start, for a quick backup of the remote editor, or to compare the in-memory script with the file on disk.
sync
ParameterRequiredDescription
operationโœ“Must be getscript
Response HeaderValue
Content-Typetext/plain; charset=utf-8
200Body with the full script source (UTF-8)
200Empty body โ€” no script open in frmScript or error while reading
GET /?operation=getscript HTTP/1.1 Host: 127.0.0.1:8080
# Save the currently loaded script to a file curl "http://127.0.0.1:8080/?operation=getscript" --output current_script.js

Read current line

GET/?operation=getcurrentlineReturns the current cursor line number
Returns, in the response body, the (1-based) number of the line where the cursor of the SynSynaScript editor in frmScript is currently positioned. This is exactly the line that would be used as the starting point by the next ?operation=start: script execution indeed starts from the current caret position in the editor. Useful for monitoring how far a script's execution has progressed, synchronizing external interfaces with the execution pointer, or checking the starting line before launching a start. Purely a read endpoint: it does not alter the editor state.
sync
ParameterRequiredDescription
operationโœ“Must be getcurrentline
Response HeaderValue
Content-Typetext/plain; charset=utf-8
200Current line number as a string (e.g. 42)
2000 โ€” frmScript not initialized or read error
GET /?operation=getcurrentline HTTP/1.1 Host: 127.0.0.1:8080 โ†’ 42

Set starting line

GET/?operation=setcurrentline&line={N}Moves the cursor to the given line for the next start
Moves the cursor of the SynSynaScript editor to the given line (1-based), which becomes the starting line used by the next ?operation=start. The caret column is reset to 1. If the requested value exceeds the number of lines present in the script, a clamp is applied to the last available line. The operation is protected: if a script is already running, the call is rejected to avoid altering the current execution pointer. More flexible than reset cursor, which always moves the caret back to line 1.
sync
ParameterRequiredDescription
operationโœ“Must be setcurrentline
lineโœ“Line number (integer โ‰ฅ 1, 1-based). Values beyond the maximum number of lines are clamped to the last available line.
Response HeaderValue
Content-Typetext/plain; charset=utf-8
200line_set_N โ€” confirmation with the line number actually set (may differ from the one requested if clamping was applied)
200*ERROR: parametro line mancante o non numerico
200*ERROR: line deve essere >= 1
200*ERROR: script in esecuzione, impossibile cambiare la linea corrente
200*ERROR: frmScript non inizializzato
GET /?operation=setcurrentline&line=42 HTTP/1.1 Host: 127.0.0.1:8080 โ†’ line_set_42
Typical flow: call ?operation=status to check the system is idle, then ?operation=setcurrentline&line=N, then ?operation=start to start execution from the chosen line.

Start execution

GET/?operation=start[&params...]Starts the current script
Starts execution of the script currently loaded in the JuliuS editor, beginning at the line indicated by currentLine. Before calling this endpoint it is good practice to check the state with ?operation=status: if a process is already running, the call is rejected with an explicit message, avoiding concurrent executions. The excelLine and remoteVirtualPath parameters set the logging and screenshot upload context used by the script during execution.
async
ParameterRequiredDescription
operationโœ“Must be start
currentLineLine at which execution starts
excelLineBase name of the row in the Excel log, used to name screenshot files
remoteVirtualPathRemote virtual path for screenshot upload (_ is replaced with /). The trailing / is added automatically.
200started
200*Already Running, check status before try to start another process
200*Script is not already initiated โ€” no script form open

Stop execution

GET/?operation=stopStops the running script
Stops the running script by calling frmScript.stopExecution on the main thread. The operation correctly handles both the running and paused states, clearing both status flags. Any child popup window opened during execution is also closed. If no execution is in progress, the call is a silent no-op.
async
GET /?operation=stop HTTP/1.1

Reset cursor

GET/?operation=resetMoves the editor cursor back to line 1
Moves the SynEdit editor cursor to the first line of the script, preparing a new execution from the start. Useful in automated flows to ensure the script always restarts from the beginning after a completed cycle. The operation is protected: if a script is currently running (IsRunning = true), the call is silently ignored without returning errors, avoiding interference with the process in progress.
async
Note: Silently ignored if a script is running (IsRunning = true).

Status

GET/?operation=statusChecks the state of the scripting engine
Returns the current state of the JuliuS scripting engine. This is the fundamental polling endpoint to call before every start to avoid multiple concurrent starts, and during execution to detect when a script has finished. The state accounts for both active script execution and page loading in the browser (MainBrowserFrm.FPageLoading): if the page is still loading, the system is reported as busy even if the script is technically paused.
sync
200on working โ€” script running or page loading
200no operation progress โ€” system idle, ready for a new start

Get Result (fixed function)

GET/?operation=getresultExecutes preventivo() and returns the result
Calls the JavaScript function preventivo() in the browser โ€” the result-extraction function used by convention in JuliuS scripts โ€” and returns its value serialized as TOperationResult JSON. The JSON includes the raw result, the operation ID, the start date, and the list of captured screenshots. Use this at the end of a quoting script to retrieve the computed value. For functions with a different name, use the variable Get Result endpoint.
sync

Get Result (variable function)

GET/?getresult={functionName}Executes an arbitrary JS function and returns the result
Generalized version of getresult: executes in the browser the JavaScript function whose name is passed as a parameter, automatically appending the parentheses (). Returns the value as TOperationResult JSON, exactly like the fixed endpoint. Use this endpoint when the script exposes extraction functions with custom names (e.g. getOrderTotal, calcolaPremio) instead of the standard preventivo() function. The function must already be defined in the browser's JS context at the time of the call.
sync
ParameterDescription
getresultName of the JS function to execute, without parentheses. The () are added automatically.
GET /?getresult=getOrderTotal HTTP/1.1

Click (CEF)

GET/?operation=click&X={x}&Y={y}Simulates a click in the CEF browser
Sends a synthetic click to the embedded Chromium browser at the specified pixel coordinates, relative to the CEF panel. Useful for interacting with elements not easily reachable via JavaScript (canvas, WebGL, elements with custom event handlers). Coordinates must be calibrated relative to the resolution set with SCREEN_SIZE. For clicks on native Windows windows or system dialogs, use the OS Mouse endpoints instead, which act at the operating-system level.
sync
ParameterDescription
XX coordinate in pixels relative to the CEF panel
YY coordinate in pixels relative to the CEF panel
GET /?operation=click&X=320&Y=240 HTTP/1.1

Snapshot (CEF)

GET/?operation=snapshotScreenshot of the CEF browser as a JPG stream
Captures the current visual state of the embedded CEF browser and returns it as a binary JPG stream. The custom scalefactor header indicates the monitor's DPI scale factor and should be used by the client to correctly interpret image dimensions in high-density display environments (HiDPI). This endpoint captures only the browser panel, not the entire JuliuS window nor the desktop. For a screenshot of the whole desktop, use osscreenshotjpg.
syncbinary stream
Response HeaderValue
Content-Typeimage/jpg
scalefactorMonitor DPI factor (e.g. 1.25 for 125% displays)
curl "http://127.0.0.1:8080/?operation=snapshot" --output screenshot.jpg

Restart Chromium

GET /?operation=restartchromium Reset the in-memory Chromium session

Clears the embedded Chromium session without restarting the application. Via the DevTools Protocol it clears HTTP cache, cookies, localStorage, sessionStorage and IndexedDB, then navigates to about:blank. Responds only once the reset is complete.

sync

Response

200 chromium_restarted โ€” reset completed
200* ERROR: ... โ€” error message

Example

GET /?operation=restartchromium HTTP/1.1 Host: 127.0.0.1:8080 โ†’ chromium_restarted

Delete Chromium Cache

GET /?operation=deletechromiumcache Deep cleanup: memory + files on disk

Performs a complete reset of the Chromium cache: clears HTTP cache, cookies and storage via the DevTools Protocol, then physically deletes the GlobalCEFApp.RootCache directory on disk. Slower than restartchromium โ€” use it for a corrupted cache or to guarantee a session indistinguishable from a cold start.

sync

Comparison with restartchromium

Actionrestartchromiumdeletechromiumcache
In-memory HTTP cacheโœ…โœ…
In-memory cookiesโœ…โœ…
LocalStorage / IndexedDBโœ…โœ…
Cache files on diskโŒโœ…
Average time~3 s~5 s

Response

200 chromium_cache_deleted โ€” cleanup completed
200* ERROR: ... โ€” error message

Example

GET /?operation=deletechromiumcache HTTP/1.1 Host: 127.0.0.1:8080 โ†’ chromium_cache_deleted

Get DOM

GET/?operation=getdomReturns the complete outerHTML of the page
Returns the full HTML source of the page currently loaded in the browser, obtained via document.documentElement.outerHTML. Useful for offline DOM analysis, debugging pages with dynamic rendering, or checking the current state of the page before performing interactions. Since it returns the live DOM (post-JavaScript, not the server's original source), it reflects the actual state of the page including changes made by scripts already executed.
sync
200Full page HTML โ€” text/html; charset=utf-8
200*ERROR: ... โ€” internal exception

Get Form Fields

GET/?operation=getformfieldsLists all form fields on the page as JSON
Analyzes the DOM of the current page and returns a JSON array with all interactive form elements: input, select, textarea and button. For each element, properties such as id, name, type, value and visible are included. Particularly useful while developing a script, to identify the IDs of elements to use in WRITETO commands without having to manually inspect the page source.
sync
200JSON array of form fields โ€” application/json; charset=utf-8
200*ERROR: ... โ€” internal exception

Get Page Info

GET/?operation=getpageinfoMetadata about the current page
Returns a JSON object with essential information about the currently loaded page: current URL, document title, readyState and the list of iframes present with their URLs. This is the ideal endpoint to quickly check which page the browser is on, verify that loading is complete (readyState === "complete"), and identify the frame structure before using TARGET_FRAME in scripts.
sync
200JSON with url, title, readyState, iframes list โ€” application/json; charset=utf-8
200*ERROR: ... โ€” internal exception

Get Console Log

GET/?operation=getconsolelogRetrieves JavaScript console messages
Automatically installs a listener on the browser's JavaScript console (if not already active) and returns all console.log, console.warn and console.error messages accumulated so far. Essential for debugging SNIPPET blocks in scripts, which typically use console.log() to trace execution. Messages are accumulated in memory and returned on every call without being cleared, unless an explicit reset occurs.
sync
200JSON array of console messages โ€” application/json; charset=utf-8
200*ERROR: ... โ€” internal exception

EvalJS (via API)

GET/?evaljs={expression}Evaluates an arbitrary JavaScript expression in the browser
Executes a single JavaScript expression in the CEF browser context and returns its value as plain text. Unlike ?operation=getresult, the result is not stored in the current TOperationResult but returned directly in the HTTP response. The expression must be URL-encoded. Useful for quick DOM queries or checking the state of JS variables without having to define a dedicated function in the script.
sync
200Result of the expression as a string โ€” text/plain; charset=utf-8
200*ERROR: ... โ€” internal exception or JS error
# Reads the page title GET /?evaljs=document.title # Checks the visibility of an element (URL-encoded selector) GET /?evaljs=%24('%23btnAvanti').is('%3Avisible')

Find Element

GET/?findelement={css_selector}Checks whether a CSS element exists in the DOM
Checks whether a CSS selector is present in the DOM of the current page and returns a JSON object with the properties of the found element, including id, tagName, value, visible and boundingRect. Useful for implementing conditional logic in automation flows: checking that a button is present before clicking, waiting for a result element to appear, or detecting error messages on the page. The selector must be URL-encoded.
sync
200JSON with the properties of the found element โ€” application/json; charset=utf-8
200*ERROR: ... โ€” internal exception
# Search by ID (# URL-encoded = %23) GET /?findelement=%23btnAvanti # Search by class GET /?findelement=.risultato-finale

Get Frame List

GET/?operation=getframelistList of all frames open in the browser
Returns a JSON array with all frames currently open in the CEF browser: main frame, iframes and child frames. For each frame, name, id, url, the isMain flag and the isFocused flag are provided. This is the reference endpoint to consult before using the TARGET_FRAME=POPUP directive in scripts, to identify exactly the name or URL of the target frame. Particularly useful with pages that open popups or use nested frames.
sync
200JSON array with name, id, url, isMain, isFocused
200*{"error":"..."}

Get Frame Source

GET/?operation=getframesource[&frame={name}]Source HTML of a specific frame
Reads and returns the source HTML of a specific frame identified by name, including support for cross-origin frames that would normally not be accessible via standard JavaScript due to security policy. If the frame parameter is omitted, the source of the main frame is returned. Useful for inspecting the content of third-party iframes, forms loaded in separate frames, or child popups opened during navigation.
sync
ParameterRequiredDescription
frameName of the target frame. If omitted โ†’ main frame.
200Frame HTML โ€” text/html; charset=utf-8
200*ERROR: ... โ€” frame not found or internal error
GET /?operation=getframesource&frame=contentFrame HTTP/1.1

Wait Page Load

GET/?operation=waitpageload[&timeout={ms}]Waits for page load to complete
Blocks the HTTP response until the page in the browser has finished loading (or until the timeout expires). Unlike fixed WAITs in scripts, this endpoint adapts to the server's real timing: it returns the response as soon as the page is ready, reducing unnecessary wait time. The request runs on the HTTP thread without blocking the application's main thread. The default timeout is 15 seconds and can be increased for particularly slow pages.
sync (blocking)
ParameterDefaultDescription
timeout15000Maximum wait timeout in milliseconds
200loaded โ€” page loaded successfully within the timeout
200*timeout โ€” the timeout expired before loading completed
GET /?operation=waitpageload&timeout=20000 HTTP/1.1

DevTools Protocol

GET/?devtools={method}[&params={json}]Executes a Chrome DevTools Protocol command
Allows executing any Chrome DevTools Protocol (CDP) command directly on the CEF browser, opening access to advanced functionality not exposed by the standard APIs: device emulation, network request interception, profiling, low-level DOM access and much more. The params parameter accepts a URL-encoded JSON object with the specific parameters of the CDP command. Consult the official CDP documentation for the full list of available methods.
sync
ParameterRequiredDescription
devtoolsโœ“CDP method to execute (e.g. Network.enable, DOM.getDocument)
paramsCommand parameters as URL-encoded JSON
200JSON with the CDP command response
200*{"error":"..."} โ€” invalid method or CDP error
# Enables network request tracking GET /?devtools=Network.enable # Evaluates an expression via the Runtime CDP domain GET /?devtools=Runtime.evaluate¶ms=%7B%22expression%22%3A%22document.title%22%7D

Start Network Log

GET/?operation=startnetworklogStarts logging network calls
Clears the previous network log buffer and enables Network.enable via the Chrome DevTools Protocol to intercept all HTTP/HTTPS requests made by the browser: XHR, fetch, resource loading. Must be called before navigating to the page to monitor, so as not to miss the first requests. The collected data can then be retrieved with ?operation=getnetworklog. Useful for analyzing the APIs called by a web page or identifying endpoints to replicate.
sync
200network log started
200*ERROR: ... โ€” internal exception

Get Network Log

GET/?operation=getnetworklogRetrieves the log of intercepted network requests
Returns the accumulated log of network requests intercepted after a call to startnetworklog. The log is a JSON array where each entry contains the HTTP method (method), the full URL (url) and the resource type (type, e.g. XHR, Fetch, Document). Calling this endpoint multiple times does not clear the log: the buffer grows until the next startnetworklog. Ideal for reverse-engineering a web page's APIs or checking the calls made during a script's execution.
sync
200JSON array with method, url, type for each request โ€” application/json; charset=utf-8
200*{"error":"..."}

OS Mouse โ€” Move

GET/?operation=osmousemove&x={x}&y={y}Moves the mouse cursor to absolute screen coordinates
Moves the mouse cursor to absolute screen coordinates using the native Windows operating system APIs (TCrossSO.SetMousePos). Unlike the CEF click endpoint, which acts inside the embedded browser, this endpoint controls the cursor at the OS level and can interact with any window visible on the desktop: native Windows dialogs, system popups, windows of other applications, or JuliuS's own interface. Use in combination with osmouseclick to perform precise clicks on native elements.
syncOS
200moved
200*ERROR: ...
GET /?operation=osmousemove&x=500&y=300 HTTP/1.1

OS Mouse โ€” Left click

GET/?operation=osmouseclickSimulates a left click at the current cursor position
Simulates pressing and releasing the left mouse button at the current position of the system cursor, via TCrossSO.MouseLClick. Must be preceded by a call to osmousemove to correctly position the cursor. Acts at the operating-system level, so it works on any active window on the desktop, not just the CEF browser. For movement and click in a single atomic operation, use osmousemoveclick.
syncOS
200clicked

OS Mouse โ€” Move + Click

GET/?operation=osmousemoveclick&x={x}&y={y}Moves the cursor and clicks in a single operation
Combines cursor movement and left click into a single API call, with a 50ms pause between the two operations to allow the operating system to update the cursor position before the click. This is the most efficient endpoint for clicks on fixed coordinates, as it reduces the number of HTTP round-trips compared to two separate calls. Ideal for fast automations that need to click on many elements in sequence.
syncOS
200moved_and_clicked
GET /?operation=osmousemoveclick&x=640&y=480 HTTP/1.1

OS Mouse โ€” Right click

GET/?operation=osmouserclickSimulates a right click at the current cursor position
Simulates pressing and releasing the right mouse button at the current cursor position, via TCrossSO.MouseRClick. Useful for opening native operating-system context menus or Windows applications that do not expose their own elements via a web interface. Like the other OS mouse endpoints, it acts at the operating-system level and is not bound to the CEF browser.
syncOS
200right_clicked

OS Mouse โ€” Get position

GET/?operation=osmouseposReturns the current position of the system cursor
Reads and returns the absolute screen coordinates of the mouse cursor as a JSON object {"x": N, "y": N}. Useful during automation development and debugging to calibrate the coordinates to use in the osmousemove and osmousemoveclick endpoints, or to check that the cursor is at the expected position before performing a click.
syncOS
200{"x":320,"y":240} โ€” application/json; charset=utf-8
200*{"error":"..."}

OS Keyboard โ€” Key Press

GET/?operation=oskeypress&key={keycode}Simulates pressing a key via numeric keycode
Sends a key press to the active operating-system window using its Virtual Key (VK) keycode. Unlike WRITETO, which writes into the CEF browser, this endpoint acts at the OS level and can control any active window: native Windows dialogs, non-web forms, desktop applications. For common keys (ENTER, ESC, TAB), dedicated, more readable shortcuts are available; use this endpoint when you need a specific key not covered by the shortcuts.
syncOS
KeycodeKeyKeycodeKey
13ENTER27ESC
9TAB32SPACE
8BACKSPACE46DELETE
37โ† LEFT38โ†‘ UP
39โ†’ RIGHT40โ†“ DOWN
112โ€“123F1โ€“F1265โ€“90Aโ€“Z
200key_pressed
GET /?operation=oskeypress&key=13 HTTP/1.1 # presses ENTER on the active window

OS Keyboard โ€” Common key shortcuts

GET/?operation={oskeyXXX}Named shortcuts for the most commonly used keys
Named aliases for the most frequently used keys in automations, more readable than the numeric keycodes of oskeypress. Each endpoint performs exactly the same operation as the corresponding numeric keycode, but makes logs and automation sequences immediately understandable. Use these shortcuts whenever possible; fall back to oskeypress with a numeric keycode only for keys not covered by these aliases.
syncOS
OperationKeyResponse
oskeyenterENTER (โ†ต)enter
oskeyescESCesc
oskeytabTAB (โ‡ฅ)tab
oskeybackspaceBACKSPACE (โŒซ)backspace
GET /?operation=oskeyenter HTTP/1.1 GET /?operation=oskeyesc HTTP/1.1

OS Keyboard โ€” Arrow Keys

GET/?operation=oskeyarrow&dir={up|down|left|right}Simulates pressing the directional arrow keys
Sends a press of one of the four directional arrow keys to the active operating-system window. Useful for navigating native dropdowns, scrolling lists, moving between fields of a Windows form, or controlling desktop applications that respond to arrow keys. The dir parameter accepts the values up, down, left, right in lowercase; unrecognized values are silently ignored.
syncOS
dirKey
upโ†‘ Arrow up
downโ†“ Arrow down
leftโ† Arrow left
rightโ†’ Arrow right
200arrow_down / arrow_up / etc.
GET /?operation=oskeyarrow&dir=down HTTP/1.1

OS Keyboard โ€” Key Combo

GET/?operation=oskeycombะพ&combo={modifier+key}OS key combination (Ctrl/Shift/Alt + key)
Simulates a key combination at the operating-system level via the Windows keybd_event API. The combo parameter accepts the syntax modifier+key in lowercase, URL-encoded if necessary. The modifier can be ctrl, shift or alt; the key can be a single letter (aโ€“z) or a special key by name. Available only on the Windows platform: on other platforms the endpoint responds with an explicit error message without raising exceptions.
syncOS
Combo fieldAccepted values
modifierctrl, shift, alt
keySingle letter (aโ€“z), or: f4โ€“f6, f10โ€“f12, tab, enter, esc, del, home, end, pageup, pagedown
200combo_ctrl+c โ€” confirmation of the executed combination
200*ERROR: formato combo non valido, usare modifier+key
200*ERROR: tasto non riconosciuto [...]
200*ERROR: oskeycombะพ not implemented on this platform
# Copy (Ctrl+C) GET /?operation=oskeycombะพ&combo=ctrl+c # Paste (Ctrl+V) GET /?operation=oskeycombะพ&combo=ctrl+v # Close window (Alt+F4) GET /?operation=oskeycombะพ&combo=alt+f4 # Select all (Ctrl+A) GET /?operation=oskeycombะพ&combo=ctrl+a # Reverse tab (Shift+Tab) GET /?operation=oskeycombะพ&combo=shift+tab

OS Screenshot (PNG)

GET/?operation=osscreenshotScreenshot of the entire Windows desktop in PNG format
Captures the entire Windows desktop โ€” including the taskbar, native popups, system dialogs, and any open window โ€” and returns it as a binary PNG stream. Unlike snapshot, which captures only the CEF browser panel, this endpoint photographs everything visible on the screen. The scalefactor header indicates the monitor's DPI factor. Use the osscreenshotjpg variant when file size takes priority over quality.
syncOSbinary stream
Response HeaderValue
Content-Typeimage/png
scalefactorMonitor DPI factor
200PNG stream of the entire desktop
200*ERROR: screenshot failed
curl "http://127.0.0.1:8080/?operation=osscreenshot" --output desktop.png

OS Screenshot (JPG)

GET/?operation=osscreenshotjpgScreenshot of the entire Windows desktop in JPG format
JPG variant of the osscreenshot endpoint: captures the entire Windows desktop and returns it compressed as JPEG at quality 45 (the same used for the CEF browser snapshot). Produces significantly lighter files than PNG, at the cost of a slight quality loss in text areas. This is the recommended variant for debugging and frequent monitoring flows, where transfer speed matters more than image fidelity.
syncOSbinary stream
Response HeaderValue
Content-Typeimage/jpg
scalefactorMonitor DPI factor
200JPG stream of the entire desktop
200*ERROR: screenshot failed
curl "http://127.0.0.1:8080/?operation=osscreenshotjpg" --output desktop.jpg

Get Browser Window Info

GET/?operation=getbrowserwindowinfoPosition and size of the JuliuS window and the CEF panel
Returns a JSON object with the position and size of both the main JuliuS window (mainForm) and the CEF browser panel (browser), including absolute screen values (screenLeft, screenTop). The scaleFactor field indicates the monitor's DPI factor. This endpoint is essential for converting browser-relative coordinates into absolute screen coordinates to use with the OS mouse endpoints, so that automations work correctly regardless of where the JuliuS window is positioned on the desktop.
sync

JSON response structure

{ "mainForm": { "left": 100, "top": 50, "width": 1200, "height": 800 }, "browser": { "left": 0, "top": 60, "width": 1024, "height": 768, "screenLeft": 100, "screenTop": 110, "clientWidth": 1024, "clientHeight": 768 }, "scaleFactor": 1.25 }
200JSON with mainForm, browser and scaleFactor โ€” application/json; charset=utf-8
200*{"error":"..."}
Typical use: Call this endpoint once before a sequence of OS clicks to obtain browser.screenLeft and browser.screenTop, then add them to the browser-relative coordinates to get the absolute screen coordinates to pass to osmousemoveclick.

Browser Move Click

GET/?operation=browsermoveclick&x={x}&y={y}OS click at coordinates relative to the browser panel
Performs a left click at the operating-system level using coordinates relative to the CEF browser panel (the same origin as snapshot and MOUSE_CLICK), internally delegating to ClickOnBrowserRelative the conversion into absolute screen coordinates. It is more reliable than osmousemoveclick with absolute coordinates because it works correctly regardless of the position of the JuliuS window on the desktop and the DPI scale factor, without the caller having to compute the conversion manually.
syncOS
ParameterDescription
xX coordinate in CSS pixels relative to the top-left corner of the browser panel
yY coordinate in CSS pixels relative to the top-left corner of the browser panel
200clicked_at_browser_320_240 โ€” confirmation with the coordinates used
200*ERROR: ...
# Click at X=320, Y=240 relative to the browser GET /?operation=browsermoveclick&x=320&y=240 HTTP/1.1
Difference from CEF click and osmousemoveclick: ?operation=click sends an internal synthetic CEF event. osmousemoveclick uses absolute screen coordinates. browsermoveclick uses browser-relative coordinates but acts at the OS level โ€” it is the sweet spot between ease of use and cross-position reliability.

Rewrite Global Variables

POST/?globalv=rewriteOverwrites the current script's global variables
Sends a new set of global variables in the POST body and injects them directly into the GLOBALV block of the script currently loaded, overwriting the previous values. The content is loaded into frmScript.GlobalV via LoadFromStream and then updateGlobalV physically updates the lines of the GLOBALV=BEGIN/END block in the editor. Useful in orchestration systems to parameterize an already-loaded script with different data (e.g. different customer, different case) without reloading the entire file. The body must contain var name="value"; pairs in the GLOBALV block format.
async
POST /?globalv=rewrite HTTP/1.1 Content-Type: text/plain var USERNAME="mario.rossi"; var TARGET_URL="https://example.com/dashboard"; var MAX_RETRIES="3";

API Logging โ€” Overview

Every HTTP request received by the JuliuS server is automatically recorded as a JSON Lines row in the application's log file. Logging relies on the synaLog unit (global singleton thLog, asynchronous writing with a dedicated writer thread, automatic rotation at 100 MB, zip archiving of old logs with a 7-day retention). The log file is the same one used by the scripting engine (wLog), so API requests and script execution logs appear in the same chronological sequence.

Format of a log line

{"ts":"2026-05-22T14:03:21.421","tag":"API","reqId":"A3F1B2C7","client":"127.0.0.1","method":"GET","uri":"/","op":"start","durMs":3,"params":{"operation":"start","currentLine":"42"},"response":"started"}

Fields present in each entry

FieldDescription
tsLocal ISO 8601 timestamp with milliseconds
tagAlways "API" โ€” distinguishes API rows from other system logs
reqId8-character ID (first 8 hex digits of a GUID) to correlate entry/exit of the same request
clientCaller's IP (AContext.Binding.PeerIP)
methodHTTP method (GET, POST)
uriRequested URI (always / for JuliuS, parameters in the query string)
opIdentified operation: the value of ?operation= if present, otherwise inferred from loadscript, globalv, navigate, evaljs, getresult, findelement, devtools
durMsRequest duration in milliseconds (from receipt to response composition)
paramsObject with all query string and form parameters
bodyBytes(only if logBodies=true and there is a POST body) โ€” size of the body in bytes
bodyPreview(only if logBodies=true) โ€” text preview of the body up to maxBodyPreview characters, or <REDACTED> for sensitive operations
responsePreview of the response truncated to maxBodyPreview characters, or <binary> if the content type is image/*

Sensitive operations (masked if maskSensitive=true)

The body of the following operations is replaced with <REDACTED> to avoid writing credentials or personal data contained in global variables to disk, and to prevent the log from ballooning with large scripts:

  • POST /?operation=readscritpfromstream โ€” body with script source (potentially MB in size)
  • POST /?globalv=rewrite โ€” body with global variables (potentially credentials)

Configuration

The four toggles are in Settings.Data.ApiLog and can be changed at runtime via setapilog without restarting the server:

ParameterTypeDefaultDescription
EnabledbooleantrueMaster switch: if false, no request is logged
LogBodiesbooleanfalseIf true, includes bodyPreview and bodyBytes in entries
MaskSensitivebooleantrueIf true, redacts the bodies of sensitive operations even with LogBodies=true
MaxBodyPreviewinteger500Maximum characters for bodyPreview and response
Reading the log: Entries are in JSON Lines format, perfectly compatible with jq, grep, and import into Splunk/ELK. Quick example to filter errors:
grep '"response":"ERROR' app.log | jq -r '[.ts,.op,.response] | @tsv'

Log status

GET/?operation=getapilogstatusReturns the current status of the API log
Returns a JSON object with the current API log configuration and the path of the physical log file in use. A purely read-only endpoint, it does not modify anything. Useful for checking at runtime which file is being written to and which flags are active.
sync
Response HeaderValue
Content-Typeapplication/json; charset=utf-8

Response structure

{ "enabled": true, "logBodies": false, "maskSensitive": true, "maxBodyPreview": 500, "logFile": "C:\\JuliuS\\JuliuS.log", "thLogActive": true }
GET /?operation=getapilogstatus HTTP/1.1

Hot toggle

GET/?operation=setapilog[&enabled=...&logbodies=...&masksensitive=...&maxpreview=...]Modifies API log flags at runtime
Modifies one or more API log toggles without needing to restart the server. All parameters are optional and combinable: unspecified parameters remain unchanged. Changes take effect immediately on the next request but are not persisted to the configuration file: on the next server restart they revert to the defaults. The response is the same as getapilogstatus and reflects the state after the changes are applied.
sync
ParameterValuesDescription
enabledtrue / false / 1 / 0Master switch of the log
logbodiestrue / falseLogs POST body and response
masksensitivetrue / falseRedacts the bodies of sensitive operations
maxpreviewinteger > 0Maximum characters in previews

Examples

# Temporarily disable logging during a load test GET /?operation=setapilog&enabled=false # Debug mode: full logs with body and no masking GET /?operation=setapilog&logbodies=true&masksensitive=false&maxpreview=2000 # Back to production defaults GET /?operation=setapilog&enabled=true&logbodies=false&masksensitive=true&maxpreview=500
Not persistent: changes live only for the current server session. For permanent changes, modify the defaults in uSettings.pas โ†’ TApiLogSettings.Initialize.

Read last lines

GET/?operation=getapilog[&lines={N}]Returns the last N lines of the log file
Forces a flush to disk of all the buffer queued in the thLog writer thread, then reads the log file and returns the last N lines in the response body as plain UTF-8 text. The default is 200 lines, the maximum limit is 5000. Useful for remote debugging without needing access to the filesystem of the machine running JuliuS, or for integration with monitoring dashboards.
sync
ParameterDefaultDescription
lines200Number of final lines to return. Values < 1 โ†’ 1, values > 5000 โ†’ 5000.
Response HeaderValue
Content-Typetext/plain; charset=utf-8
200The last N lines of the log separated by CRLF
200Empty body โ€” log file not yet created
200*ERROR: thLog non attivo โ€” the global logger is not initialized
200*ERROR: ... โ€” file exclusively locked by the writer or I/O error
# Last 200 lines (default) GET /?operation=getapilog HTTP/1.1 # Last 50 lines GET /?operation=getapilog&lines=50 # Pipe to jq to filter errors remotely curl "http://127.0.0.1:8080/?operation=getapilog&lines=1000" | grep '"response":"ERROR' | jq .
Performance: for very large log files (close to the 100 MB limit) the read loads the entire file into memory and then trims the last N lines. This is a simple, thread-safe choice; for very high-frequency scenarios, consider reading directly from the filesystem.

Flush to disk

GET/?operation=flushapilogForces a flush of the log buffer to disk
Calls thLog.FlushLog to immediately write to disk all rows still buffered in the synaLog writer thread. Under normal conditions the writer flushes automatically every 200 rows (if FdoFlush=true) or when the thread stops; this endpoint is useful when you want to guarantee that the file on disk contains everything up to that point, for example before copying it off for analysis.
sync
200flushed
200*ERROR: thLog non attivo
200*ERROR: ... โ€” exception during flush
GET /?operation=flushapilog HTTP/1.1

Force rotation

GET/?operation=rotateapilogForces rotation of the log file
Calls thLog.RequestRotate to trigger manual rotation of the file: thLog closes the current file, renames it with a unique name and zips it in the background via txtUtils.ZipAndDeleteAsync, then opens a fresh, clean file. The operation is asynchronous: the rotation flag is set and processed by the thLog Execute thread on the next iteration, typically within a second. Regardless of this call, automatic size-based rotation (default 100 MB, checked every 30 seconds) remains always active.
async
200rotate_requested โ€” flag set, the writer thread will perform the rotation
200*ERROR: thLog non attivo
GET /?operation=rotateapilog HTTP/1.1
Typical use: at the start of an extended test session, call rotateapilog to begin with a fresh file, run the tests, then flushapilog and collect the "clean" log file that contains only that session.