HttpService

Show Deprecated
Not Creatable
Service

HttpService allows HTTP requests to be sent from game servers using RequestAsync, GetAsync and PostAsync. This service allows games to be integrated with off-Roblox web services such as analytics, data storage, remote server configuration, error reporting, advanced calculations or real-time communication.

You should only send HTTP requests to trusted third-party platforms to avoid making your experience vulnerable to security risks.

Enabling HTTP Requests

Request-sending functions aren't enabled by default: attempting to use them while disabled will result in the error "Http requests are not enabled. Enable via game settings". To send requests, set HttpEnabled to true through the Game Settings interface in Studio under the Security section, or use the Command Bar for unpublished experiences. This property cannot be interacted with at runtime.


-- For unpublished games, use this in the Command Bar:
game:GetService("HttpService").HttpEnabled = true

Other Functions

HttpService also houses the JSONEncode and JSONDecode functions, which are useful for communicating with services that use the JSON format. In addition, the GenerateGUID function provides random 128-bit labels, which can be treated as probabilistically unique in a variety of scenarios.

Use in Plugins

HttpService can also be used by Roblox Studio plugins. They may do this to check for updates, send usage data, download content or other business logic. The first time a plugin attempts to do this, the user may be prompted to give the plugin permission to communicate with the particular web address. A user may accept, deny and revoke such permissions at any time through the Plugin Management window.

Plugins may also communicate with other software running on the same computer through the localhost and 127.0.0.1 hosts. By running programs compatible with such plugins, you can extend the functionality of your plugin beyond the normal capabilities of Roblox Studio, such as interacting with your computer's file system. Beware that such software must be distributed separately from the plugin itself, and can pose security hazards if you aren't careful.

Considerations

  • There are port restrictions. You cannot use port 1194 or any port below 1024, except 80 and 443. If you try to use a blocked port, you will receive either a 403 Forbidden or ERR_ACCESS_DENIED error.
  • For each Roblox game server, there is a limit of 500 HTTP requests per minute. Exceeding this may cause request-sending functions to stall entirely for about 30 seconds.
  • Requests cannot be made to any Roblox website, such as www.roblox.com.
  • Web requests can fail for many reasons, so it is important to "code defensively" (use pcall) and have a plan for when requests fail.
  • Although the http:// protocol is supported, you should use https:// wherever possible.
  • Requests sent should provide a secure form of authentication, such as a pre-shared secret key, so that bad actors cannot pose as one of your Roblox game servers.
  • Be aware of the general capacity and rate-limiting policies of the web servers to which requests are being sent.

Code Samples

Astronauts in Space

local HttpService = game:GetService("HttpService")
local URL_ASTROS = "http://api.open-notify.org/astros.json"
-- Make the request to our endpoint URL
local response = HttpService:GetAsync(URL_ASTROS)
-- Parse the JSON response
local data = HttpService:JSONDecode(response)
-- Information in the data table is dependent on the response JSON
if data.message == "success" then
print("There are currently " .. data.number .. " astronauts in space:")
for i, person in pairs(data.people) do
print(i .. ": " .. person.name .. " is on " .. person.craft)
end
end
Where is the International Space Station?

local HttpService = game:GetService("HttpService")
-- Where is the International Space Station right now?
local URL_ISS = "http://api.open-notify.org/iss-now.json"
local function printISS()
local response
local data
-- Use pcall in case something goes wrong
pcall(function()
response = HttpService:GetAsync(URL_ISS)
data = HttpService:JSONDecode(response)
end)
-- Did our request fail or our JSON fail to parse?
if not data then
return false
end
-- Fully check our data for validity. This is dependent on what endpoint you're
-- to which you're sending your requests. For this example, this endpoint is
-- described here: http://open-notify.org/Open-Notify-API/ISS-Location-Now/
if data.message == "success" and data.iss_position then
if data.iss_position.latitude and data.iss_position.longitude then
print("The International Space Station is currently at:")
print(data.iss_position.latitude .. ", " .. data.iss_position.longitude)
return true
end
end
return false
end
if printISS() then
print("Success")
else
print("Something went wrong")
end
New Pastebin Post

