LoliScript Reference
LoliScript is the line-based domain-specific language used by OBM2 Pro to define automation scripts. It is both written by hand and generated by the visual Stacker editor.
Overview
LoliScript is a simple imperative language where each line is one instruction. Beyond block invocations, control flow and variable assignment, it can also embed inline scripts (JavaScript or IronPython) for custom logic — see Inline Scripting. It is case-insensitive for keywords.
The Stacker (visual editor) and the LoliScript editor stay fully in sync. Editing one updates the other in real time.
Script Structure
A LoliScript file consists of a sequence of lines. Blank lines are ignored. Each non-blank line is either a:
- Block invocation — runs a stacker block (REQUEST, PARSE, KEYCHECK, etc.)
- Control statement — IF, ELSE, END, JUMP, LABEL
- Built-in command — SET, LOG
- Comment — line starting with
#
# A minimal LoliScript config
REQUEST GET "https://example.com"
PARSE <SOURCE> LR "token:" "\"" -> "token"
KEYCHECK
KEYCHAIN Success OR
KEY "<token>" Exists
KEYCHAIN Failure OR
KEY "<RESPONSECODE>" EqualTo "401"
Comments
Lines beginning with # are ignored by the interpreter.
# This is a comment
REQUEST GET "https://example.com" # Inline comments are NOT supported
Inline comments (after an instruction on the same line) are not supported. Place comments on their own line.
Variables in LoliScript
Variable values are substituted by wrapping the name in angle brackets: <varName>. This substitution happens automatically in string fields before each instruction executes.
SET "greeting" "Hello, <username>! Your score is <score>."
LOG "<greeting>"
See the Variables & BotData page for the full reference including automatic variables and list syntax.
Control Flow
IF / ELSE / END
Conditional branching. The condition is evaluated against a variable using the same operators as Keycheck.
IF "<RESPONSECODE>" EqualTo "200"
PARSE <SOURCE> JSON "user.token" -> "token"
ELSE
SET "token" ""
LOG "Unexpected response code: <RESPONSECODE>"
END
Available Operators in IF
Same as Keycheck: Contains, DoesNotContain, EqualTo, NotEqualTo, Exists, DoesNotExist, GreaterThan, LessThan, MatchesRegex.
JUMP & LABEL
Unconditional jump to a named label. Useful for retry loops or skipping sections.
LABEL retry
REQUEST GET "https://example.com/check"
IF "<RESPONSECODE>" EqualTo "429"
UTILITY Wait 2000
JUMP retry
END
PARSE <SOURCE> JSON "status" -> "status"
Infinite loops via JUMP are possible. Always include an exit condition (IF / Keycheck) before jumping back.
SET & LOG
SET
Assign a value to a variable. The value string supports variable substitution.
SET "apiUrl" "https://api.example.com/v1/user/<userId>"
SET "authHeader" "Bearer <token>"
LOG
Write a message to the run log. Visible in the Debugger's Log tab and in the Runner log panel.
LOG "User: <email> — Status: <RESPONSECODE>"
LOG "Capture: <planType>"
Inline Scripting (JavaScript / IronPython)
When the standard blocks aren't enough, LoliScript can embed an inline script between BEGIN SCRIPT and END SCRIPT. The current LoliScript variables are injected into the script's scope; the variables listed after OUTPUTS are read back and stored as BotData variables, usable by the blocks that follow.
BEGIN SCRIPT IronPython
# <USERNAME> and <PASSWORD> are injected as variables
result = USERNAME.upper() + "::" + PASSWORD
END SCRIPT -> VARS OUTPUTS "result"
The language token right after BEGIN SCRIPT selects the engine: IronPython (embedded Python, no system install required) or JavaScript. Use OUTPUTS "a,b,c" to export several variables at once.
IronPython scripting was reintroduced on .NET 8 — embedded, with no external interpreter required. It is distinct from the PYRUN utility, which shells out to a separately installed Python.
Block Keywords Reference
Every stacker block has a corresponding LoliScript keyword. Parameters enclosed in quotes are strings (support variable substitution); parameters in parentheses are named boolean/int flags.
| Keyword | Block | Minimal Example |
|---|---|---|
REQUEST | HTTP Request | REQUEST GET "https://url" |
TLSREQUEST | TLS Request | TLSREQUEST GET "https://url" TLSPROFILE:"Chrome" |
KEYCHECK | Keycheck | (multi-line, see Stacker docs) |
PARSE | Parse | PARSE <SOURCE> LR "L" "R" -> "out" |
FUNCTION | Function | FUNCTION Hash MD5 "<pass>" -> "hash" |
UTILITY | Utility | UTILITY Wait 1000 |
CAPTCHA | Captcha | CAPTCHA RecaptchaV2 "url" "sitekey" -> "token" |
NAVIGATE | Navigate (Selenium) | NAVIGATE "https://url" TIMEOUT:10000 |
BROWSERACTION | BrowserAction | BROWSERACTION SendKeys "<TAB>||Hello||<ENTER>" |
ELEMENTACTION | ElementAction | ELEMENTACTION id "username" ClearAndType "<email>" |
EXECUTEJS | ExecuteJS | EXECUTEJS "return document.title;" -> "title" |
TCP | TCP | TCP Connect "host" "port" (UseSSL=False) |
IMAP | IMAP | IMAP Connect "imap.host" "993" (UseSSL=True) 30000 |
POP3 | POP3 | POP3 Connect "pop.host" "995" (UseSSL=True) 30000 |
SMTP | SMTP | SMTP Connect "smtp.host" "587" (UseSSL=True) 30000 |
FTP | FTP | FTP Connect "ftp.host" "21" "user" "pass" (UseSSL=False) 15000 |
Debugger
The Debugger lets you step through a script line by line with test data, without running the full Runner.
| Tab | Description |
|---|---|
| Data | Live view of all BotData variables after each step |
| Log | Execution log with timestamps and block names |
| HTML View | Rendered HTML of the last HTTP or browser response |
| Notepad | Scratch pad — test regex patterns, LR anchors, or JSONPath expressions against pasted text |
Test Input
Enter test credentials in the Debugger's input field in the same format as your wordlist (e.g. user@example.com:password123). You can also specify a test proxy.
OBM2 Pro