HELP
Scripting Advanced Published: 2026-03-15  |  ← Back to School

Alife Virtual School - Class 12: HTTP Requests in LSL

HTTP Requests in LSL — Alife Virtual School

HTTP Requests in LSL — Free class in Alife Virtual School

Connecting Your In-World Creations to the World Wide Web

Welcome, future master scripter, to Class 12 at the Alife Virtual School! You’ve learned how to build, texture, and write basic scripts. You’ve made objects that move, talk, and react to avatars. But what if you could make your creations truly live? What if an object in Alife Virtual could know the real-world weather, display live stock prices, or even talk to an advanced AI on the internet?

This is where the magic happens. By learning to use HTTP requests in LSL (Linden Scripting Language), you will unlock the ability to connect your in-world objects to the vast expanse of the World Wide Web. This skill is the gateway to creating some of the most dynamic and impressive content you'll see across the grid, from live scoreboards for sports events to AI-powered chatbots and self-updating vendor systems. You're not just scripting an object anymore; you're building a bridge between the virtual world and the real world.

In Alife Virtual, where you have a free private island with 10,000 prims to build on, this skill is especially powerful. You have the space and the resources to build large-scale, data-driven projects without the crippling land fees you'd find elsewhere. Imagine a whole sim that changes its environment based on the real-world time of day and weather, all powered by the techniques you'll learn today. Let's get started!

What You Will Learn

By the end of this advanced tutorial, you will be able to:

Prerequisites

This is an advanced class. Before you begin, you should be comfortable with the fundamentals of LSL scripting. We recommend you have a solid grasp of:

If you need a refresher, please feel free to browse our earlier, free classes at the Alife Virtual School. You’ll also need your free full-body mesh avatar and a place to build—which is no problem since every one of our 1,148,000+ members can claim a free 65,536 sqm private island to call their own!

Main Tutorial: Making the Web Work for You

Part 1: The Theory - What is an HTTP Request?

Think of it like ordering food from a restaurant.

  1. You (the script) decide what you want (e.g., the current price of Bitcoin).
  2. You write down your order and give it to the waiter. This is the HTTP Request. Your script uses the llHTTPRequest() function to send this "order" to a specific web address (URL).
  3. The kitchen (the web server/API) prepares your order.
  4. The waiter brings your food back to your table. This is the HTTP Response. Your script receives this "food" (the data) in a special event called http_response.

The key is that this is an asynchronous process. Your script doesn't stop and wait for the answer. It sends the request and continues running. When the response arrives (which could be milliseconds or seconds later), the http_response event is triggered, and your script can then process the data.

Part 2: The Core LSL Functions

Two main components make this all work in LSL:

1. The Function: llHTTPRequest(key url, list parameters, string body)

This is the function you call to send your "order".

Let's correct that. The function signature is `key llHTTPRequest(string url, list parameters, string body)`.

The function returns a key, which is the unique ID for this specific request. You need to save this key to match it with the incoming response.

2. The Event: http_response(key request_id, integer status, list metadata, string body)

This event is automatically triggered in your script when the web server sends back a response.

Part 3: Step-by-Step Example: Building a Live Bitcoin Price Board

Let's build something practical. We'll create a simple prim that shows the current price of Bitcoin in USD and updates when you touch it. We'll do this on your free island, which you can claim right after you register for Alife Virtual. Remember, our platform uses the same Firestorm Viewer as Second Life, so your skills are 100% transferable, but here, your creative freedom isn't limited by upload fees or land costs!

Step 1: Find a Free Public API

An API (Application Programming Interface) is a way for computers to talk to each other. We need an API that provides cryptocurrency prices. A great, simple one is CoinGecko.

The URL we will use is: https://api.coingecko.com/api/v3/simple/price?ids=bitcoin&vs_currencies=usd

If you visit that URL in your web browser, you'll see a simple text response: {"bitcoin":{"usd":68000.50}} (the price will vary, of course). This is the data we want to get into our script.