local HttpService = game:GetService("HttpService")
local URL_PASTEBIN_NEW_PASTE = "https://pastebin.com/api/api_post.php"
local dataFields = {
-- Pastebin API developer key from
-- https://pastebin.com/api#1
["api_dev_key"] = "FILL THIS WITH YOUR API DEVELOPER KEY",
["api_option"] = "paste", -- keep as "paste"
["api_paste_name"] = "HttpService:PostAsync", -- paste name
["api_paste_code"] = "Hello, world", -- paste content
["api_paste_format"] = "text", -- paste format
["api_paste_expire_date"] = "10M", -- expire date
["api_paste_private"] = "0", -- 0=public, 1=unlisted, 2=private
["api_user_key"] = "", -- user key, if blank post as guest
}
-- The pastebin API uses a URL encoded string for post data
-- Other APIs might use JSON, XML or some other format
local data = ""
for k, v in pairs(dataFields) do
data = data .. ("&%s=%s"):format(HttpService:UrlEncode(k), HttpService:UrlEncode(v))
end
data = data:sub(2) -- Remove the first &
-- Here's the data we're sending
print(data)
-- Make the request
local response = HttpService:PostAsync(URL_PASTEBIN_NEW_PASTE, data, Enum.HttpContentType.ApplicationUrlEncoded, false)
-- The response will be the URL to the new paste (or an error string if something was wrong)
print(response)

Summary

Properties

  • Local User Security
    Read Parallel

    Indicates whether http request can be sent to external websites.

Methods

Properties

HttpEnabled

Local User Security
Read Parallel

When set to true, you are able to send requests to other websites using HttpService:GetAsync(), HttpService:PostAsync(), and HttpService:RequestAsync().

To enable HTTP requests, the HttpService must be enabled in Studio's Game Settings through the SecurityAllow HTTP Requests toggle.

Methods

GenerateGUID

Write Parallel

The GenerateGUID function randomly creates a universally unique identifier (UUID) string.

The sixteen octets of a UUID are represented as 32 hexadecimal (base 16) digits, displayed in 5 groups separated by hyphens in the form 8-4-4-4-12 for a total of 36 characters. For example: 123e4567-e89b-12d3-a456-426655440000.

The wrapInCurlyBraces argument determines whether the returned string is wrapped in curly braces {}. For instance:

  • true - {94b717b2-d54f-4340-a504-bd809ef5bf5c}
  • false - db454790-7563-44ed-ab4b-397ff5df737b

Parameters

wrapInCurlyBraces: bool

Whether the returned string should be wrapped in {curly braces}.

Default Value: true

Returns

The randomly generated UUID.

Code Samples

HttpService GenerateGUID

local HttpService = game:GetService("HttpService")
local result = HttpService:GenerateGUID(true)
print(result) --> Example output: {4c50eba2-d2ed-4d79-bec1-02a967f49c58}

GetSecret

Write Parallel

This method returns a value previously added to the secrets store for the experience. The secret content is not printable and, for security reasons, secrets are not available when the experience runs locally.

The returned Secret can be transformed using built-in methods such as Secret:AddPrefix(). It is expected to be sent as a part of the HTTP request.

Note that a secret may have an associated domain name. If the domain name is empty, the secret cannot be sent over the network and therefore could not be used as an API key. To allow sending the secret anywhere, set the domain name to *. You can also limit the URL to a specific domain name such as apis.myservice.com or to subdomains of a domain, for example *.myservice.org.

Parameters

key: string

Returns

JSONDecode

Variant
Write Parallel

The JSONDecode function transforms a JSON object or array into a Lua table with the following characteristics:

  • Keys of the table are strings or numbers but not both. If a JSON object contains both, string keys are ignored.
  • An empty JSON object generates an empty Lua table {}.
  • If the input string is not a valid JSON object, this function will throw an error.

To encode a Lua table into a JSON object, you can use the HttpService:JSONEncode() function.

Many web endpoints use JSON, as it is commonly used on the Internet. Visit JSON.org to become more familiar with the format.

