# llHTTPResponse

*LSL function*

```lsl
void llHTTPResponse(key request_id, integer status, string body);
```

- `key request_id`: Unique key identifying the incoming HTTP request.
- `integer status`: Integer HTTP status code (such as 200, 400, or 404) to respond with.
- `string body`: String contents of the response body.

- Energy: 10

Responds to **request_id** with **status** and **body**.

The response need not be made inside the [http_request](/events/http_request/) event but if it does not happen in a timely fashion the request will time out (within 25 seconds).

```lsl title="How to use" frame="terminal"
llHTTPResponse(NULL_KEY, 0, "");
```

## Caveats

- This call must be made by the script containing the [http_request](/events/http_request/) event where the **request_id** was received.
- There is no limit, other than script size, to the amount of data that can be sent by this function.
  - [llHTTPRequest](/functions/llHTTPRequest/) can truncate the response length in *receiving* scripts. Be aware when using them together for prim-to-prim communications.
- The response by default has `"content-type: text/plain"`. Use [llSetContentType](/functions/llSetContentType/) to optionally return a different type, like `"text/html"`.
- Besides [llSetContentType](/functions/llSetContentType/), there is no way to set any custom HTTP headers in the response.

## Examples

<details open>
<summary>Example 1</summary>

```lsl collapse={1-29, 35-50}
string url;

default
{
    changed(integer change)
    {
        if (change & (CHANGED_REGION_START | CHANGED_REGION | CHANGED_TELEPORT))
            llResetScript();
    }

    state_entry()
    {
        llRequestURL();
    }

    touch_start(integer num_detected)
    {
    //  PUBLIC_CHANNEL has the integer value 0
        if (url != "")
            llSay(PUBLIC_CHANNEL, "URL: " + url);
    }

    http_request(key id, string method, string body)
    {
    //  http://en.wikipedia.org/wiki/Create,_read,_update_and_delete
        list CRUDmethods = ["GET", "POST", "PUT", "DELETE"];
    //  it's bit-wise NOT ( ~ ) !!!
        integer isAllowedMethod = ~llListFindList(CRUDmethods, [method]);

        if (isAllowedMethod)
        {
            llHTTPResponse(id, 200, "Body of request below:\n" + body);
        }
        else if (method == URL_REQUEST_GRANTED)
        {
        //  don't forget the trailing slash
            url = body + "/";

            llOwnerSay("URL: " + url);
        }
        else if (method == URL_REQUEST_DENIED)
        {
            llOwnerSay("Something went wrong, no URL.\n" + body);
        }
        else
        {
            llOwnerSay("Ummm... I have no idea what SL just did. Method=\""+method+"\"\n" + body);
        }
    }
}
```

</details>

## History

- SVN:1836 r112899 Trunk

## Known issues

From the issue templates included by the wiki article:

- SCR-396 (nf): **llHTTPImageResponse**() - function for sending image data as a response to an HTTP request

## See also

### Functions

- [llGetFreeURLs](/functions/llGetFreeURLs/)
- [llRequestURL](/functions/llRequestURL/)
- [llRequestSecureURL](/functions/llRequestSecureURL/)
- [llReleaseURL](/functions/llReleaseURL/)
- [llGetHTTPHeader](/functions/llGetHTTPHeader/)
- [llSetContentType](/functions/llSetContentType/)

### Events

- [http_request](/events/http_request/)
- [http_response](/events/http_response/)

### Articles

- [LSL http server](https://wiki.secondlife.com/wiki/LSL_http_server)

---

*Source: [LlHTTPResponse](https://wiki.secondlife.com/wiki/LlHTTPResponse) on the Second Life Wiki. Content from the Second Life Wiki articles LlHTTPResponse (revision 1219025, 2026-09-08) and Template:Issues/SCR-396 (revision 1171982, 2012-08-23), CC BY-SA 3.0.*

---

From lsl.dev: https://lsl.dev/functions/llHTTPResponse/