Step 2: Set Up Your Object in Alife Virtual

  1. Log into Alife Virtual using the Firestorm Viewer.
  2. Teleport to your free private island. (If you haven't claimed it, visit this page after registering).
  3. Right-click the ground and choose Build. A wooden cube will appear. This is your price board.
  4. Right-click the cube and choose Edit.
  5. In the edit window, go to the Content tab.
  6. Click the New Script button. A new script named "New Script" will be created and opened.

[Image: A screenshot showing the in-world editor in Alife Virtual. A prim is selected, and the 'Content' tab is open, highlighting the 'New Script' button.]

Step 3: Write the Script - Making the Request

Delete the default "Hello, Avatar!" code and replace it with the following. We'll start by declaring our variables and setting up the touch event to fire the request.

// --- Global Variables ---
string API_URL = "https://api.coingecko.com/api/v3/simple/price?ids=bitcoin&vs_currencies=usd";
key g_request_id; // To store the ID of our request

default
{
    state_entry()
    {
        llSetObjectDesc("Bitcoin Price Ticker");
        llSetText("Click me to update price...", <1.0, 1.0, 1.0>, 1.0);
    }

    touch_start(integer total_number)
    {
        llSetText("Fetching price...", <1.0, 0.8, 0.0>, 1.0);
        // Send the HTTP request and store the returned key
        g_request_id = llHTTPRequest(API_URL, [], "");
    }
}
Tip: We use a global variable g_request_id to hold the key that llHTTPRequest() gives us. This is crucial for identifying the response when it arrives. Using a prefix like "g_" for global variables is a good coding practice.

Step 4: Handle the Response

Now, let's add the http_response event to our script. This code will "listen" for the reply from the CoinGecko server.

Add this event inside your default state, after the touch_start event.

    http_response(key request_id, integer status, list metadata, string body)
    {
        // First, check if this response is for our request
        if (request_id == g_request_id)
        {
            // Next, check if the request was successful
            if (status == 200)
            {
                // For now, let's just print the body to see what we got
                llOwnerSay("Response received: " + body);
                
                // We will parse this data in the next step!
                // For now, let's just show a success message.
                llSetText("Data received! Processing...", <0.0, 1.0, 0.0>, 1.0);
            }
            else
            {
                // The request failed! Tell the user.
                llSetText("Error: Failed to fetch price. Status: " + (string)status, <1.0, 0.0, 0.0>, 1.0);
                llOwnerSay("HTTP request failed with status code: " + (string)status);
            }
        }
    }

Save your script. Now, touch the object in-world. You should see the text change to "Fetching price..." and then, in your local chat, a message like: Response received: {"bitcoin":{"usd":68000.50}}. This confirms your script is successfully communicating with the web!

Step 5: Parse the Data and Display It

We have the data, but it's trapped in a string: {"bitcoin":{"usd":68000.50}}. This format is called JSON. While LSL doesn't have a built-in JSON parser, we can use simple string functions for this basic structure.

We'll use llParseString2List to break the string apart using the double quote (") as a delimiter.

Replace the `llOwnerSay` and temporary `llSetText` line inside your `if (status == 200)` block with the following parsing logic:

                // --- Start Parsing ---
                // The response looks like: {"bitcoin":{"usd":PRICE}}
                // We will split the string by the " character.
                list parsed_data = llParseString2List(body, ["\""], []);

                // The price will be the 4th element in the list, but it has a colon.
                // e.g., ":68000.50}}"
                string price_part = llList2String(parsed_data, 7); // Index 7 should be the price value
                
                // Let's clean it up by removing the trailing characters '}}' and the colon ':'
                // Find the position of the colon
                integer colon_pos = llSubStringIndex(price_part, ":");
                // Get the substring after the colon
                string price_raw = llGetSubString(price_part, colon_pos + 1, -1);
                // Remove the closing curly braces
                integer brace_pos = llSubStringIndex(price_raw, "}");
                string final_price = llGetSubString(price_raw, 0, brace_pos - 1);

                // Now, display the final price!
                llSetText("Bitcoin: $" + final_price, <1.0, 1.0, 1.0>, 1.0);
                llOwnerSay("Current Bitcoin Price: $" + final_price);

Save the script. Now when you touch the cube, it will fetch the live price, parse it, and display it as floating text on the object! Congratulations, you've just built your first web-connected LSL object!

A Note on Parsing: This string parsing method is fragile. If the API changes its JSON structure even slightly, it will break. For more complex data, scripters often write their own robust JSON parsing functions, a topic for a future, even more advanced class!

Part 4: Sending Data with a `POST` Request

What if you want to send data, not just get it? For example, submitting a high score to a web leaderboard. This is done with a POST request. The process is very similar, but you need to configure the `parameters` and `body` in your `llHTTPRequest` call.

Here’s a quick example snippet. Imagine you have a web service (a "webhook") that accepts a player's name and score.

string webhookURL = "https://your-api.com/submit_score";
string playerName = "Explorer_123";
integer playerScore = 9500;

// Create the JSON data to send
string jsonBody = "{ \"name\": \"" + playerName + "\", \"score\": " + (string)playerScore + " }";

// Define the parameters for a POST request
list postParams = [
    HTTP_METHOD, "POST",
    HTTP_MIMETYPE, "application/json"
];

// Send the request!
llHTTPRequest(webhookURL, postParams, jsonBody);

The server at `webhookURL` would receive the JSON data, and you would still get a confirmation back in your `http_response` event, which you should handle just like you did for the `GET` request.

Common Mistakes and How to Avoid Them

Advanced Tips and Tricks

Practice Exercise: Enhance Your Ticker!

Now it's your turn to apply what you've learned. Modify the Bitcoin price ticker script to do the following. This is a perfect project to try on your free island, where you have plenty of room and prims to experiment.

  1. Add Ethereum: Modify the `API_URL` to also fetch the price of Ethereum. (Hint: The URL should look like `...&ids=bitcoin,ethereum&...`).
  2. Update the Parser: Your string parser will need to be adjusted to handle the more complex response, which will now include Ethereum's price.
  3. Automatic Updates: Use `llSetTimerEvent()` in your `state_entry` to make the script automatically update the price every 10 minutes, without needing to be touched.

Frequently Asked Questions (FAQ)

1. Why is my http_response event not firing?
This is usually due to one of three things: 1) You haven't granted the script HTTP permissions. Reset the script (Tools > Reset Scripts in the pie menu) and watch for the permission dialog. 2) The URL is malformed or points to a non-existent domain. 3) The remote server is down or is blocking requests from Alife Virtual's servers.
2. Can I connect to a database on my own computer at home?
Yes, but it's tricky. The HTTP request is made from Alife Virtual's servers, not your personal computer. Therefore, your home server must be accessible from the public internet (not just your local network). This usually involves configuring port forwarding on your router and having a static IP address or a dynamic DNS service.
3. What are the limits on HTTP requests in Alife Virtual?
Like all LSL functions, `llHTTPRequest` is subject to governor limits to prevent abuse. A script can have a limited number of active HTTP requests at one time, and there are limits on the total number of requests per object per minute. These limits are generous for normal use but prevent spamming. Always design your scripts to be efficient.
4. This string parsing for JSON is hard. Is there a better way?
For simple key-value pairs, string parsing is manageable. For complex JSON with nested objects and arrays, scripters often use pre-written library functions that act as a more complete parser. While not built into LSL, you can find many examples of these functions on open-source LSL code repositories. This is an excellent next step once you've mastered the basics here.