This method can be used regardless of whether HTTP Requests are enabled.

Parameters

input: string

The JSON object being decoded.


Returns

Variant

The decoded JSON object as a Lua table.

Code Samples

HttpService JSONDecode

local HttpService = game:GetService("HttpService")
local jsonString = [[
{
"message": "success",
"info": {
"points": 120,
"isLeader": true,
"user": {
"id": 12345,
"name": "JohnDoe"
},
"past_scores": [50, 42, 95],
"best_friend": null
}
}
]]
local data = HttpService:JSONDecode(jsonString)
if data.message == "success" then
-- Since tab["hello"] and tab.hello are equivalent,
-- you could also use data["info"]["points"] here:
print("I have " .. data.info.points .. " points")
if data.info.isLeader then
print("I am the leader")
end
print("I have " .. #data.info.past_scores .. " past scores")
print("All the information:")
for key, value in pairs(data.info) do
print(key, typeof(value), value)
end
end

JSONEncode

Write Parallel

The JSONEncode function transforms a Lua table into a JSON object or array based on the following guidelines:

  • Keys of the table must be either strings or numbers. If a table contains both, an array takes priority (string keys are ignored).

  • An empty Lua table {} generates an empty JSON array.

  • The value nil is never generated.

  • Cyclic table references cause an error.

    This function allows values such as inf and nan, which are not valid JSON. This may cause problems if you want to use the outputted JSON elsewhere.

To reverse the encoding process, and decode a JSON object, you can use the HttpService:JSONDecode() function.

Many web endpoints use JSON, as it is commonly used on the Internet. Visit JSON.org to become more familiar with the format.

This method can be used regardless of whether HTTP Requests are enabled.

Parameters

input: Variant

The input Lua table.


Returns

The returned JSON string.

Code Samples

HttpService JSONEncode

local HttpService = game:GetService("HttpService")
local tab = {
-- Remember: these lines are equivalent
--["message"] = "success",
message = "success",
info = {
points = 123,
isLeader = true,
user = {
id = 12345,
name = "JohnDoe",
},
past_scores = { 50, 42, 95 },
best_friend = nil,
},
}
local json = HttpService:JSONEncode(tab)
print(json)

UrlEncode

Write Parallel

The UrlEncode function percent-encodes a given string so that reserved characters properly encoded with '%' and two hexadecimal characters.

This is useful when formatting URLs for use with HttpService:GetAsync()/HttpService:PostAsync(), or POST data of the media type application/x-www-form-urlencoded (Enum.HttpContentType.ApplicationUrlEncoded).

For instance, when you encode the URL https://www.roblox.com/discover#/, this function returns https%3A%2F%2Fwww%2Eroblox%2Ecom%2Fdiscover%23%2F.

Parameters

input: string

The string (URL) to encode.


Returns

The encoded string.

Code Samples

HttpService UrlEncode

local HttpService = game:GetService("HttpService")
local content = "Je suis allé au cinéma." -- French for "I went to the movies"
local result = HttpService:UrlEncode(content)
print(result) --> Je%20suis%20all%C3%A9%20au%20cinema%2E
New Pastebin Post

local HttpService = game:GetService("HttpService")
local URL_PASTEBIN_NEW_PASTE = "https://pastebin.com/api/api_post.php"
local dataFields = {
-- Pastebin API developer key from
-- https://pastebin.com/api#1
["api_dev_key"] = "FILL THIS WITH YOUR API DEVELOPER KEY",
["api_option"] = "paste", -- keep as "paste"
["api_paste_name"] = "HttpService:PostAsync", -- paste name
["api_paste_code"] = "Hello, world", -- paste content
["api_paste_format"] = "text", -- paste format
["api_paste_expire_date"] = "10M", -- expire date
["api_paste_private"] = "0", -- 0=public, 1=unlisted, 2=private
["api_user_key"] = "", -- user key, if blank post as guest
}
-- The pastebin API uses a URL encoded string for post data
-- Other APIs might use JSON, XML or some other format
local data = ""
for k, v in pairs(dataFields) do
data = data .. ("&%s=%s"):format(HttpService:UrlEncode(k), HttpService:UrlEncode(v))
end
data = data:sub(2) -- Remove the first &
-- Here's the data we're sending
print(data)
-- Make the request
local response = HttpService:PostAsync(URL_PASTEBIN_NEW_PASTE, data, Enum.HttpContentType.ApplicationUrlEncoded, false)
-- The response will be the URL to the new paste (or an error string if something was wrong)
print(response)

GetAsync

Yields

The GetAsync function sends an HTTP GET request. It functions similarly to RequestAsync except that it accepts HTTP request parameters as method parameters instead of a single dictionary and returns only the body of the HTTP response. Generally, this method is useful only as a shorthand and RequestAsync should to be used in most cases.

When true, the nocache parameter prevents this function from caching results from previous calls with the same url.

Parameters

url: Variant

The web address you are requesting data from.

nocache: bool

Whether the request stores (caches) the response.

Default Value: false
headers: Variant

Used to specify some HTTP request headers.


Returns

The GET request's response body.

Code Samples

Astronauts in Space

local HttpService = game:GetService("HttpService")
local URL_ASTROS = "http://api.open-notify.org/astros.json"
-- Make the request to our endpoint URL
local response = HttpService:GetAsync(URL_ASTROS)
-- Parse the JSON response
local data = HttpService:JSONDecode(response)
-- Information in the data table is dependent on the response JSON
if data.message == "success" then
print("There are currently " .. data.number .. " astronauts in space:")
for i, person in pairs(data.people) do
print(i .. ": " .. person.name .. " is on " .. person.craft)
end
end
Where is the International Space Station?

local HttpService = game:GetService("HttpService")
-- Where is the International Space Station right now?
local URL_ISS = "http://api.open-notify.org/iss-now.json"
local function printISS()
local response
local data
-- Use pcall in case something goes wrong
pcall(function()
response = HttpService:GetAsync(URL_ISS)
data = HttpService:JSONDecode(response)
end)
-- Did our request fail or our JSON fail to parse?
if not data then
return false
end
-- Fully check our data for validity. This is dependent on what endpoint you're
-- to which you're sending your requests. For this example, this endpoint is
-- described here: http://open-notify.org/Open-Notify-API/ISS-Location-Now/
if data.message == "success" and data.iss_position then
if data.iss_position.latitude and data.iss_position.longitude then
print("The International Space Station is currently at:")
print(data.iss_position.latitude .. ", " .. data.iss_position.longitude)
return true
end
end
return false
end
if printISS() then
print("Success")
else
print("Something went wrong")
end

PostAsync

Yields

The PostAsync function sends an HTTP POST request. It functions similarly to RequestAsync except that it accepts HTTP request parameters as method parameters instead of a single dictionary and returns only the body of the HTTP response. Generally, this method is useful only as a shorthand and RequestAsync should to be used in most cases.

When true, the compress parameter controls whether large request bodies will be compressed using gzip.

Parameters

url: Variant

The destination address for the data.

data: string

The data being sent.

content_type: Enum.HttpContentType

Modifies the value in the Content-Type header sent with the request.

Default Value: "ApplicationJson"
compress: bool

Determines whether the data is compressed (gzipped) when sent.

Default Value: false
headers: Variant

Used to specify some HTTP request headers.


Returns

The HTTP response sent back indicating the request result.

Code Samples

New Pastebin Post

local HttpService = game:GetService("HttpService")
local URL_PASTEBIN_NEW_PASTE = "https://pastebin.com/api/api_post.php"
local dataFields = {
-- Pastebin API developer key from
-- https://pastebin.com/api#1
["api_dev_key"] = "FILL THIS WITH YOUR API DEVELOPER KEY",
["api_option"] = "paste", -- keep as "paste"
["api_paste_name"] = "HttpService:PostAsync", -- paste name
["api_paste_code"] = "Hello, world", -- paste content
["api_paste_format"] = "text", -- paste format
["api_paste_expire_date"] = "10M", -- expire date
["api_paste_private"] = "0", -- 0=public, 1=unlisted, 2=private
["api_user_key"] = "", -- user key, if blank post as guest
}
-- The pastebin API uses a URL encoded string for post data
-- Other APIs might use JSON, XML or some other format
local data = ""
for k, v in pairs(dataFields) do
data = data .. ("&%s=%s"):format(HttpService:UrlEncode(k), HttpService:UrlEncode(v))
end
data = data:sub(2) -- Remove the first &
-- Here's the data we're sending
print(data)
-- Make the request
local response = HttpService:PostAsync(URL_PASTEBIN_NEW_PASTE, data, Enum.HttpContentType.ApplicationUrlEncoded, false)
-- The response will be the URL to the new paste (or an error string if something was wrong)
print(response)

RequestAsync

Yields

This method sends an HTTP request using a dictionary to specify the request data, such as the target URL, method, headers and request body data. It returns a dictionary that describes the response data received. Optionally, the request can be compressed using HttpCompression.

Request Dictionary Fields

NameTypeRequiredDescription
UrlStringyesThe target URL for this request. Must use http or https protocols.
MethodStringnoThe HTTP method being used by this request, most often GET or POST.
HeadersDictionarynoA dictionary of headers to be used with this request. Most HTTP headers are accepted here, but not all.
BodyStringnoThe request body. Can be any string, including binary data. Must be excluded when using the GET or HEAD HTTP methods. It might be necessary to specify the Content-Type header when sending JSON or other formats.
CompressEnum.HttpCompressionnoAn optional compression field that will compress the data in the request. The value can either be None or Gzip.

HTTP Headers

In the request dictionary, you can specify custom HTTP headers to use in the request. However, some headers cannot be specified. For example, Content-Length is determined from the request body. User-Agent and Roblox-Id are locked by Roblox. Other headers like Accept or Cache-Control use default values but can be overridden. More commonly, some REST APIs may require API keys or other service authentication to be specified in request headers.

This method does not detect the format of body content. Many web servers require the Content-Type header be set appropriately when sending certain formats. Other methods of HttpService use the Enum.HttpContentType enum; for this method set the Content-Type header appropriately: text/plain, text/xml, application/xml, application/json or application/x-www-form-urlencoded are replacement Content-Type header values for the respective enum values.

Response Dictionary Fields

The function returns a dictionary containing the following fields:

NameTypeDescription
SuccessBooleanThe success status of the request. This is true if and only if the StatusCode lies within the range [200, 299].
StatusCodeIntegerThe HTTP response code identifying the status of the response.
StatusMessageStringThe status message that was sent back.
HeadersDictionaryA dictionary of headers that were set in this response.
BodyThe request body (content) received in the response.

Error Cases

This method raises an error if the response times out or if the target server rejects the request. If a web service goes down for some reason, it can cause scripts that use this method to stop functioning altogether. It is often a good idea to wrap calls to this method in pcall and gracefully handle failure cases if the required information isn't available.

Limitations

The current limitation for sending and receiving HTTP requests is 500 requests per minute. Requests over this threshold will fail. Additionally, Roblox domains are excluded. This means that HTTP requests cannot be sent to any Roblox owned site, such as www.roblox.com.

Parameters

requestOptions: Dictionary

A dictionary containing information to be requested from the server specified.


Returns

A dictionary containing response information from the server specified.

Code Samples

Sending an HTTP Request

-- Remember to set enable HTTP Requests in game settings!
local HttpService = game:GetService("HttpService")
local function request()
local response = HttpService:RequestAsync({
Url = "http://httpbin.org/post", -- This website helps debug HTTP requests
Method = "POST",
Headers = {
["Content-Type"] = "application/json", -- When sending JSON, set this!
},
Body = HttpService:JSONEncode({ hello = "world" }),
})
if response.Success then
print("Status code:", response.StatusCode, response.StatusMessage)
print("Response body:\n", response.Body)
else
print("The request failed:", response.StatusCode, response.StatusMessage)
end
end
-- Remember to wrap the function in a 'pcall' to prevent the script from breaking if the request fails
local success, message = pcall(request)
if not success then
print("Http Request failed:", message)
end

Events