Lifebots symbol
Lifebots.cloud
Workshop — Script API
LifeBots Workshop

Overview

The LifeBots Workshop is a server-side JavaScript sandbox where you write your own programs to drive a LifeBots avatar (bot) in Second Life and OpenSim, live.

Controlling bots with JavaScript

You write plain, modern JavaScript — functions, callbacks, arrays, objects, Promises and async/await all work as you'd expect. Your code runs inside an isolated V8 engine (not a web browser, and not a normal Node.js process), so the language is completely familiar, but the only capabilities available to it are the Workshop globals documented in this reference.

  • Modern JavaScript is fully supported, including top-level await — there is no old-engine restriction.
  • There is no module system: import / export / require are disabled.
  • You can't (yet) include one script inside another.
  • There are no Node.js or browser APIs (no fs, no fetch, no Buffer, no DOM). Use the built-in http, localStorage and Bot interfaces instead.

Interacting with your bot

Your program runs in the sandbox and sends commands to the bot, while events flow back from the bot into your program. Both directions map straight onto ordinary JavaScript:

  • Bot commands are functions you call — for example await Bot.say(0, 'Hello').
  • Events are callback functions you register — for example Bot.on('chat_message', handler).
// command: a function you call
await Bot.say(0, 'Hello from the Workshop');

// event: a callback you register
Bot.on('chat_message', (msg) => {
  console.log(msg.speakerName + ': ' + msg.message);
});

The command and event API uses a familiar Bot.<command>() / Bot.on('event', handler) shape, so existing bot scripts from comparable platforms usually paste straight in with little or no change.

Good to know

  • Almost every Bot.<command>() returns a Promise; use await or .then().
  • Unless it returns a bare scalar, every command resolves to an object that always includes success (bool) and, on failure, error (string). Command-specific fields are added on top.
  • Avatars/objects are SL UUIDs (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx). Many avatar params accept either a UUID or a 'First Last' name.
  • scanNearbyAvatars camelCases CBaseBots PascalCase keys by lowercasing only the first character, so the avatar UUID key surfaces as uUID (not uuid).
  • Scripts may only target bots the running user owns.

Use the menu on the left, or start typing to filter. Pick a command or event to see its parameters, return fields, and examples.

LifeBots Workshop

Selling your scripts

You can publish a Workshop script to the LifeBots addon store and earn L$ when other users buy it. Buyers can run your script on their own bot and configure its settings — but they can never see your source code. Your code stays protected on the server.

How source protection works

When you publish a version, the Workshop snapshots your code into a release on the server. That release is never sent to any browser. Each buyer gets an owned copy that stores their bot choice and settings but holds no code — when they press Run, the runtime loads your code server-side. The result: buyers run exactly the version you shipped, with zero visibility into how it works.

A buyer's copy is run-only. They choose which bot it drives and fill in any settings you exposed, then start/stop it like any Workshop script — the editor and source are hidden for purchased scripts.

Step 1 — Build and test your script

Write and debug your script normally in the Workshop, attached to one of your own bots. Get it working end-to-end before you think about selling — buyers run the exact code you publish.

Step 2 — Expose settings (optional, recommended)

Most sellable scripts need per-buyer configuration (a greeting message, a group key, an API token…). Instead of hard-coding these, define a user settings schema — a list of fields (text, textarea, number, select, or checkbox) that buyers fill in on a simple form. Number fields can declare an optional min/max range that the buyer's form enforces, so you don't have to bounds-check in the script. Read them in your code via the userSettings global:

const greeting = userSettings.greeting || 'Hello!';
await Bot.say(0, greeting);

The schema is snapshotted into each release, so a buyer always sees the field set that matches the version they run. Never put secrets you don't want buyers to control in code — expose them as settings the buyer provides instead.

Step 3 — Cut a version

On the script's Versioning tab, publish a release with a MAJOR.MINOR.PATCH version (e.g. 1.0.0). This snapshots your current code + settings schema. Rules:

  • The script can't be empty.
  • Each new version must be strictly greater than the last (1.0.1 > 1.0.0).
  • You need at least one release before the script can go on sale.

Cutting a version is independent of listing for sale — you can version privately and only enable sale later.

Step 4 — Fill in the store listing

On the Listing tab, provide the details buyers see in the store:

FieldNotes
Store nameDisplay name in the store (up to 80 chars). Defaults to the script name.
Short descriptionStore-card blurb. Required to sell — at least 10 characters (max 280).
Long descriptionFull details on the addon page. Markdown supported (max 8000 chars).
PriceWhole L$, from 0 to 1,000,000. 0 = free.
CategoryOptional grouping label.
Store imagesOn the Store Images tab. At least one https:// image is required to sell (up to 8).
ContactsOptional support contacts (up to 10).

Step 5 — Turn on “Available for sale”

Flip the Available for sale toggle on the Listing tab. Before it can go live you must have: at least one published version, a short description of 10+ characters, and at least one store image. Toggle it off any time to pull the script from sale — existing buyers keep their copies and can still run them.

Step 6 — Approval

Your listing is mirrored into the LifeBots store. Trusted developers are auto-approved and go live immediately. Everyone else starts as Pending until a LifeBots admin reviews and activates the listing. The script's status badge (Live / Pending / Hidden) shows where it stands.

Step 7 — Preview as a buyer

Use Test purchase to install your own script the way a buyer would — schema-driven settings form, no source visible, run on a bot. It skips the wallet and the published check (but still needs a release). Remove the test copies when you're done; they don't affect real buyers.

Pricing & earnings

  • Buyers pay from their L$ wallet; the price transfers to your wallet instantly, with an audit transaction on both sides.
  • Free scripts (price 0) skip the wallet entirely.
  • A buyer who already owns a script won't be charged again — re-buying just returns their existing copy.
  • You can't buy your own script (it's already in your authored list).

Updating buyers after release

Each buyer is pinned to the release they're running, so a new version never changes their behavior unexpectedly. To ship an update, cut a new version (Step 3), then:

  • Buyers see an “update available” flag and can update themselves, with a changelog of what's new.
  • From your Sales view you can push one buyer — or all buyers — to the latest release; running copies restart automatically onto the new code.
  • Publishing with force update moves every buyer to the new release at once.

The Sales view also reports each buyer (name censored for privacy), the version they're on, their run status, and whether they're behind. Buyers who own a script can rate it 1–5 stars.

Summary: build & test → expose settings → cut a version → write the listing + add an image → enable “Available for sale” → (get approved) → earn L$ as buyers run your protected code.
Reference

Globals & built-in functions

The basic built-in functions do not relate to bot functionality. Instead, they let you write flexible scripts. Each script runs in its own isolated-vm V8 Isolate with a private heap and no shared memory with the host. The script's top-level code runs once at start; top-level await is supported. Any Bot.on(...) handlers you register keep firing after the top-level finishes, until the script is stopped or calls process.exit().

setTimeout(function () {
  console.log("Timer has fired!");
}, 3000);

List of functions

Click any function for its parameters, return value, and examples.

