API Reference
Macro Handler API Guide
All API objects, methods, and global functions available in Macro Handler scripts. Browse categories from the left panel or use the search.
Completion, parameter hints and type checking. Installation instructions and downloads are hosted on GitHub.
Lua: Prefer ":" for instance method calls (example: region:find(Asset.image("target"), FindParam.timeout(3000)), match:click()).
Language and OCR scope
14 languages are selectable on both the website and the Android app settings. The Android app starts in the phone's language when it is one of them, otherwise in English; the website starts in English. Users can switch either one to their preferred language at any time.
70 cataloged OCR locale-routing codes map to 7 OCR recognizer families: Latin, Chinese, Japanese, Korean, Devanagari, Arabic, and Cyrillic. The count shows which recognizer handles each code; it is not independently validated accuracy for 70 languages. Latin, Chinese, Japanese, Korean, and Devanagari use ML Kit recognizer packages; Arabic and Cyrillic use bundled Tesseract data for offline fallback. For scripts outside the listed recognizer families or rapidly changing glyph shapes, prefer template or image flows.
Trigger and Event scope
Macros can start manually from the dashboard, shortcuts, quick settings tile, and widget surfaces; the trigger modes cover daily time (classic clock or an advanced cron expression), repeating interval, app launch and close (an app launch opens the control panel and waits for you to press play), allowlisted notification posted and cleared, battery level, system broadcast, remote trigger (an encrypted FCM message that reaches only devices signed in to your own account; there is no public webhook, and the control that sends it is not available yet), charger connected and disconnected, screen on and off, and volume key. Every trigger can be narrowed with 10 conditions combined in an AND/OR/NOT constraint tree: screen on, charging, Wi-Fi, headset, device unlocked, macro idle, device orientation, battery level, time-of-day window, and foreground app. On the script side, the Event object exposes source, kind, mode, macroId, packageName, appName, title, body, and at fields.
Total APIs
848
Global Functions
29
Global Objects
60
Object Methods
819
Global Functions
Adds a button to a Setting dialog that lets the user pick one of this macro’s Agent Detect reference sets. The id of the chosen set comes back under the field key and is stored as a Setting unless the key starts with "_".
local builder = Setting.builder()
builder:add("targets", AgentDetectEditor("", "Targets"))
local result = builder:build():show()Adds an on/off checkbox to a Setting dialog; its value in the result table is a real boolean.
local builder = Setting.builder()
builder:add("notify", Checkbox(true, "Show notifications"))Taps a Point, a Region (its middle) or a search Result. param is a ClickParam for repeats, hold and waits; returns true when the tap was dispatched.
click(Point(540, 960))
-- or the last match of a search: click(region:getLastMatch(), ClickParam["repeat"](2))Adds a colour picker to a Setting dialog; the value is a hex string such as "#RRGGBB".
local builder = Setting.builder()
builder:add("marker", ColorPicker("#FF0000", "Marker colour"))Adds a date and time picker to a Setting dialog; pattern is the value format (default "yyyy-MM-dd HH:mm:ss").
local builder = Setting.builder()
builder:add("start", DateTimePicker("2026-10-01 09:00:00", "Start", "yyyy-MM-dd HH:mm:ss"))Adds a text field to a Setting dialog: value is the initial text, lines the visible line count (default 1), label the field label and hint the placeholder shown while empty.
local builder = Setting.builder()
builder:add("delay", EditText("500", 1, "Delay (ms)", "100-5000"))Adds a file picker to a Setting dialog; the value is the path of the chosen file.
local builder = Setting.builder()
builder:add("list", FilePicker("", "Word list"))Creates a waypoint for a swipe path: holdMs is how long the finger rests after reaching the point, moveMs is the duration of the move into it (ignored for the first point, at least 50 ms).
local start = GesturePoint(Point(540, 1500), 0, 0)
local finish = GesturePoint(Point(540, 500), 100, 300)
swipe({ start, finish })Adds an image picker to a Setting dialog; the chosen image name can be used with Asset.image(...).
local builder = Setting.builder()
builder:add("target", ImagePicker("target", "Target image"))Returns a multi-finger gesture builder: add each finger path with add(path), then build() and go().
local builder = MultiGestureBuilder()
builder:add({ GesturePoint(Point(300, 1500), 0, 0), GesturePoint(Point(300, 600), 0, 400) })
builder:add({ GesturePoint(Point(780, 1500), 0, 0), GesturePoint(Point(780, 600), 0, 400) })
builder:build():go()Adds a multi-choice list to a Setting dialog; selectedValues are the options selected at start.
local builder = Setting.builder()
builder:add("modes", MultiSelect({ "Slow", "Fast" }, { "Slow" }, "Modes"))Adds a button to a Setting dialog that opens this macro’s Navigation setup (map and route). The selection the user saves comes back under the field key and is stored as a Setting unless the key starts with "_".
local builder = Setting.builder()
builder:add("route", NavigationEditor("", "Route"))
local result = builder:build():show()Shows a short on-screen message and writes it to the macro log; returns true.
notifyPro("Step completed")Adds a number field limited to min and max to a Setting dialog.
local builder = Setting.builder()
builder:add("repeat", NumberRange("3", "Repeat count", "1", "10"))Writes its arguments, separated by tabs, to the macro log.
print("Level", 3, "started")Sends one immediate tap at a Point, Region or Result; returns false when the target does not resolve to a point.
local p = Point(540, 960)
quickTap(p)Adds a single-choice group to a Setting dialog; the result is the text of the chosen option.
local builder = Setting.builder()
builder:add("speed", RadioGroup({ "Slow", "Fast" }, 0))Adds a field for a recording (Replay) name to a Setting dialog. It does not start recording by itself; record with Replay.start() and Replay.save(name).
local builder = Setting.builder()
builder:add("route", Recorder("daily_route", "Recording name"))Asks the macro to stop gracefully; running waits and gestures end at their next stop check.
if not License.isActive() then
requestStop()
endAdds a finger-drawn signature field to a Setting dialog.
local builder = Setting.builder()
builder:add("signature", SignaturePad("", "Signature"))Pauses the script for the given number of seconds; fractions are allowed (0.5 = 500 ms). A stop request ends the pause early.
sleep(0.5)Adds a slider between min and max to a Setting dialog.
local builder = Setting.builder()
builder:add("repeat", Slider("3", "Repeat count", "1", "10"))Adds vertical space between two fields of a Setting dialog.
local builder = Setting.builder()
builder:add("gap", Spacer())Swipes along a path of at least two points. The path is a table of GesturePoint or Point values; param is a SwipeParam. Returns true when the movement was dispatched.
swipe({ GesturePoint(Point(540, 1500), 0, 0), GesturePoint(Point(540, 500), 0, 300) })Adds a tabbed layout to a Setting dialog; define the fields of each tab with tab(...).
local builder = Setting.builder()
local tabs = TabLayout({}, 0)
tabs:tab("General", { "delay" }, {}, true)
builder:add("tabs", tabs)
builder:add("delay", EditText("500", 1, "Delay (ms)"))Adds an input for comma-separated tags to a Setting dialog.
local builder = Setting.builder()
builder:add("tags", TagInput("daily,reward", "Tags"))Adds a read-only line of text to a Setting dialog.
local builder = Setting.builder()
builder:add("intro", TextView("Choose how the macro should run."))Shows a short on-screen message and writes the text to the macro log; returns true.
toast("Macro started")Pauses the script for the given number of milliseconds. Stop and pause requests interrupt it.
wait(500)
wait(1000)Touch and Actions
Runs the approved routine or plan of an enabled Agent block saved in this macro. Uses the same macro-start consent, stop rules and failure behavior as the block, returning a structured result.
Foundation Example
-- Use a literal id from an enabled Agent block saved in this macro.
-- Its routine/plan must be approved; launch consent is still required.
local result = Agent.run("saved_agent_block_id")
if result.ok then
print(result.outcome, result.taps)
else
print(result.outcome, result.detail, result.kind)
endNetwork and Integration
Sends text or image prompts to the configured AI provider; the result is a table with ok, text and error.
Foundation Example
local answer = AI.ask("Summarise this log line in five words: level 3 cleared")
if answer.ok then print(answer.text) else print(answer.error) endCore Flow
Queries available API names and missing requirements for portable libraries.
Foundation Example
local capabilities = Api.check({"Form.show", "Workflow.retry", "Module.use"})
if not capabilities.ok then
error("Missing: " .. table.concat(capabilities.missing, ", "))
end
print("Library APIs are available")Data and Files
Helpers for Lua lists: sort, filter, map, reduce, contains, length, reverse and join.
Foundation Example
local scores = Array.sort({ 3, 1, 2 })
local doubled = Array.map(scores, function(item) return item * 2 end)Scanning and Detection
Creates search templates: Asset.image(name), Asset.color(hex) and Asset.text(text) return a template (AssetTemplate) you tune with methods such as :mScore() and :gray().
Foundation Example
local template = Asset.image("play_button"):mScore(0.85)
local region = Region()
local match = region:find(template)Scanning and Detection
The search template Asset.image/color/text returns. It is not a global name; its methods chain and return the template (for example Asset.image("x"):mScore(0.9):gray()).
Foundation Example
local template = Asset.image("target"):mScore(0.9):gray()
local match = Region():find(template)Core Flow
Timers and promises: Async.defer and Async.every schedule delayed or repeating callbacks, Async.promise creates a result you can await. At most 128 timers and 128 promises can exist at once.
Foundation Example
local timerId = Async.every(1000, function() print("tick") end)
wait(3500)
Async.cancel(timerId)Core Flow
The result object Async.promise() creates: complete it with resolve or reject and wait for it with await.
Foundation Example
local promise = Async.promise()
if promise then
Async.defer(500, function() promise:resolve("ready") end)
local ok, value = promise:await(2000)
endScanning and Detection
The screen-capture session: grabs areas as Base64 images (for AI.askVision) and reports the session state.
Foundation Example
local image = Capture.regionToBase64(Region(0, 0, 540, 960))
local answer = AI.askVision("What button is shown?", image)Parameter Objects
Tap settings for click(): repeat count, hold time, pauses after each tap and a random offset.
Foundation Example
click(Point(540, 960), ClickParam.hold(120))Data and Files
Copies text to the clipboard and reads the clipboard text.
Foundation Example
Clipboard.copy("Macro Handler")
local text = Clipboard.paste()Data and Files
Persistent document collections private to the macro: write with put(name, id, document) and query by field equality with find(name, field, value).
Foundation Example
Collection.put("players", "player_1", { name = "Ada", level = 3 })
local players = Collection.find("players", "level", 3, 10)Scanning and Detection
Reads and compares colours. Color.pixel(x, y) reads a colour from the screen; Color.isSimilar compares colours within a deltaE threshold. The factory functions are called with a dot and accept a Color object, a hex string or a packed ARGB number.
Foundation Example
Snap.screenRefresh()
local pixel = Color.pixel(540, 960)
if pixel and Color.isSimilar(pixel, "#22BB57", 15) then
click(Point(540, 960))
endUI and Dialogs
Writes to the macro log and asks the user for text with Console.in.
Foundation Example
local level = Console["in"]("Enter a level number")
Console.out("Selected level: " .. level)License and Security
Digests (MD5, SHA), HMAC signatures, Base64/hex encoding, secure random values and constant-time comparison. Digests return hex strings; there is no encryption such as AES.
Foundation Example
local signature = Crypto.hmacSha256("shared-secret", "payload")
local ok = Crypto.constantTimeEquals(signature, signature)Date and Time
Date and time values. DateTime.now() or DateTime(...) returns a DateTime object; formatting uses Java patterns (yyyy-MM-dd HH:mm).
Foundation Example
local now = DateTime.now()
toast(now:format("yyyy-MM-dd HH:mm"))UI and Dialogs
Dialog.init() returns the same dialog builder as Setting.builder(). Add fields, then show the dialog with build():show().
Foundation Example
local builder = Dialog.init()
builder:setTitle("Settings")
builder:add("delay", EditText("500", 1, "Delay (ms)"))
local result = builder:build():show()System Control
Sets and reads screen cutouts (notches), used to adapt coordinates between the macro and the device.
Foundation Example
Env.setMacroCutouts({ top = 80 })
local cutouts = Env.cutouts()System Control
Information about the trigger that started this run (source, app, title, text, time). Event.exists() tells whether the run was started by a trigger.
Foundation Example
if Event.exists() then
print(Event.appName() .. ": " .. Event.title())
endCore Flow
In-script events: add listeners with Events.on and emit with Events.emit. At most 128 listeners in total and 32 per event.
Foundation Example
Events.on("level_done", function(level) print("cleared " .. level) end)
Events.emit("level_done", 3)Data and Files
Reads, writes and lists text files in the macro’s file area.
Foundation Example
File.write("run.log", "Started")
local text = File.read("run.log")Parameter Objects
Search parameters: timeout (ms), match threshold mScore (0-1), scan rate sRate (1-30 per second), scale and engine. Chain them as in FindParam.timeout(3000):mScore(0.85).
Foundation Example
local param = FindParam.timeout(3000):mScore(0.85):sRate(10)
local match = Region():find(Asset.image("target"), param)UI and Dialogs
Builds conditional, tabbed and styled native dialogs from code-authored schemas.
Foundation Example
local schema = {title = "Run settings", positive = "Start", negative = "Cancel", fields = {
{type = "checkbox", key = "enabled", label = "Enabled", value = true},
{type = "input", key = "target", label = "Target", value = "Example", required = true},
{type = "slider", key = "count", label = "Count", min = 1, max = 10, value = 3},
{type = "select", key = "mode", options = {"Safe", "Fast"}, selected = 2},
{type = "multi", key = "steps", label = "Steps", options = {"Scan", "Report"}, value = {"Scan"}}
}}
local values = Form.show(schema)
if values ~= nil and values.enabled then
local count = tonumber(values.count)
if count then print(values.target, values.mode, count) end
endUI and Dialogs
A floating info box on screen. Hud(x, y, w, h, clickable) creates a Hud object; text and style methods are called on that object, and Hud.off() closes every box.
Foundation Example
local hud = Hud(20, 20, 320, 64, false)
hud:setText("Running")
hud:setTextColor("#FFFFFF")
hud:setBackgroundColor("#80000000")
hud:show()Touch and Actions
Sets and reads this macro’s human-like gesture level (0 is off, at most 3).
Foundation Example
Humanize.setLevel(2)Data and Files
Converts between Lua tables and JSON text. Call JSON.parse and JSON.stringify with a dot.
Foundation Example
local data = JSON.parse([[{"enabled":true,"level":3}]])
local text = JSON.stringify({ enabled = true })Data and Files
Persistent key-value storage private to the macro. Each macro has its own store; a value is limited to 1 MB and the store to 10 MB.
Foundation Example
local runs = KV.increment("runs", 1)
KV.set("last_run", DateTime.now():format("yyyy-MM-dd HH:mm"))License and Security
Checks the user’s premium entitlement from a script: License.isActive() returns true when it is active. No activation keys or per-macro licences are used, so activate and deactivate change nothing.
Foundation Example
if License.isActive() then
toast("License active")
endCore Flow
Runs other macros: Macro.run(target, params) queues one, Macro.runWait(target, params, timeoutMs) waits for it and returns the outcome. Call with a dot.
Foundation Example
local outcome = Macro.runWait("daily_rewards", { level = 3 }, 60000)
print(outcome.status)Data and Files
A key-value collection. Map() creates a Map object; get, set, has and keys are called on it with a colon. Static helpers such as Map.keys(table) also work on plain Lua tables.
Foundation Example
local scores = Map()
scores:set("level", 3)
if scores:has("level") then
print(scores:get("level"))
endData and Files
Helpers that complement Lua’s math library: random ranges, angle conversion, hypot and atan2.
Foundation Example
local distance = Math.hypot(300, 400)
local delay = Math.randomRange(200, 400)System Control
Collects and summarises runtime metrics (scan and OCR counters).
Foundation Example
Metrics.enable()
-- ... run the scans ...
print(Metrics.summary())Core Flow
Organizes source code carried with the macro into reusable libraries with dependencies.
Foundation Example
Module.define("example.normalizer", function()
return {clean = function(text) return string.lower(text) end}
end)
local library = Module.use("example.normalizer")
print(library.clean("HELLO"))Touch and Actions
Multi-finger gestures: add each finger path with MultiGesture.builder(), then run them together with build():go().
Foundation Example
local builder = MultiGesture.builder()
builder:add({ GesturePoint(Point(300, 1500), 0, 0), GesturePoint(Point(300, 600), 0, 400) })
builder:add({ GesturePoint(Point(780, 1500), 0, 0), GesturePoint(Point(780, 600), 0, 400) })
builder:build():go()Touch and Actions
Steers a joystick along a saved map and route. Navigation.run(options, onCheckpoint?) owns the control loop and returns a table describing how the run ended; Navigation.stop() ends the journey from an observation group after confirmed input release.
Foundation Example
local result = Navigation.run({ profileId = profileId, routeId = routeId, routeType = "one_way", timeoutMs = 120000 })
print(result.state, result.progress)Data and Files
Number conversion and rounding; Num.parseOcr and Num.evalOcrMath turn OCR-read text into numbers safely.
Foundation Example
local coins = Num.parseOcr("l,234", 0)
local price = Num.precise(19.987, 2)Touch and Actions
Controls the floating control panel from a script: show, hide, position it, set its opacity and read its state.
Foundation Example
Panel.show()
Panel.setOpacity(0.85)
Panel.setPosition(120, 300)Core Flow
The Time/Repeat gate: on each visit it picks the true or the false phase by visit count or elapsed time and keeps its state for the macro run.
Foundation Example
local gate = PhaseGate.create({ trueMode = "count", trueLimit = 3, falseMode = "count", falseLimit = 1 })
if PhaseGate.next(gate) then
print("work phase")
endParameter Objects
Playback settings for Replay.play(): repeats, pauses, a random offset and speed.
Foundation Example
Replay.play("daily_route", PlayParam.setSpeed(1.5))Touch and Actions
A point on the screen. Point(x, y) maps macro coordinates to the device and returns a Point object (nil when mapping fails); click, quickTap and Touch calls accept a Point.
Foundation Example
local point = Point(540, 960)
if point then quickTap(point) endData and Files
Java regular expressions: match, matchAll, find, replace and split. The pattern is the first argument; each operation is limited to 2 seconds.
Foundation Example
local level = Regex.match("[0-9]+", "Level 12, stage 3")
local parts = Regex.split(",\\s*", "red, green, blue")Scanning and Detection
An area of the screen to search and act in. Region(x, y, w, h) creates a Region object (Region() is the whole screen); find, click, wait, read and the geometry methods are called on that object with a colon.
Foundation Example
local area = Region()
local hit = area:find(Asset.image("ok_button"))
if hit then quickTap(hit) endTouch and Actions
Touch recordings: start and stop a recording, save it under a name, list them and play one with Replay.play.
Foundation Example
local ok = Replay.play("daily_route")Network and Integration
HTTPS requests. Short calls such as Request.get(url) take only the address; for headers, a body or retries create a request object with Request(url) and configure it. Read the response with getResponseCode() and getData().
Foundation Example
local res = Request.get("https://example.com/api/status")
if res:getResponseCode() == 200 then
local data = JSON.parse(res:getData())
endScanning and Detection
The match a search such as region:find(...) returns. It is not a global name: check the search result for nil first, then call methods such as getX(), getScore() or getEngine() on it.
Foundation Example
local match = Region():find(Asset.image("target"), FindParam.timeout(3000))
if match then
print(match:getX(), match:getY(), match:getScore())
click(match)
endSystem Control
Coordinate and runtime settings: the macro’s reference resolution (Runtime.setMacroSize), scale, debug mode and completion messages.
Foundation Example
Runtime.setMacroSize(1080, 2400)
print(Runtime.resolution())UI and Dialogs
Manages macro settings and the user dialog. Call its functions with a dot: Setting.get(key, default) and Setting.set(key, value) read their arguments by position.
Foundation Example
local builder = Setting.builder()
builder:add("delay", EditText("500", 1, "Delay (ms)"))
Setting.setDialog(builder:build())
Setting.show()
local delay = tonumber(Setting.get("delay", "500")) or 500UI and Dialogs
The dialog builder from Setting.builder() or Dialog.init(). Add fields with add(key, view); build() returns the dialog and build():show() returns the user’s answers.
Foundation Example
local builder = Setting.builder()
builder:setTitle("Macro settings")
builder:add("delay", EditText("500", 1, "Delay (ms)"))
local result = builder:build():show()Scanning and Detection
Manages the screen-capture cache: take a fresh frame with Snap.screenRefresh() before searching and limit capture to an area with Snap.region(...).
Foundation Example
Snap.screenRefresh()
local region = Region()
local found = region:find(Asset.image("start_button"))Network and Integration
Server-Sent Events reader: reads events from an address and returns a table with ok, events, count and first.
Foundation Example
local result = SSE.first("https://example.com/events", 10000)
if result.ok and result.first then print(result.first.data) endDate and Time
Measures elapsed time. Stopwatch() creates a stopwatch object; start(), elapsedMs() and lap() are called on that object.
Foundation Example
local watch = Stopwatch()
watch:start()
wait(250)
print("Elapsed ms: " .. tostring(watch:elapsedMs()))Data and Files
String helpers. Positions are 0-based like Java strings: Str.indexOf returns -1 when nothing is found and Str.substring(source, start, end) excludes end.
Foundation Example
local name = Str.trim(" Macro Handler ")
if Str.startsWith(name, "Macro") then
print(Str.toUpperCase(name))
endParameter Objects
Swipe settings for swipe(): repeat count, pauses between repeats and waypoints, and a random offset.
Foundation Example
swipe({ GesturePoint(Point(540, 1500), 0, 0), GesturePoint(Point(540, 500), 0, 300) }, SwipeParam["repeat"](2))System Control
Device and app operations: messages and logging, global actions (Back, Home), opening apps, timers and scheduled runs, and screen information.
Foundation Example
System.toast("Starting")
local width, height = System.width(), System.height()
System.log("Screen: " .. width .. "x" .. height)Date and Time
Duration values. Factory functions such as TimeSpan.fromSeconds(...) return a TimeSpan object; totalSeconds(), add() and format() are called on it.
Foundation Example
local span = TimeSpan.fromMinutes(90)
print(span:totalHours(), span:format("HH:mm:ss"))UI and Dialogs
Styled messages: ToastParams() creates a style object, settings chain, and show(text) displays the message.
Foundation Example
local style = ToastParams():setPosition("top"):setDuration(3000)
style:show("Level complete")Touch and Actions
Low-level touch: finger down/move/up, pinch and rotate gestures and, from 1.0.51, background finger lanes (Touch.lane*).
Foundation Example
Touch.down(Point(500, 1200), 0)
wait(80)
Touch.up(0)Parameter Objects
Settings for this run: a script can store and read back a match threshold, tap and swipe delays, a scan interval and a comparison size; these do not change searches or gestures. Only the grayscale switch changes searches: from Macro Handler 1.0.51, Tune.grayscaleOn() makes image searches colour-independent.
Foundation Example
Tune.grayscaleOn()
local match = Region():find(Asset.image("enemy_icon"), FindParam.timeout(2000))
Tune.grayscaleOff()Touch and Actions
Reads the on-screen app interface from the accessibility tree: finds elements by text or id and clicks them.
Foundation Example
local node = Ui.byText("Settings")
if node then Ui.click(node) endTouch and Actions
Utility functions: Utils.interpolatePoints creates evenly spaced points between two points.
Foundation Example
local points = Utils.interpolatePoints(Point(200, 1600), Point(880, 400), 8)System Control
Version comparison. Version.isAtLeast("1.0.40") checks the running app; Version("1.2.3") creates a Version object.
Foundation Example
if not Version.isAtLeast("1.0.40") then
System.alert("Please update Macro Handler")
requestStop()
endScanning and Detection
Visual target tracking: describe several views of one target with profile, find it on each frame with step, and follow its moving or lost status.
Foundation Example
local profile = VisualTarget.profile("enemy", { { name = "front", template = Asset.image("enemy_front") } })
local state = VisualTarget.step(profile, Region())
if state.found then VisualTarget.click(profile) endNetwork and Integration
WebSocket client: WebSocket.text and WebSocket.exchange make a one-off exchange; WebSocket.connect opens a connection object whose send, receive, on and close methods are called on it.
Foundation Example
local socket = WebSocket.connect("wss://example.com/socket")
socket:send("ping")
local event = socket:receive(5000)
socket:close()Core Flow
Combines condition polling, bounded retries, sequential loops and cleanup in authored code.
Foundation Example
local result = Workflow.retry(function(attempt)
return attempt >= 3, "sample result"
end, {maxAttempts = 4, delayMs = 50, backoff = 2, timeoutMs = 2000})
print(result.ok, result.attempts, result.values[2])Detailed Usage Examples
Starter scripts to paste into the code editor and adapt to your own screen. Adjust coordinates, image templates and wait times, then test them on your device. Each example comes with a description and parameter notes.