Summary and Next Steps

Incredible work! You've just learned one of the most powerful skills in the LSL scripter's toolkit. You now understand how to use llHTTPRequest and http_response to make your in-world objects communicate with the outside web. You've sent GET requests, parsed the data, and displayed it in-world, opening up a universe of possibilities for dynamic, interactive content.

Your next step is to practice! Try the exercise, then dream bigger. Could you build a weather station for your island? A board that displays the latest news headlines? A system that sends you a message on Discord when someone visits your land? With HTTP requests, all of this is now within your reach.

Keep an eye on the Alife Virtual School course list for more advanced classes. We're committed to providing free, high-quality education to help you make the most of your virtual life.


Ready to Build Without Limits?

Everything you learned today can be built and tested for free in Alife Virtual. Join our community of over a million residents and start creating today.

When you register, you get immediate access to:

Your new virtual life is waiting. What will you create?

Register for Alife Virtual Now

Claim Your Free Island!


🎓 Ready to Practice In-World?

Get your FREE island and practice everything you just learned — no credit card, no monthly fees.

Claim Your Free Island Now →

No credit card required · Takes 2 minutes · Your island is FREE forever


Published: 2026-03-15 · Difficulty: Advanced · Category: Scripting  |  Questions? Contact us  |  ← Back to School