Script details & flow
process.nameRead-only property reflecting the running script's display name (shown in the left panel).
process.releaseRead-only property reflecting the script release version (for store scripts).
process.exitEnds execution of the script.
process.sleepPauses script execution for the given number of milliseconds.
Timer control
setTimeoutRuns a callback once after a delay (ms).
clearTimeoutCancels a pending setTimeout by its id.
setIntervalRuns a callback repeatedly every ms.
clearIntervalStops a repeating setInterval by its id.
Persistent bot storage
localStorage.getRestores a string value from persistent storage.
localStorage.setPuts a string value into persistent storage.
localStorage.keysReturns the list of available keys in persistent storage (for this bot).
localStorage.removeDeletes a key. localStorage.delete() is an alias.
localStorage.onAdds an event callback on localStorage. selector = a key name fires handler(oldValue, newValue) on any write to that key (including this…
User settings
userSettingsAccess any configured setting as a property, e.g. userSettings.systemPrompt.
HTTP
http.getRetrieves data from an HTTP source via GET.
http.postSends data to an HTTP source via POST.
http.requestWebhookUrlAllocates a new per-run webhook URL and bearer token for this script instance.
Debug
console.logLogs data to the runtime log. console.info and console.debug behave the same.
console.warnLogs data at the 'warn' level.
console.errorLogs data at the 'error' level.
_assertLogs an error line if the assertion is false.

The Bot object

Command surface + Bot.on/off + Bot.AI. It is a Proxy: any unknown method (Bot.somecommand(...)) is dispatched to the host, so every command in the Commands list is callable even though it isn’t a literal property. bot is an alias of Bot.

PropertyTypeDescription
Bot.agentIdstringThe bot’s avatar UUID.
Bot.namestringThe bot’s Second Life name.
  • Bot.<command>(...args) — any command in the sidebar; returns a Promise.
  • Bot.on(event, handler) / Bot.off(event, handler?) — subscribe / unsubscribe to events (chainable).

Not available

User scripts run in a true V8 sandbox — the following are intentionally absent:

  • require() and import — there is no module system; static import/require is rejected before the script runs
  • Node's real process — only the sandboxed process shim is exposed
  • Node core modules — fs, path, os, net, child_process, crypto, etc.
  • Buffer
  • fetch / XMLHttpRequest / WebSocket — use http.get / http.post instead
  • DOM / window / document — there is no browser environment

Safety & resource caps

User code cannot reach the host. Inputs/outputs cross the boundary by deep clone, Error.prepareStackTrace is locked, and the host injection slots are wiped after bootstrap. Runaway scripts are bounded by per-call CPU timeouts, a heap cap, and a sustained-CPU monitor (see Limits). See Limits for the exact numbers.

Built-ins › process

process.name

Read-only property reflecting the running script's display name (shown in the left panel).

Example

console.log(process.name);
Built-ins › process

process.release

Read-only property reflecting the script release version (for store scripts). Currently always an empty string in this runtime.

Example

console.log(process.release);
Built-ins › process

process.exit()

Ends execution of the script. Sets the script's desiredState to 'stopped' (one-shot scripts do not auto-resume) and disposes the isolate.

Usage

await Bot.say(0, 'done');
process.exit();

Input

None.

Returns

Does not return — throws internally to halt the script

Built-ins › process

process.sleep(ms)

Pauses script execution for the given number of milliseconds.

Usage

await process.sleep(2000);

Input

VariableRequiredDescription
msyesMilliseconds to pause

Returns

Promise (resolves after ms)

Built-ins › Timers

setTimeout(fn, ms, ...args)

Runs a callback once after a delay (ms). Returns a numeric timer id that can be passed to clearTimeout.

Usage

const id = setTimeout((name) => console.log('hi ' + name), 1000, 'Bob');
// clearTimeout(id); // to cancel before it fires

Input

VariableRequiredDescription
fnyesCallback to run
msyesDelay in milliseconds
...argsnoExtra arguments passed to the callback

Returns

number — timer id (use with clearTimeout)

Built-ins › Timers

clearTimeout(id)

Cancels a pending setTimeout by its id.

Usage

const id = setTimeout(() => console.log('hi'), 5000);
clearTimeout(id); // cancels it before it fires

Input

VariableRequiredDescription
idyesTimer id returned by setTimeout

Returns

undefined (synchronous)

Built-ins › Timers

setInterval(fn, ms, ...args)

Runs a callback repeatedly every ms. Returns a numeric timer id for clearInterval. The next tick is scheduled only after the previous callback resolves.

Usage

let n = 0;
const id = setInterval(() => {
  if (++n >= 5) clearInterval(id);
  console.log('tick', n);
}, 5000);

Input

VariableRequiredDescription
fnyesCallback to run each interval
msyesInterval in milliseconds
...argsnoExtra arguments passed to the callback

Returns

number — timer id (use with clearInterval)

Built-ins › Timers

clearInterval(id)

Stops a repeating setInterval by its id.

Usage

const id = setInterval(() => console.log('tick'), 1000);
clearInterval(id); // stops the repeating timer

Input

VariableRequiredDescription
idyesTimer id returned by setInterval

Returns

undefined (synchronous)

Built-ins › localStorage

localStorage.get(key)

Restores a string value from persistent storage.

Usage

const v = await localStorage.get('runs');

Input

VariableRequiredDescription
keyyesKey to read

Returns

Promise<string|null> — the value, or null if unset

Built-ins › localStorage

localStorage.set(key, value)

Puts a string value into persistent storage.

Usage

await localStorage.set('runs', String(n));

Input

VariableRequiredDescription
keyyesKey to write
valueyesValue to store

Returns

Promise (resolves once written)

Built-ins › localStorage

localStorage.keys()

Returns the list of available keys in persistent storage (for this bot).

Usage

const keys = await localStorage.keys();

Input

None.

Returns

Promise<string[]>

Built-ins › localStorage

localStorage.remove(key)

Deletes a key. localStorage.delete() is an alias.

Usage

await localStorage.remove('runs');

Input

VariableRequiredDescription
keyyesKey to delete

Returns

Promise (resolves once removed)

Built-ins › localStorage

localStorage.on(selector, handler)

Adds an event callback on localStorage. selector = a key name fires handler(oldValue, newValue) on any write to that key (including this script's own writes). selector = 'update' (or its alias 'change') fires handler(key, newValue, scriptName) for CROSS-script writes only.

Usage

localStorage.on('update', (key, val, fromScript) => {
  console.log(fromScript + ' set ' + key + ' = ' + val);
});

Input

VariableRequiredDescription
selectoryesA key name, or 'update' / 'change'
handleryesCallback (signature depends on selector)

Returns

undefined (registers the observer)

Built-ins › userSettings

userSettings

Access any configured setting as a property, e.g. userSettings.systemPrompt. Values are whatever the settings form produced (usually strings) — coerce as needed.

Example

const prompt = userSettings.systemPrompt || 'You are helpful.';
const temp = parseFloat(userSettings.temperature) || 0.7;
Built-ins › http

http.get(url, opts)

Retrieves data from an HTTP source via GET. Returns the response body as text; throws on non-2xx, redirect, SSRF block, timeout, or oversize body.

Usage

const body = await http.get('https://api.example.com/data');
const data = JSON.parse(body);

Input

VariableRequiredDescription
urlyeshttp/https URL
optsno{ headers? }

Returns

Promise<string> — the response body text

Built-ins › http

http.post(url, data, opts)

Sends data to an HTTP source via POST. A string body is sent as-is (text/plain); an object is JSON-stringified with Content-Type application/json. Returns the response body text.

Usage

const res = await http.post('https://api.example.com/echo', { hello: 'world' });

Input

VariableRequiredDescription
urlyeshttp/https URL
datayesString body, or object (sent as JSON)
optsno{ headers? }

Returns

Promise<string> — the response body text

Built-ins › http

http.requestWebhookUrl()

Allocates a new per-run webhook URL and bearer token for this script instance. Inbound HTTP hits to the URL fire the workshop_webhook event. Callers must send 'Authorization: Bearer <token>'.

Usage

const hook = await http.requestWebhookUrl();
Bot.on('workshop_webhook', (e) => console.log(e.payload));

Input

None.

Returns

Promise<{ success, url, token }>

Output fields

FieldTypeDescription
successbooltrue if allocation succeeded
urlstringThe public webhook URL
tokenstringBearer token callers must send
Built-ins › Debug

console.log(...args)

Logs data to the runtime log. console.info and console.debug behave the same.

Usage

console.log('user', { name: 'Bob' });

Input

VariableRequiredDescription
...argsyesAny values; objects are JSON-stringified, Errors print their stack

Returns

undefined

Built-ins › Debug

console.warn(...args)

Logs data at the 'warn' level.

Usage

console.warn('careful').then(function (res) {
  console.log("console.warn response:", res);
});

Or using async/await:

let res = await console.warn('careful');
console.log("console.warn response:", res);

Input

VariableRequiredDescription
...argsyesAny values

Returns

undefined

Built-ins › Debug

console.error(...args)

Logs data at the 'error' level.

Usage

console.error('failed:', err).then(function (res) {
  console.log("console.error response:", res);
});

Or using async/await:

let res = await console.error('failed:', err);
console.log("console.error response:", res);

Input

VariableRequiredDescription
...argsyesAny values

Returns

undefined

Built-ins › Debug

_assert(cond, message)

Logs an error line if the assertion is false. Does NOT throw — execution continues.

Usage

_assert(result.success, 'command should have succeeded');

Input

VariableRequiredDescription
condyesCondition to assert
messagenoMessage logged when cond is falsy

Returns

undefined

Commands › Status / Lifecycle

Bot.status()

Returns the bot's online status and location.

Usage

Bot.status().then(function (res) {
  console.log("status response:", res);
});

Or using async/await:

let res = await Bot.status();
console.log("status response:", res);

Input

None.

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed
statusstringConnection status, e.g. "ONLINE"
onlinestring"1" if the bot is online
slnamestringBot's Second Life name
uuidstringBot's avatar UUID
locationstringCurrent position, format "Region/X/Y/Z"

Example response

{
  "success": true,
  "status": "ONLINE",
  "online": "1",
  "slname": "My Bot",
  "uuid": "0b65a122-8f77-64fe-5b2a-225d4c490d9c",
  "location": "Mainland/128/128/25"
}
Commands › Status / Lifecycle

Bot.statusExt()

Status with extended fields. CBaseBots currently returns the same shape as status() (no extra fields are added today).

Usage

Bot.statusExt().then(function (res) {
  console.log("statusExt response:", res);
});

Or using async/await:

let res = await Bot.statusExt();
console.log("statusExt response:", res);

Input

None.

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed
statusstringConnection status, e.g. "ONLINE"
onlinestring"1" if the bot is online
slnamestringBot's Second Life name
uuidstringBot's avatar UUID
locationstringCurrent position, format "Region/X/Y/Z"
Commands › Status / Lifecycle

Bot.isOnline()

Returns a bare boolean — true if the bot is online.

Usage

Bot.isOnline().then(function (res) {
  console.log("isOnline response:", res);
});

Or using async/await:

let res = await Bot.isOnline();
console.log("isOnline response:", res);

Input

None.

Output

FieldTypeDescription
(return value)booltrue if the bot is currently online, false otherwise
Commands › Status / Lifecycle

Bot.login()

Logs the bot in.

Usage

Bot.login().then(function (res) {
  console.log("login response:", res);
});

Or using async/await:

let res = await Bot.login();
console.log("login response:", res);

Input

None.

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed
resulttextstringPresent when already logged in ("Bot is already logged in")
Commands › Status / Lifecycle

Bot.logout()

Logs the bot out.

Usage

Bot.logout().then(function (res) {
  console.log("logout response:", res);
});

Or using async/await:

let res = await Bot.logout();
console.log("logout response:", res);

Input

None.

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed
Commands › Messaging

Bot.say(channel, message)

Sends a chat message on a channel. Channel 0 is local nearby chat.

Usage

Bot.say(0, 'Hello, world').then(function (res) {
  console.log("say response:", res);
});

Or using async/await:

let res = await Bot.say(0, 'Hello, world');
console.log("say response:", res);

Input

VariableRequiredDescription
channelyesChat channel. 0 = local nearby chat; any integer otherwise
messageyesText to send

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed
resulttextstring"Message sent"

Example response

{
  "success": true,
  "resulttext": "Message sent"
}
Commands › Messaging

Bot.im(name_or_UUID, message)

Sends an instant message to an avatar.

Usage

Bot.im('0b65a122-8f77-64fe-5b2a-225d4c490d9c', 'Hi there!').then(function (res) {
  console.log("im response:", res);
});

Or using async/await:

let res = await Bot.im('0b65a122-8f77-64fe-5b2a-225d4c490d9c', 'Hi there!');
console.log("im response:", res);

Input

VariableRequiredDescription
name_or_UUIDyesAvatar UUID or "First Last" name
messageyesText to send

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed
resulttextstring"IM sent"

Example response

{
  "success": true,
  "resulttext": "IM sent"
}
Commands › Messaging

Bot.startTyping(uuid, delay)

Shows the typing indicator in an IM session.

Usage

Bot.startTyping('0b65a122-8f77-64fe-5b2a-225d4c490d9c').then(function (res) {
  console.log("startTyping response:", res);
});

Or using async/await:

let res = await Bot.startTyping('0b65a122-8f77-64fe-5b2a-225d4c490d9c');
console.log("startTyping response:", res);

Input

VariableRequiredDescription
uuidyesTarget avatar UUID
delaynoSeconds before it auto-clears (default 15)

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed
Commands › Messaging

Bot.stopTyping(uuid)

Stops the typing indicator.

Usage

Bot.stopTyping('0b65a122-8f77-64fe-5b2a-225d4c490d9c').then(function (res) {
  console.log("stopTyping response:", res);
});

Or using async/await:

let res = await Bot.stopTyping('0b65a122-8f77-64fe-5b2a-225d4c490d9c');
console.log("stopTyping response:", res);

Input

VariableRequiredDescription
uuidyesTarget avatar UUID

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed
Commands › Messaging

Bot.replyDialog(channel, object, button)

Presses a button on a received script dialog (see the script_dialog event).

Usage

Bot.replyDialog(1, '0b65a122-8f77-64fe-5b2a-225d4c490d9c', 'Yes').then(function (res) {
  console.log("replyDialog response:", res);
});

Or using async/await:

let res = await Bot.replyDialog(1, '0b65a122-8f77-64fe-5b2a-225d4c490d9c', 'Yes');
console.log("replyDialog response:", res);

Input

VariableRequiredDescription
channelyesDialog channel (from the script_dialog event)
objectyesObject UUID (from the event)
buttonyesButton label to press

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed
replystringThe button label that was pressed
Commands › Friendship

Bot.friends()

Returns the bot's friends list and the friendship rights on each side.

Usage

Bot.friends().then(function (res) {
  console.log("friends response:", res);
});

Or using async/await:

let res = await Bot.friends();
console.log("friends response:", res);

Input

None.

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed
friendsarrayArray of friend objects (see below)
friends[].slnamestringFriend's SL name
friends[].uuidstringFriend's avatar UUID
friends[].onlinebooltrue if the friend is online
friends[].theirRightsobject{ canSeeOnMap, canSeeOnline, canModifyObjects } — rights they granted the bot
friends[].myRightsobject{ canSeeOnMap, canSeeOnline, canModifyObjects } — rights the bot granted them

Example response

{
  "success": true,
  "friends": [
    {
      "slname": "Resident One",
      "uuid": "11111111-2222-3333-4444-555555555555",
      "online": true,
      "theirRights": {
        "canSeeOnMap": false,
        "canSeeOnline": true,
        "canModifyObjects": false
      },
      "myRights": {
        "canSeeOnMap": false,
        "canSeeOnline": true,
        "canModifyObjects": false
      }
    }
  ]
}
Commands › Friendship

Bot.offerFriendship(avatar, message)

Sends a friend request to an avatar.

Usage

Bot.offerFriendship('0b65a122-8f77-64fe-5b2a-225d4c490d9c', 'Be my friend').then(function (res) {
  console.log("offerFriendship response:", res);
});

Or using async/await:

let res = await Bot.offerFriendship('0b65a122-8f77-64fe-5b2a-225d4c490d9c', 'Be my friend');
console.log("offerFriendship response:", res);

Input

VariableRequiredDescription
avataryesAvatar UUID or name
messagenoOffer message (default "Be my friend")

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed
Commands › Friendship

Bot.acceptFriendshipOffer(avatar_uuid, session_id, accept)

Accepts or rejects a pending friendship offer. session_id comes from the friendship_offer event.

Usage

Bot.acceptFriendshipOffer('0b65a122-8f77-64fe-5b2a-225d4c490d9c', 'session-uuid', true).then(function (res) {
  console.log("acceptFriendshipOffer response:", res);
});

Or using async/await:

let res = await Bot.acceptFriendshipOffer('0b65a122-8f77-64fe-5b2a-225d4c490d9c', 'session-uuid', true);
console.log("acceptFriendshipOffer response:", res);

Input

VariableRequiredDescription
avatar_uuidyesOffering avatar's UUID
session_idyesSession id from the friendship_offer event
acceptnotrue to accept, false to reject (default true)

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed
resulttextstring"Friendship accepted" or "Friendship declined"
Commands › Friendship

Bot.cancelFriendship(uuid)

Removes a friend (LifeBots extension).

Usage

Bot.cancelFriendship('0b65a122-8f77-64fe-5b2a-225d4c490d9c').then(function (res) {
  console.log("cancelFriendship response:", res);
});

Or using async/await:

let res = await Bot.cancelFriendship('0b65a122-8f77-64fe-5b2a-225d4c490d9c');
console.log("cancelFriendship response:", res);

Input

VariableRequiredDescription
uuidyesFriend's avatar UUID

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed
Commands › Group

Bot.activateGroup(groupuuid)

Sets the bot's active group tag.

Usage

Bot.activateGroup('group-uuid').then(function (res) {
  console.log("activateGroup response:", res);
});

Or using async/await:

let res = await Bot.activateGroup('group-uuid');
console.log("activateGroup response:", res);

Input

VariableRequiredDescription
groupuuidyesGroup UUID

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed
Commands › Group

Bot.listGroups()

Lists the groups the bot has joined.

Usage

Bot.listGroups().then(function (res) {
  console.log("listGroups response:", res);
});

Or using async/await:

let res = await Bot.listGroups();
console.log("listGroups response:", res);

Input

None.

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed
groupsstringNewline-delimited "groupUUID;groupName" pairs (NOT an array)

Example response

{
  "success": true,
  "groups": "11111111-...;My Group\n22222222-...;Another Group"
}
Commands › Group

Bot.groupInfo(groupUUID)

Returns details about a group.

Usage

Bot.groupInfo('group-uuid').then(function (res) {
  console.log("groupInfo response:", res);
});

Or using async/await:

let res = await Bot.groupInfo('group-uuid');
console.log("groupInfo response:", res);

Input

VariableRequiredDescription
groupUUIDyesGroup UUID

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed
namestringGroup name
uuidstringGroup UUID
charterstringGroup charter text
membersnumberMember count
member_titlestringBot's title in the group
insigniastringGroup insignia texture UUID
founderstringFounder avatar UUID
feenumberMembership fee (L$)
openbooltrue if open enrollment
maturebooltrue if mature-rated
Commands › Group

Bot.joinGroup(groupuuid)

Joins a group by UUID.

Usage

Bot.joinGroup('group-uuid').then(function (res) {
  console.log("joinGroup response:", res);
});

Or using async/await:

let res = await Bot.joinGroup('group-uuid');
console.log("joinGroup response:", res);

Input

VariableRequiredDescription
groupuuidyesGroup UUID

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed
Commands › Group

Bot.leaveGroup(groupuuid)

Leaves a group by UUID.

Usage

Bot.leaveGroup('group-uuid').then(function (res) {
  console.log("leaveGroup response:", res);
});

Or using async/await:

let res = await Bot.leaveGroup('group-uuid');
console.log("leaveGroup response:", res);

Input

VariableRequiredDescription
groupuuidyesGroup UUID

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed
Commands › Group

Bot.ejectGroupMember(avatar, groupuuid)

Ejects a member from a group.

Usage

Bot.ejectGroupMember('avatar-uuid', 'group-uuid').then(function (res) {
  console.log("ejectGroupMember response:", res);
});

Or using async/await:

let res = await Bot.ejectGroupMember('avatar-uuid', 'group-uuid');
console.log("ejectGroupMember response:", res);

Input

VariableRequiredDescription
avataryesMember's avatar UUID or name
groupuuidyesGroup UUID

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed
Commands › Group

Bot.setGroupRole(avatar_uuid, group_uuid, role_uuid)

Adds a member to a group role.

Usage

Bot.setGroupRole('avatar-uuid', 'group-uuid', 'role-uuid').then(function (res) {
  console.log("setGroupRole response:", res);
});

Or using async/await:

let res = await Bot.setGroupRole('avatar-uuid', 'group-uuid', 'role-uuid');
console.log("setGroupRole response:", res);

Input

VariableRequiredDescription
avatar_uuidyesMember's avatar UUID
group_uuidyesGroup UUID
role_uuidyesRole UUID

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed
Commands › Group

Bot.revokeGroupRole(avatar_uuid, group_uuid, role_uuid)

Removes a member from a group role.

Usage

Bot.revokeGroupRole('avatar-uuid', 'group-uuid', 'role-uuid').then(function (res) {
  console.log("revokeGroupRole response:", res);
});

Or using async/await:

let res = await Bot.revokeGroupRole('avatar-uuid', 'group-uuid', 'role-uuid');
console.log("revokeGroupRole response:", res);

Input

VariableRequiredDescription
avatar_uuidyesMember's avatar UUID
group_uuidyesGroup UUID
role_uuidyesRole UUID

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed
Commands › Group

Bot.sendGroupIM(groupuuid, message)

Sends a message to a group's chat session.

Usage

Bot.sendGroupIM('group-uuid', 'Hello group!').then(function (res) {
  console.log("sendGroupIM response:", res);
});

Or using async/await:

let res = await Bot.sendGroupIM('group-uuid', 'Hello group!');
console.log("sendGroupIM response:", res);

Input

VariableRequiredDescription
groupuuidyesGroup UUID
messageyesText to send

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed
groupUUIDstringThe group UUID the message was sent to
Commands › Group

Bot.sendNotice(groupuuid, subject, text, attachment)

Sends a group notice, optionally with an inventory attachment.

Usage

Bot.sendNotice('group-uuid', 'Meeting', 'See you at 5pm', '').then(function (res) {
  console.log("sendNotice response:", res);
});

Or using async/await:

let res = await Bot.sendNotice('group-uuid', 'Meeting', 'See you at 5pm', '');
console.log("sendNotice response:", res);

Input

VariableRequiredDescription
groupuuidyesGroup UUID
subjectyesNotice subject
textyesNotice body
attachmentnoInventory item UUID to attach (default none)

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed
groupUUIDstringThe group UUID the notice was sent to
Commands › Group

Bot.acceptGroupOffer(avatar_uuid, session_id, accept)

Accepts or rejects a group invite. session_id comes from the group_offer event.

Usage

Bot.acceptGroupOffer('avatar-uuid', 'session-uuid', true).then(function (res) {
  console.log("acceptGroupOffer response:", res);
});

Or using async/await:

let res = await Bot.acceptGroupOffer('avatar-uuid', 'session-uuid', true);
console.log("acceptGroupOffer response:", res);

Input

VariableRequiredDescription
avatar_uuidyesInviting avatar UUID
session_idyesSession id from the group_offer event
acceptnotrue to accept, false to reject (default true)

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed
resulttextstring"Group invite accepted" or "Group invite declined"
Commands › Group

Bot.inviteGroup(avatar, groupuuid, roleuuid, check_membership)

Invites an avatar to a group, optionally into a specific role.

Usage

Bot.inviteGroup('avatar-uuid', 'group-uuid', '', true).then(function (res) {
  console.log("inviteGroup response:", res);
});

Or using async/await:

let res = await Bot.inviteGroup('avatar-uuid', 'group-uuid', '', true);
console.log("inviteGroup response:", res);

Input

VariableRequiredDescription
avataryesAvatar UUID or name to invite
groupuuidyesGroup UUID
roleuuidnoRole UUID (default everyone role)
check_membershipnoIf truthy, skip avatars already in the group

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed
resulttextstring"Group invite sent"
Commands › Inventory

Bot.listInventory(folderUUID)

Lists the contents of an inventory folder (root if omitted).

Usage

Bot.listInventory().then(function (res) {
  console.log("listInventory response:", res);
});

Or using async/await:

let res = await Bot.listInventory();
console.log("listInventory response:", res);

Input

VariableRequiredDescription
folderUUIDnoFolder UUID; root folder if omitted

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed
itemsarrayArray of inventory entries (see below)
items[].idstringItem or folder UUID
items[].namestringItem or folder name
items[].typestringAsset type (e.g. notecard, object, folder)
items[].folderTypenumberFolder type code (folders only)
Commands › Inventory

Bot.giveInventory(avatar, object)

Gives an inventory item (or folder) to an avatar.

Usage

Bot.giveInventory('avatar-uuid', 'item-uuid').then(function (res) {
  console.log("giveInventory response:", res);
});

Or using async/await:

let res = await Bot.giveInventory('avatar-uuid', 'item-uuid');
console.log("giveInventory response:", res);

Input

VariableRequiredDescription
avataryesRecipient avatar UUID or name
objectyesInventory item or folder UUID

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed
resulttextstring"Inventory item given" or "Inventory folder given"
Commands › Inventory

Bot.deleteInventory(uuid)

Deletes an inventory item.

Usage

Bot.deleteInventory('item-uuid').then(function (res) {
  console.log("deleteInventory response:", res);
});

Or using async/await:

let res = await Bot.deleteInventory('item-uuid');
console.log("deleteInventory response:", res);

Input

VariableRequiredDescription
uuidyesInventory item UUID

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed
Commands › Inventory

Bot.acceptInventoryOffer(sender_type, object_id, sender_uuid, folder, session, accept)

Accepts or rejects an inventory offer (see the inventory_offer event).

Usage

Bot.acceptInventoryOffer('agent', '', 'sender-uuid', '', 'session-uuid', true).then(function (res) {
  console.log("acceptInventoryOffer response:", res);
});

Or using async/await:

let res = await Bot.acceptInventoryOffer('agent', '', 'sender-uuid', '', 'session-uuid', true);
console.log("acceptInventoryOffer response:", res);

Input

VariableRequiredDescription
sender_typeno"agent" or "object" (default "agent")
object_idnoObject UUID if the sender is an object
sender_uuidyesSender's avatar UUID
foldernoDestination folder UUID
sessionyesSession id from the inventory_offer event
acceptnotrue to accept, false to reject (default true)

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed
resulttextstring"Inventory accepted" or "Inventory declined"
Commands › Inventory

Bot.createNotecard(folder, name, description, text)

Creates a notecard in inventory.

Usage

Bot.createNotecard('', 'My Notecard', 'A note', 'Hello from a notecard.').then(function (res) {
  console.log("createNotecard response:", res);
});

Or using async/await:

let res = await Bot.createNotecard('', 'My Notecard', 'A note', 'Hello from a notecard.');
console.log("createNotecard response:", res);

Input

VariableRequiredDescription
foldernoDestination folder UUID (root if omitted)
nameyesNotecard name
descriptionnoNotecard description
textyesNotecard body text

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed
uuidstringUUID of the newly created notecard
Commands › Inventory

Bot.editNotecard(uuid, text)

Replaces a notecard's text.

Usage

Bot.editNotecard('notecard-uuid', 'New content').then(function (res) {
  console.log("editNotecard response:", res);
});

Or using async/await:

let res = await Bot.editNotecard('notecard-uuid', 'New content');
console.log("editNotecard response:", res);

Input

VariableRequiredDescription
uuidyesNotecard UUID
textyesNew body text

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed
Commands › Inventory

Bot.readNotecard(uuid)

Reads a notecard's text.

Usage

Bot.readNotecard('notecard-uuid').then(function (res) {
  console.log("readNotecard response:", res);
});

Or using async/await:

let res = await Bot.readNotecard('notecard-uuid');
console.log("readNotecard response:", res);

Input

VariableRequiredDescription
uuidyesNotecard UUID

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed
textstringThe notecard's body text
Commands › Appearance

Bot.wear(uuid)

Wears / attaches an inventory item.

Usage

Bot.wear('item-uuid').then(function (res) {
  console.log("wear response:", res);
});

Or using async/await:

let res = await Bot.wear('item-uuid');
console.log("wear response:", res);

Input

VariableRequiredDescription
uuidyesInventory item UUID

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed
itemNamestringName of the worn item
resulttextstringHuman-readable result message
Commands › Appearance

Bot.takeoff(uuid)

Detaches / takes off an item.

Usage

Bot.takeoff('item-uuid').then(function (res) {
  console.log("takeoff response:", res);
});

Or using async/await:

let res = await Bot.takeoff('item-uuid');
console.log("takeoff response:", res);

Input

VariableRequiredDescription
uuidyesInventory item UUID

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed
resulttextstringe.g. "Detached <item>"
Commands › Money

Bot.getBalance()

Returns the bot's L$ balance.

Usage

Bot.getBalance().then(function (res) {
  console.log("getBalance response:", res);
});

Or using async/await:

let res = await Bot.getBalance();
console.log("getBalance response:", res);

Input

None.

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed
balancenumberCurrent L$ balance

Example response

{
  "success": true,
  "balance": 1250
}
Commands › Money

Bot.giveMoney(avatar, amount, comment)

Sends L$ to an avatar.

Usage

Bot.giveMoney('avatar-uuid', 100, 'Thanks!').then(function (res) {
  console.log("giveMoney response:", res);
});

Or using async/await:

let res = await Bot.giveMoney('avatar-uuid', 100, 'Thanks!');
console.log("giveMoney response:", res);

Input

VariableRequiredDescription
avataryesRecipient avatar UUID or name
amountyesAmount of L$ to send
commentnoTransaction comment

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed
Commands › Movement

Bot.fly(enableFlying)

Toggles flying mode.

Usage

Bot.fly(true).then(function (res) {
  console.log("fly response:", res);
});

Or using async/await:

let res = await Bot.fly(true);
console.log("fly response:", res);

Input

VariableRequiredDescription
enableFlyingyesTruthy to fly, falsy to stop flying

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed
Commands › Movement

Bot.getLocation()

Returns the bot's current region and position.

Usage

Bot.getLocation().then(function (res) {
  console.log("getLocation response:", res);
});

Or using async/await:

let res = await Bot.getLocation();
console.log("getLocation response:", res);

Input

None.

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed
regionstringRegion name
xnumberX position in region
ynumberY position in region
znumberZ position (height)

Example response

{
  "success": true,
  "region": "Mainland",
  "x": 128.5,
  "y": 64.2,
  "z": 25
}
Commands › Movement

Bot.move(instruction, state)

Low-level movement control — start/stop directional movement.

Usage

Bot.move('FORWARD', 'START').then(function (res) {
  console.log("move response:", res);
});

Or using async/await:

let res = await Bot.move('FORWARD', 'START');
console.log("move response:", res);

Input

VariableRequiredDescription
instructionyesOne of FORWARD, BACK, LEFT, RIGHT, FLY, STOP
stateyesSTART or STOP

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed
Commands › Movement

Bot.sit(uuid, save)

Sits the bot on a prim. uuid="NONE" stands the bot up.

Usage

Bot.sit('prim-uuid').then(function (res) {
  console.log("sit response:", res);
});

Or using async/await:

let res = await Bot.sit('prim-uuid');
console.log("sit response:", res);

Input

VariableRequiredDescription
uuidnoPrim UUID to sit on; "NONE" stands up (default "NONE")
savenoIf truthy, save as permanent sit location

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed
messagestringHuman-readable result (e.g. "Sitting")
Commands › Movement

Bot.stand()

Stands the bot up. Alias of sit("NONE").

Usage

Bot.stand().then(function (res) {
  console.log("stand response:", res);
});

Or using async/await:

let res = await Bot.stand();
console.log("stand response:", res);

Input

None.

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed
messagestringHuman-readable result
Commands › Movement

Bot.teleport(location)

Teleports the bot to a location.

Usage

Bot.teleport('Mainland/128/128/25').then(function (res) {
  console.log("teleport response:", res);
});

Or using async/await:

let res = await Bot.teleport('Mainland/128/128/25');
console.log("teleport response:", res);

Input

VariableRequiredDescription
locationyes"Region/X/Y/Z" or "HOME"

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed
resulttextstring"Teleported to <region>" on success
Commands › Movement

Bot.walkTo(x, y, z)

Walks (autopilot) to a position in the current region. Fires autopilot_* events. Each call first stops the bot and switches flying off, and coordinates are rounded down to whole metres — to re-aim a moving bot often (e.g. following an avatar) use moveTo, and to fly use flyTo.

Usage

Bot.walkTo(128, 128, 25).then(function (res) {
  console.log("walkTo response:", res);
});

Or using async/await:

let res = await Bot.walkTo(128, 128, 25);
console.log("walkTo response:", res);

Input

VariableRequiredDescription
xyesTarget X in region
yyesTarget Y in region
zyesTarget Z (height)

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed
resulttextstring"Walking to <x>, <y>, <z>"
Commands › Movement

Bot.moveTo(x, y, z, options)

Walks to a position in the current region with continuous steering. Unlike walkTo it never stops the bot between calls — a new call just moves the target — and it keeps decimal precision, so it suits scripts that re-aim often, such as following an avatar. Runs in the background and ends on arrival (within 0.75 m), after 3 s without progress, or when another movement command is sent. Honours alwaysRun. Does not fire autopilot_* events. Within 3 m of a target point that has stopped moving it automatically slows down and stops on the point instead of coasting past (a point you keep re-aiming ahead of a moving avatar keeps normal speed). Pass { slow: true } to walk slowly the whole way.

Usage

Bot.moveTo(128.5, 64.2, 25).then(function (res) {
  console.log("moveTo response:", res);
});

Or using async/await:

let res = await Bot.moveTo(128.5, 64.2, 25);
console.log("moveTo response:", res);

Input

VariableRequiredDescription
xyesTarget X in region
yyesTarget Y in region
zyesTarget Z (height); ignored while walking
optionsnoOptional { slow: true }: the bot walks very slowly and stops dead on the point instead of coasting past it (holds the server STOP control, like holding the spacebar while walking in Firestorm). Default: normal walking.

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed
resulttextstring"Moving to <x>, <y>, <z>"
Commands › Movement

Bot.flyTo(x, y, z, options)

Flies to a position in the current region, including climbing and descending, with continuous steering (same behaviour as moveTo). Switches flying on, brakes smoothly into the target instead of overshooting, and keeps hovering on arrival. walkTo cannot fly: it switches flying off, and the autopilot ignores height. Bot.fly(false) lands the bot and ends the flight. Flight speed is capped (6 m/s by default) by pulsing the controls around the limit, the same technique the viewer's autopilot uses; pass options.speed to change it.

Usage

Bot.flyTo(128, 128, 60, { speed: 4 }).then(function (res) {
  console.log("flyTo response:", res);
});

Or using async/await:

let res = await Bot.flyTo(128, 128, 60, { speed: 4 });
console.log("flyTo response:", res);

Input

VariableRequiredDescription
xyesTarget X in region
yyesTarget Y in region
zyesTarget Z (height)
optionsnoOptional speed cap in m/s (horizontal and vertical), as a number or { speed }. Default 6; 0 = no limit (the sim top speed). Values are clamped to 0.2-50. Very low values (under 1.5) use the slow nudge controls.

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed
resulttextstring"Flying to <x>, <y>, <z>"
Commands › Movement

Bot.moveAlong(points, options)

Walks through a list of waypoints with continuous steering (same engine as moveTo), ending at the last one — e.g. to follow the exact path another avatar walked around corners and obstacles. Each point is passed once reached (or once the bot has clearly gone past it). A new call replaces the waypoints without stopping the bot. Up to 128 points; invalid points are skipped.

Usage

Bot.moveAlong([{ x: 120, y: 64, z: 25 }, { x: 124, y: 70, z: 25 }, { x: 130, y: 71, z: 25 }]).then(function (res) {
  console.log("moveAlong response:", res);
});

Or using async/await:

let res = await Bot.moveAlong([{ x: 120, y: 64, z: 25 }, { x: 124, y: 70, z: 25 }, { x: 130, y: 71, z: 25 }]);
console.log("moveAlong response:", res);

Input

VariableRequiredDescription
pointsyesArray of region positions: { x, y, z } objects or [x, y, z] arrays
optionsnoOptional { slow: true }: the bot walks very slowly and stops dead at the last point instead of coasting past it (holds the server STOP control, like holding the spacebar while walking in Firestorm). Default: normal walking.

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed
resulttextstring"Moving along <n> point(s) to <x>, <y>, <z>"
Commands › Movement

Bot.flyAlong(points, options)

Like moveAlong, but flying (including climbing and descending, same engine as flyTo). Brakes smoothly into the last point instead of overshooting it. Speed is capped like flyTo (6 m/s by default).

Usage

Bot.flyAlong([{ x: 120, y: 64, z: 40 }, { x: 140, y: 80, z: 55 }], { speed: 4 }).then(function (res) {
  console.log("flyAlong response:", res);
});

Or using async/await:

let res = await Bot.flyAlong([{ x: 120, y: 64, z: 40 }, { x: 140, y: 80, z: 55 }], { speed: 4 });
console.log("flyAlong response:", res);

Input

VariableRequiredDescription
pointsyesArray of region positions: { x, y, z } objects or [x, y, z] arrays
optionsnoOptional speed cap in m/s (horizontal and vertical), as a number or { speed }. Default 6; 0 = no limit (the sim top speed). Values are clamped to 0.2-50. Very low values (under 1.5) use the slow nudge controls.

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed
resulttextstring"Flying along <n> point(s) to <x>, <y>, <z>"
Commands › Movement

Bot.alwaysRun(enable)

Turns always-run on or off. While on, walkTo and moveTo run instead of walk. Switches flying off.

Usage

Bot.alwaysRun(true).then(function (res) {
  console.log("alwaysRun response:", res);
});

Or using async/await:

let res = await Bot.alwaysRun(true);
console.log("alwaysRun response:", res);

Input

VariableRequiredDescription
enablenotrue to run, false to walk again (default true)

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed
Commands › Movement

Bot.autoMove(x, y, z)

Obstacle-aware navigation to a position in the current region: plans a route around walls and furniture from the objects the bot can see, and climbs stairs and ramps. Runs in the background; a new autoMove, autoMoveStop or any other movement command cancels it. Falls back to a straight walk if no route is found.

Usage

Bot.autoMove(140, 90, 25).then(function (res) {
  console.log("autoMove response:", res);
});

Or using async/await:

let res = await Bot.autoMove(140, 90, 25);
console.log("autoMove response:", res);

Input

VariableRequiredDescription
xyesTarget X in region
yyesTarget Y in region
zyesTarget Z (height)

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed
messagestring"automove started to (x,y,z)"
Commands › Movement

Bot.autoRun(x, y, z)

Same as autoMove, but runs along the route.

Usage

Bot.autoRun(140, 90, 25).then(function (res) {
  console.log("autoRun response:", res);
});

Or using async/await:

let res = await Bot.autoRun(140, 90, 25);
console.log("autoRun response:", res);

Input

VariableRequiredDescription
xyesTarget X in region
yyesTarget Y in region
zyesTarget Z (height)

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed
messagestring"automove started to (x,y,z)"
Commands › Movement

Bot.autoMoveStop()

Cancels a running autoMove / autoRun.

Usage

Bot.autoMoveStop().then(function (res) {
  console.log("autoMoveStop response:", res);
});

Or using async/await:

let res = await Bot.autoMoveStop();
console.log("autoMoveStop response:", res);

Input

None.

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed
Commands › Movement

Bot.turnTo(deg)

Turns the bot to face a heading (0-360 degrees). Resolved client-side by projecting a look-at point ahead of the bot (two RPCs: bot_location then lookat).

Usage

Bot.turnTo(90).then(function (res) {
  console.log("turnTo response:", res);
});

Or using async/await:

let res = await Bot.turnTo(90);
console.log("turnTo response:", res);

Input

VariableRequiredDescription
degyesHeading in degrees, 0-360

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed
headingnumberThe heading the bot turned to (on success)
Commands › Other Avatars

Bot.avatarInfo(uuid)

Returns the Second Life avatar profile details.

Usage

Bot.avatarInfo('0b65a122-8f77-64fe-5b2a-225d4c490d9c').then(function (res) {
  console.log("avatarInfo response:", res);
});

Or using async/await:

let res = await Bot.avatarInfo('0b65a122-8f77-64fe-5b2a-225d4c490d9c');
console.log("avatarInfo response:", res);

Input

VariableRequiredDescription
uuidyesUUID of the avatar to query

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed
aboutstringProfile (About) text
bornstringSL birth date, MM/DD/YYYY
identifiednumber1 if the avatar has payment info on file
imagestringProfile image texture UUID
first_life_imagestringFirst-life image texture UUID
first_life_textstringFirst-life profile text
maturenumber1 if the profile is mature
onlinenumber1 if the avatar is online
partnerstringPartner avatar UUID (zero UUID if none)
publish_webnumber1 if the profile may be published on the web
transactednumber1 if payment info has been used
urlstringProfile URL

Example response

{
  "success": true,
  "about": "Builder, scripter, explorer.",
  "born": "03/14/2009",
  "identified": 1,
  "image": "aaaaaaaa-...",
  "first_life_image": "00000000-0000-0000-0000-000000000000",
  "first_life_text": "",
  "mature": 0,
  "online": 1,
  "partner": "00000000-0000-0000-0000-000000000000",
  "publish_web": 1,
  "transacted": 1,
  "url": ""
}

Limitations

Not intended for mass parsing — takes ~2-3 seconds per call and repeated requests (more than ~1 per 3 seconds) may be throttled. Excessive non-stop requests can cause the bot to relog.

Commands › Other Avatars

Bot.key2name(key)

Resolves a UUID to an SL name.

Usage

Bot.key2name('0b65a122-8f77-64fe-5b2a-225d4c490d9c').then(function (res) {
  console.log("key2name response:", res);
});

Or using async/await:

let res = await Bot.key2name('0b65a122-8f77-64fe-5b2a-225d4c490d9c');
console.log("key2name response:", res);

Input

VariableRequiredDescription
keyyesAvatar UUID

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed
keystringThe UUID that was queried
namestringResolved SL name

Example response

{
  "success": true,
  "key": "0b65a122-8f77-64fe-5b2a-225d4c490d9c",
  "name": "Resident Name"
}
Commands › Other Avatars

Bot.name2key(slname)

Resolves an SL name to a UUID.

Usage

Bot.name2key('First Last').then(function (res) {
  console.log("name2key response:", res);
});

Or using async/await:

let res = await Bot.name2key('First Last');
console.log("name2key response:", res);

Input

VariableRequiredDescription
slnameyesAvatar name ("First Last")

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed
namestringThe name that was queried
keystringResolved avatar UUID
normalnamestringNormalized name

Example response

{
  "success": true,
  "name": "First Last",
  "key": "0b65a122-8f77-64fe-5b2a-225d4c490d9c",
  "normalname": "first.last"
}
Commands › Other Avatars

Bot.offerTeleport(avatar, message)

Sends a teleport offer to an avatar.

Usage

Bot.offerTeleport('avatar-uuid', 'Join me').then(function (res) {
  console.log("offerTeleport response:", res);
});

Or using async/await:

let res = await Bot.offerTeleport('avatar-uuid', 'Join me');
console.log("offerTeleport response:", res);

Input

VariableRequiredDescription
avataryesAvatar UUID or name
messagenoOffer message (default "Join me")

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed
Commands › Other Avatars

Bot.acceptTeleportOffer(avatar_uuid, session_id, accept)

Accepts or rejects a teleport offer (see the teleport_offer event).

Usage

Bot.acceptTeleportOffer('avatar-uuid', 'session-uuid', true).then(function (res) {
  console.log("acceptTeleportOffer response:", res);
});

Or using async/await:

let res = await Bot.acceptTeleportOffer('avatar-uuid', 'session-uuid', true);
console.log("acceptTeleportOffer response:", res);

Input

VariableRequiredDescription
avatar_uuidyesOffering avatar UUID
session_idyesSession id from the teleport_offer event
acceptnotrue to accept, false to reject (default true)

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed
resulttextstring"Teleport offer accepted" or "Teleport offer declined"
Commands › Access Rights

Bot.isMyOwner(slNameOrUUID)

Returns a bare boolean — true if the avatar is the bot's owner. Resolved client-side (accepts UUID or name).

Usage

Bot.isMyOwner('0b65a122-8f77-64fe-5b2a-225d4c490d9c').then(function (res) {
  console.log("isMyOwner response:", res);
});

Or using async/await:

let res = await Bot.isMyOwner('0b65a122-8f77-64fe-5b2a-225d4c490d9c');
console.log("isMyOwner response:", res);

Input

VariableRequiredDescription
slNameOrUUIDyesAvatar UUID or name to test

Output

FieldTypeDescription
(return value)booltrue if the avatar is the bot's owner
Commands › Access Rights

Bot.isMyManager(slNameOrUUID)

Returns a bare boolean — true if the avatar is a trusted manager of the bot. Resolved client-side.

Usage

Bot.isMyManager('0b65a122-8f77-64fe-5b2a-225d4c490d9c').then(function (res) {
  console.log("isMyManager response:", res);
});

Or using async/await:

let res = await Bot.isMyManager('0b65a122-8f77-64fe-5b2a-225d4c490d9c');
console.log("isMyManager response:", res);

Input

VariableRequiredDescription
slNameOrUUIDyesAvatar UUID or name to test

Output

FieldTypeDescription
(return value)booltrue if the avatar is a trusted manager
Commands › Access Rights

Bot.checkScriptedAgent(slNameOrUUID)

Returns a bare boolean — true if the avatar is a registered LifeBots bot (exists in the shared bots collection). Use to avoid bot-to-bot loops. Resolved client-side via a Mongo lookup.

Usage

Bot.checkScriptedAgent('0b65a122-8f77-64fe-5b2a-225d4c490d9c').then(function (res) {
  console.log("checkScriptedAgent response:", res);
});

Or using async/await:

let res = await Bot.checkScriptedAgent('0b65a122-8f77-64fe-5b2a-225d4c490d9c');
console.log("checkScriptedAgent response:", res);

Input

VariableRequiredDescription
slNameOrUUIDyesAvatar UUID or name to test

Output

FieldTypeDescription
(return value)booltrue if the avatar is a registered LifeBots bot
Commands › World

Bot.scanNearbyAvatars()

Scans avatars in the bot's current region.

Usage

Bot.scanNearbyAvatars().then(function (res) {
  console.log("scanNearbyAvatars response:", res);
});

Or using async/await:

let res = await Bot.scanNearbyAvatars();
console.log("scanNearbyAvatars response:", res);

Input

None.

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed
avatarsarrayArray of avatar objects (see below)
avatars[].namestringAvatar name
avatars[].uUIDstringAvatar UUID. NOTE the casing quirk: the key is uUID (camelKeys lowercases only the first char)
avatars[].positionobjectPosition in the region { x, y, z } — correct also while the avatar sits (use this one)
avatars[].localPositionobjectRaw position { x, y, z } — relative to the seat while the avatar sits
avatars[].headingnumberFacing direction in degrees, counter-clockwise from east (0 = east, 90 = north)
avatars[].localHeadingnumberSame as heading
avatars[].distancenumberDistance from the bot (metres)
avatars[].parcelIDnumberParcel local id
avatars[].sittingbooltrue if the avatar is sitting
avatars[].seenSincestringISO timestamp first seen
avatars[].seenSecondsnumberSeconds since first seen

Example response

{
  "success": true,
  "avatars": [
    {
      "name": "Resident One",
      "uUID": "11111111-2222-3333-4444-555555555555",
      "position": {
        "x": 130,
        "y": 64,
        "z": 25
      },
      "localPosition": {
        "x": 130,
        "y": 64,
        "z": 25
      },
      "heading": 45,
      "localHeading": 45,
      "distance": 3.2,
      "parcelID": 12,
      "sitting": false,
      "seenSince": "2026-06-16T12:00:00.000Z",
      "seenSeconds": 42
    }
  ]
}
Commands › World

Bot.trackAvatars(avatars)

Tracks one or more avatars; position updates fire as avatar_tracker_update events. Pass "" (or no args) to stop tracking.

Usage

Bot.trackAvatars(['11111111-2222-3333-4444-555555555555']).then(function (res) {
  console.log("trackAvatars response:", res);
});

Or using async/await:

let res = await Bot.trackAvatars(['11111111-2222-3333-4444-555555555555']);
console.log("trackAvatars response:", res);

Input

VariableRequiredDescription
avatarsyesSpace-separated UUID string or array of UUIDs. Empty string stops tracking

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed
trackingnumberNumber of avatars now being tracked
Commands › World

Bot.touchPrim(uuid)

Touches an in-world prim.

Usage

Bot.touchPrim('prim-uuid').then(function (res) {
  console.log("touchPrim response:", res);
});

Or using async/await:

let res = await Bot.touchPrim('prim-uuid');
console.log("touchPrim response:", res);

Input

VariableRequiredDescription
uuidyesPrim UUID to touch

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed
resulttextstring"Touched"
Commands › World

Bot.touchAttachment(objectName, linkNumber)

Touches one of the bot's own attachments by name + link number.

Usage

Bot.touchAttachment('My HUD', 2).then(function (res) {
  console.log("touchAttachment response:", res);
});

Or using async/await:

let res = await Bot.touchAttachment('My HUD', 2);
console.log("touchAttachment response:", res);

Input

VariableRequiredDescription
objectNameyesAttachment object name
linkNumbernoLink number within the attachment

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed
namestringName of the touched attachment
uuidstringUUID of the touched attachment
Commands › World

Bot.takeInworldPrim(operation, objectUUID, folderUUID)

Takes or copies an in-world prim into inventory.

Usage

Bot.takeInworldPrim('take', 'prim-uuid').then(function (res) {
  console.log("takeInworldPrim response:", res);
});

Or using async/await:

let res = await Bot.takeInworldPrim('take', 'prim-uuid');
console.log("takeInworldPrim response:", res);

Input

VariableRequiredDescription
operationno"take" or "copy" (default "take")
objectUUIDyesPrim UUID
folderUUIDnoDestination folder UUID

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed
resulttextstring"Prim <operation> requested"
Commands › Region

Bot.regionRestart(delay)

Restarts the current region (requires estate-manager privileges).

Usage

Bot.regionRestart(120).then(function (res) {
  console.log("regionRestart response:", res);
});

Or using async/await:

let res = await Bot.regionRestart(120);
console.log("regionRestart response:", res);

Input

VariableRequiredDescription
delaynoSeconds before restart, typically 30-240 (default 120)

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed
resulttextstring"Region restart initiated (<delay>s delay)"
Commands › Region

Bot.regionRestartCancel()

Cancels a pending region restart.

Usage

Bot.regionRestartCancel().then(function (res) {
  console.log("regionRestartCancel response:", res);
});

Or using async/await:

let res = await Bot.regionRestartCancel();
console.log("regionRestartCancel response:", res);

Input

None.

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed
resulttextstring"Region restart cancelled"
Commands › Sim / Estate moderation

Bot.estateKick(avatar)

Kicks an avatar out of the current region. Use for offenders who are not group members (e.g. spam in local chat).

Usage

Bot.estateKick('avatar-uuid').then(function (res) {
  console.log("estateKick response:", res);
});

Or using async/await:

let res = await Bot.estateKick('avatar-uuid');
console.log("estateKick response:", res);

Input

VariableRequiredDescription
avataryesAvatar UUID to kick from the region

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed

Limitations

The bot must hold estate-manager rights in-world; the simulator enforces this. No addon required.

Commands › Sim / Estate moderation

Bot.estateBan(avatar, allEstates)

Adds an avatar to the estate ban list (kicks them if present).

Usage

Bot.estateBan('avatar-uuid').then(function (res) {
  console.log("estateBan response:", res);
});

Or using async/await:

let res = await Bot.estateBan('avatar-uuid');
console.log("estateBan response:", res);

Input

VariableRequiredDescription
avataryesAvatar UUID to ban
allEstatesnotrue = apply to every estate the bot manages (default false = this estate only)

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed

Limitations

The bot must hold estate-manager rights in-world.

Commands › Sim / Estate moderation

Bot.estateUnban(avatar, allEstates)

Removes an avatar from the estate ban list.

Usage

Bot.estateUnban('avatar-uuid').then(function (res) {
  console.log("estateUnban response:", res);
});

Or using async/await:

let res = await Bot.estateUnban('avatar-uuid');
console.log("estateUnban response:", res);

Input

VariableRequiredDescription
avataryesAvatar UUID to unban
allEstatesnotrue = apply to every estate the bot manages (default false = this estate only)

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed

Limitations

The bot must hold estate-manager rights in-world.

Commands › Sim / Estate moderation

Bot.teleportHomeUser(avatar)

Sends an avatar back to their home location. Gentler than a kick — they stay in-world.

Usage

Bot.teleportHomeUser('avatar-uuid').then(function (res) {
  console.log("teleportHomeUser response:", res);
});

Or using async/await:

let res = await Bot.teleportHomeUser('avatar-uuid');
console.log("teleportHomeUser response:", res);

Input

VariableRequiredDescription
avataryesAvatar UUID to send home

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed

Limitations

The bot must hold estate-manager rights in-world.

Commands › Sim / Estate moderation

Bot.teleportHomeAll()

Sends every non-estate-manager avatar in the region back to their home location.

Usage

Bot.teleportHomeAll().then(function (res) {
  console.log("teleportHomeAll response:", res);
});

Or using async/await:

let res = await Bot.teleportHomeAll();
console.log("teleportHomeAll response:", res);

Input

None.

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed

Limitations

The bot must hold estate-manager rights in-world.

Commands › Sim / Estate moderation

Bot.parcelEject(avatar, ban)

Ejects an avatar from the current parcel. Works with parcel (owner/manager) rights rather than estate rights.

Usage

Bot.parcelEject('avatar-uuid').then(function (res) {
  console.log("parcelEject response:", res);
});

Or using async/await:

let res = await Bot.parcelEject('avatar-uuid');
console.log("parcelEject response:", res);

Input

VariableRequiredDescription
avataryesAvatar UUID to eject from the parcel
bannotrue = also add them to the parcel ban list (default false = eject only)

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed

Limitations

The bot must hold parcel owner/manager rights in-world.

Commands › Sim / Estate moderation

Bot.regionMessage(message, allEstates)

Sends a blue-box message to everyone in the region (or across the estate).

Usage

Bot.regionMessage('Please keep the region friendly.').then(function (res) {
  console.log("regionMessage response:", res);
});

Or using async/await:

let res = await Bot.regionMessage('Please keep the region friendly.');
console.log("regionMessage response:", res);

Input

VariableRequiredDescription
messageyesThe message text
allEstatesnotrue = broadcast to the whole estate (default false = current region only)

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed

Limitations

The bot must hold estate-manager rights in-world.

Commands › Sim / Estate moderation

Bot.returnObjects(avatar, includeOthersLand)

Sim-wide return of an avatar's scripted objects to their owner.

Usage

Bot.returnObjects('avatar-uuid').then(function (res) {
  console.log("returnObjects response:", res);
});

Or using async/await:

let res = await Bot.returnObjects('avatar-uuid');
console.log("returnObjects response:", res);

Input

VariableRequiredDescription
avataryesOwner UUID whose objects to return
includeOthersLandnotrue = also return objects sitting on other people's land (default false)

Output

FieldTypeDescription
successbooltrue if the command completed successfully
errorstringerror string if the command has failed

Limitations

The bot must hold estate-manager rights in-world.

Events

chat_message

Local chat message received.

Usage

Bot.on('chat_message', m => console.log(m.speakerName, m.message));

Payload fields

FieldTypeDescription
speakerNamestringSpeaker's name
speakerUuidstringSpeaker's UUID
speakerTypestringSpeaker type
ownerUuidstringOwner UUID if speaker is an object
messagestringChat text
timestampDateWhen received
Events

instant_message

IM received.

Usage

Bot.on('instant_message', async im => { await Bot.im(im.senderUuid, 'hi'); });

Payload fields

FieldTypeDescription
senderNamestringSender's name
senderUuidstringSender's UUID
senderTypestring'AGENT' or 'OBJECT'
ownerUuidstringOwner UUID if sender is an object
messagestringIM text
timestampDateWhen received
Events

group_im

Group chat message.

Usage

Bot.on('group_im', (e) => {
  console.log(e);
});

Payload fields

FieldTypeDescription
groupUuidstringGroup UUID
groupNamestringGroup name
senderNamestringSender name
senderUuidstringSender UUID
isModeratorbooltrue if sender is a moderator
messagestringMessage text
timestampDateWhen received
Events

group_notice

Group notice received.

Usage

Bot.on('group_notice', (e) => {
  console.log(e);
});

Payload fields

FieldTypeDescription
groupUuidstringGroup UUID
groupNamestringGroup name
subjectstringNotice subject
messagestringNotice body
senderNamestringSender name
senderUuidstringSender UUID
Events

group_offer

Group invite received.

Usage

Bot.on('group_offer', (e) => {
  console.log(e);
});

Payload fields

FieldTypeDescription
sessionIdstringUse with acceptGroupOffer
groupUuidstringGroup UUID
groupNamestringGroup name
avatarNamestringInviting avatar name
avatarUuidstringInviting avatar UUID
messagestringSystem message
Events

friendship_offer

Friendship request received.

Usage

Bot.on('friendship_offer', (e) => {
  console.log(e);
});

Payload fields

FieldTypeDescription
sessionIdstringUse with acceptFriendshipOffer
avatarNamestringOffering avatar name
avatarUuidstringOffering avatar UUID
messagestringOffer message
Events

inventory_offer

Inventory offer received.

Usage

Bot.on('inventory_offer', (e) => {
  console.log(e);
});

Payload fields

FieldTypeDescription
sessionIdstringUse with acceptInventoryOffer
avatarNamestringSender name
avatarUuidstringSender UUID
itemNamestringOffered item name
itemTypestringOffered item type
Events

teleport_offer

Teleport offer received.

Usage

Bot.on('teleport_offer', (e) => {
  console.log(e);
});

Payload fields

FieldTypeDescription
sessionIdstringUse with acceptTeleportOffer
avatarNamestringOffering avatar name
avatarUuidstringOffering avatar UUID
messagestringOffer message
Events

teleport_status

Teleport progress.

Usage

Bot.on('teleport_status', (e) => {
  console.log(e);
});

Payload fields

FieldTypeDescription
statusstringTeleport stage
messagestringStatus message
flagsanyTeleport flags
locationanyDestination info
Events

script_dialog

Script dialog with menu received.

Usage

Bot.on('script_dialog', async d => { await Bot.replyDialog(d.channel, d.objectUuid, d.buttons[0]); });

Payload fields

FieldTypeDescription
channelstring|numberReply channel (pass to replyDialog)
objectNamestringObject name
objectUuidstringObject UUID (pass to replyDialog)
ownerUuidstringObject owner UUID
messagestringDialog text
buttonsstring[]Button labels
Events

balance_changed

L$ balance changed.

Usage

Bot.on('balance_changed', (e) => {
  console.log(e);
});

Payload fields

FieldTypeDescription
amountnumberTransaction amount
directionstringin / out
sourcestringSource UUID/name
destinationstringDestination UUID/name
balancenumberNew balance
transactionTypestringTransaction type
descriptionstringDescription
transactionIdstringTransaction id
timestampanyWhen it occurred
Events

start_typing

Avatar started typing.

Usage

Bot.on('start_typing', (e) => {
  console.log(e);
});

Payload fields

FieldTypeDescription
avatarNamestringAvatar name
avatarUuidstringAvatar UUID
Events

stop_typing

Avatar stopped typing.

Usage

Bot.on('stop_typing', (e) => {
  console.log(e);
});

Payload fields

FieldTypeDescription
avatarNamestringAvatar name
avatarUuidstringAvatar UUID
Events

region_restart

Region restart announced.

Usage

Bot.on('region_restart', (e) => {
  console.log(e);
});

Payload fields

FieldTypeDescription
regionstringRegion name
secondsRemainingnumberSeconds until restart
Events

region_restart_cancelled

Region restart cancelled.

Usage

Bot.on('region_restart_cancelled', (e) => {
  console.log(e);
});

Payload fields

FieldTypeDescription
regionstringRegion name
Events

sit

Bot sat on or stood from an object.

Usage

Bot.on('sit', (e) => {
  console.log(e);
});

Payload fields

FieldTypeDescription
sittingbooltrue if now sitting
objectUuidstringObject UUID (empty when standing)
Events

self_position

Bot moved or turned (>1m or >5deg).

Usage

Bot.on('self_position', (e) => {
  console.log(e);
});

Payload fields

FieldTypeDescription
regionstringRegion name
xnumberX position
ynumberY position
znumberZ position
headingnumberFacing direction in degrees, counter-clockwise from east (0 = east, 90 = north)
Events

autopilot_started

WalkTo/MoveTo began.

Usage

Bot.on('autopilot_started', (e) => {
  console.log(e);
});

Payload fields

FieldTypeDescription
xnumberTarget X
ynumberTarget Y
znumberTarget Z
Events

autopilot_completed

Bot reached its destination.

Usage

Bot.on('autopilot_completed', (e) => {
  console.log(e);
});

Payload fields

FieldTypeDescription
xnumberFinal X
ynumberFinal Y
znumberFinal Z
Events

autopilot_stuck

Bot stopped making progress (>10s).

Usage

Bot.on('autopilot_stuck', (e) => {
  console.log(e);
});

Payload fields

FieldTypeDescription
xnumberCurrent X
ynumberCurrent Y
znumberCurrent Z
remainingDistancenumberDistance left to target
Events

avatar_tracker_update

Update for a tracked avatar (after Bot.trackAvatars). Checked every 0.5 s; fires only when something changed: moved more than 0.1 m, turned more than 5°, sat or stood, changed region, or appeared/disappeared. A standing, unmoving avatar sends nothing, so keep using the last update.

Usage

Bot.on('avatar_tracker_update', (e) => {
  console.log(e);
});

Payload fields

FieldTypeDescription
namestring'avatar_tracker_update'
bot_slnamestringTracking bot's name
bot_uuidstringTracking bot's UUID
avatar_namestring|nullTracked avatar name
avatar_uuidstringTracked avatar UUID
regionstring|nullRegion name
regionHandleany|nullRegion handle
positionobject|null{X,Y,Z} in the region (also while sitting); null when not visible
velocityobject|null{X,Y,Z}; null when not visible
headingnumber|nullFacing direction in RADIANS, counter-clockwise from east (0 = east, π/2 = north); null when not visible
sittingbooltrue if sitting
timestampnumber|nullUpdate time (Unix milliseconds)
event_versionnumberEvent schema version
versionstringVersion string
Events

workshop_webhook

External HTTP request hit the script's allocated webhook URL (from http.requestWebhookUrl()).

Usage

const hook = await http.requestWebhookUrl(); Bot.on('workshop_webhook', e => console.log(e.payload));

Payload fields

FieldTypeDescription
namestring'workshop_webhook'
bot_slnamestringBot name
hookIdstringWebhook id from the URL
correlationIdstringEchoed in the HTTP response too
payloadobject|stringParsed JSON body, or raw string for text/plain; {} for invalid/empty JSON
Events

before_login

Bot is logging in (CONNECTING).

Usage

Bot.on('before_login', (e) => {
  console.log(e);
});

Payload fields

FieldTypeDescription
statusstringStatus code
regionstring|nullRegion
positionany|nullPosition
errorstring|nullError (login_error only)
timestampDateWhen
Events

after_login

Bot logged in (ONLINE).

Usage

Bot.on('after_login', (e) => {
  console.log(e);
});

Payload fields

FieldTypeDescription
statusstringStatus code
regionstring|nullRegion
positionany|nullPosition
errorstring|nullError (login_error only)
timestampDateWhen
Events

before_logout

Bot is logging out (LOGGING_OUT).

Usage

Bot.on('before_logout', (e) => {
  console.log(e);
});

Payload fields

FieldTypeDescription
statusstringStatus code
regionstring|nullRegion
positionany|nullPosition
errorstring|nullError (login_error only)
timestampDateWhen
Events

after_logout

Bot logged out (LOGGED_OUT).

Usage

Bot.on('after_logout', (e) => {
  console.log(e);
});

Payload fields

FieldTypeDescription
statusstringStatus code
regionstring|nullRegion
positionany|nullPosition
errorstring|nullError (login_error only)
timestampDateWhen
Events

login_error

Login failed (LOGIN_ERROR); error is populated.

Usage

Bot.on('login_error', (e) => {
  console.log(e);
});

Payload fields

FieldTypeDescription
statusstringStatus code
regionstring|nullRegion
positionany|nullPosition
errorstring|nullFailure reason
timestampDateWhen
Bot.AI

Bot.AI.chat(message, opts)

One-shot AI completion with no memory. The model is chosen in the Bot.AI panel; instructions/temperature/maxTokens come from configure() defaults or this call's opts.

Usage

Bot.AI.chat('Summarize Second Life in one sentence.', { temperature: 0.5, maxTokens: 100 }).then(function (res) {
  console.log("chat response:", res);
});

Or using async/await:

let res = await Bot.AI.chat('Summarize Second Life in one sentence.', { temperature: 0.5, maxTokens: 100 });
console.log("chat response:", res);

Input

VariableRequiredDescription
messageyesThe prompt text
optsno{ model?, instructions?, temperature?, maxTokens? } — overrides run defaults for this call

Returns

Promise<{ text, model, tokens, cost }>

Output fields

FieldTypeDescription
textstringThe model's reply text
modelstringModel that produced the reply
tokensobject{ input, output, total } token counts
costnumberCost deducted from the owner's AI credits
Bot.AI

Bot.AI.configure(opts)

Override the run-level Bot.AI defaults applied to subsequent chat() calls.

Usage

Bot.AI.configure({ instructions: 'You are a friendly SL assistant.', temperature: 0.7, maxTokens: 300 }).then(function (res) {
  console.log("configure response:", res);
});

Or using async/await:

let res = await Bot.AI.configure({ instructions: 'You are a friendly SL assistant.', temperature: 0.7, maxTokens: 300 });
console.log("configure response:", res);

Input

VariableRequiredDescription
optsyes{ model?, instructions?, temperature?, maxTokens? }

Returns

Promise<{ ok, defaults }>

Bot.AI

Bot.AI.getConversationByName(residentName)

Returns a Conversation object (synchronously) with per-resident memory that persists for the run only. The Conversation exposes chat(message, opts?) (same return shape as Bot.AI.chat, with memory), configure(opts), and forget().

Usage

const conv = Bot.AI.getConversationByName(im.senderName);
const r = await conv.chat(im.message);
await Bot.im(im.senderUuid, r.text);

Input

VariableRequiredDescription
residentNameyesA name/key to scope the conversation memory

Returns

Conversation { chat(message, opts?), configure(opts), forget() }

Bot.AI

Bot.AI.forgetConversation(residentName)

Clears an in-memory conversation.

Usage

Bot.AI.forgetConversation('First Last').then(function (res) {
  console.log("forgetConversation response:", res);
});

Or using async/await:

let res = await Bot.AI.forgetConversation('First Last');
console.log("forgetConversation response:", res);

Input

VariableRequiredDescription
residentNameyesConversation name to clear

Returns

Promise<{ ok, removed }>

Bot.AI

Bot.AI.listConversations()

Lists active conversations and their message counts.

Usage

Bot.AI.listConversations().then(function (res) {
  console.log("listConversations response:", res);
});

Or using async/await:

let res = await Bot.AI.listConversations();
console.log("listConversations response:", res);

Input

None.

Returns

Promise<[{ name, messages }]>

Templates

Hello, world

Send a chat message and exit.

Script

console.log(`${process.name} started`);
await Bot.say(0, 'Hello from the workshop');
process.exit();
Templates

Echo IMs

Reply to every IM the bot receives.

Script

console.log('Listening for IMs…');

Bot.on('instant_message', async (im) => {
  console.log(`IM from ${im.senderName}: ${im.message}`);
  await Bot.im(im.senderUuid, `You said: ${im.message}`);
});
Templates

Greet on local chat

Wave hello when someone speaks in nearby chat.

Script

const greeted = new Set();

Bot.on('chat_message', async (msg) => {
  if (greeted.has(msg.speakerUuid)) return;
  greeted.add(msg.speakerUuid);
  console.log(`First message from ${msg.speakerName}`);
  await Bot.say(0, `Hi ${msg.speakerName}!`);
});
Templates

Scan nearby avatars

List avatars in the bot’s current region.

Script

console.log(`${process.name} started`);

const result = await Bot.scanNearbyAvatars();
console.log(`Avatars arrived: (${JSON.stringify(result).length} bytes)`);

if (!result.success) {
  console.log('Error scanning avatars: ' + result.error);
} else if (!result.avatars || result.avatars.length === 0) {
  console.log('No avatars found.');
} else {
  for (const avatar of result.avatars) {
    console.log(`${avatar.name}: seen for ${avatar.seenSeconds} seconds`);
  }
}

process.exit();
Templates

Login lifecycle

Watch the bot’s login/logout events.

Script

Bot
  .on('before_logout', () => console.log('Bot is logging out'))
  .on('before_login',  () => console.log('Bot is logging in'))
  .on('after_login',   () => console.log('Bot has logged in'))
  .on('login_error',   (e) => console.log('Login error: ' + e.error));

console.log('Watching login lifecycle. Trigger from the LifeBots dashboard.');
Templates

localStorage usage

Persist counters across script restarts.

Script

const prevRaw = await localStorage.get('runs');
const prev = prevRaw ? parseInt(prevRaw, 10) : 0;
const next = prev + 1;
await localStorage.set('runs', String(next));
console.log(`This script has been run ${next} time(s).`);

const keys = await localStorage.keys();
console.log('Stored keys:', keys);

process.exit();
Templates

Walk to a position

Move the bot to a specific spot in the current region.

Script

const x = 128, y = 128, z = 25;
console.log(`Walking to (${x}, ${y}, ${z})…`);
const r = await Bot.walkTo(x, y, z);
console.log('walkTo response:', r);
Templates

HTTP GET

Fetch a URL and log the response.

Script

const r = await http.get('https://httpbin.org/get');
console.log('status:', r.status);
console.log('body sample:', r.body.slice(0, 200));
process.exit();
Templates

AI chat bot

Reply to IMs with OpenRouter-backed AI. Remembers per-resident context.

Script

// Bot.AI uses your OpenRouter key from node-web AI settings.
// The model is picked in the Bot.AI panel above (per-script / per-buyer).
// Everything else — instructions, temperature, max tokens — is controlled
// here in code. If you want the buyer to tune those, expose them via
// userSettings (the userSettings ▾ button next to Bot.AI) and read them
// below; otherwise just hardcode whatever suits the bot.

Bot.AI.configure({
  instructions: userSettings.systemPrompt ||
    'You are a friendly Second Life assistant. Keep replies under 200 characters.',
  temperature: parseFloat(userSettings.temperature) || 0.7,
  maxTokens:   parseInt(userSettings.maxTokens, 10) || 300,
});

console.log('AI chat ready. Send the bot an IM.');

Bot.on('instant_message', async (im) => {
  // checkScriptedAgent avoids replying to other bots and getting into a loop.
  if (await Bot.checkScriptedAgent(im.senderUuid)) return;

  // One conversation per resident — memory persists for this run only.
  const conv = Bot.AI.getConversationByName(im.senderName);

  try {
    await Bot.startTyping(im.senderUuid);
    const r = await conv.chat(im.message);
    await Bot.im(im.senderUuid, r.text);
    console.log(`[${r.model}] ${im.senderName}: ${r.text}  (${r.tokens.total} tok, $${r.cost.toFixed(5)})`);
  } catch (e) {
    console.error('AI failed:', e.message);
    await Bot.im(im.senderUuid, 'Sorry, I had trouble responding.');
  } finally {
    await Bot.stopTyping(im.senderUuid);
  }
});
Reference

Limits

Runtime caps. Defaults shown; overridable via settings.workshop.limits.

LimitDefault
maxOldGenerationMb256
maxConcurrentRunsPerUser10
scriptStartTimeoutMs30000
eventHandlerTimeoutMs5000
cpuBudgetMs5000
cpuMonitorIntervalMs10000
consoleLinesPerSecond100
consoleMaxRetainedLines500
botCommandsPerSecond30
botCommandBurst60
localStorageMaxBytes1048576
localStorageMaxKeys500
httpTimeoutMs15000
httpCallsPerMinute60
httpMaxResponseBytes5242880
webhookHitsPerMinute120
aiCallsPerMinute30
aiMaxTokensCap2048
aiRequestTimeoutMs45000
aiMaxConversations20
aiMaxMessagesPerConversation50
Lifebots symbol
Lifebots.cloud

Empowering Second Life experiences with intelligent bot automation and seamless group management solutions.

Product
Support
Company
Visit Us

© 2026 LifeBots. Made with ❤️. All rights reserved.

LifeBots is not affiliated with Linden Research, Inc., or any of its affiliated entities or products, including, without limitation, Second Life (collectively, “Linden Lab”).

Initializing A New World of Second Life Bots...