Welcome to Roxy!
Roxy is a free proxy for Roblox web APIs. The code for Roxy is planned to be made open source in the future. Right now the code may not be 100% secure, so I am afraid to release it publicly and someone uses it and runs into issues, or a bad actor uses it and exploits the server with a vulnerability I did not foresee (not to mention the code is pretty hideous because this is my first project like this). I am still learning web development, so if you find any security issues or just general issues, please let me know! If you're a White Hat, refer to the bottom of the page for more info on vulnerability reporting and rewards.
The person who made Roproxy has a GitHub available to make your own proxy. So if you are looking for this option, it exists and is your safest option for using a proxy.
Why did I make Roxy? Because Roproxy throttles about 60 seconds per request. Thus I wanted something a bit faster for my own projects. Specifically my Bundle and Character/Outfit Inserter (shameful plug) plugin as of right now. I figured if I'm going to make the proxy anyway, I may as well share it. My general rule of thumb for most things I make really, haha.
General Tips (Highly Recommended Reading)
Note: Remove the prepended
_|WARNING:-DO-NOT-SHARE-THIS.--...|_
text if present in your token, otherwise
Roblox will give you an error due to an invalid character (specifically the pipe "|" character).
If you use RequestAsync, Roblox gives you the response headers. There are three custom headers that Roxy adds:
Roxy-Requests-Left
: How many more requests you have until you get throttled.Roxy-Throttle-Reset
: How many seconds until your request pool resets.Roxy-Throttled
: Whether or not you have been throttled.
You get around 100 requests a minute. However, for every request you make your throttle reset timer increases by 1 second.
So if you quickly make 100 requests, you will have to wait an extra 100 seconds on top of whatever time your throttle reset timer is at.
This shouldn't be a huge problem unless you are either trying to scrape data, or you maybe have a really big server that makes a lot of requests.
If the latter, then try to cache data as much as possible, and if you can't, let me know what your use case is and I can potentially increase the request limit.
At least hopefully with the above headers, you should be able to try to balance your request limit.
Example: GET Request (and prettyprint example)
You can use Roxy exactly like the Roblox API, just prefix your Roblox endpoint with
https://roxytheproxy.com/
. For example:
https://roxytheproxy.com/avatar.roblox.com/v2/avatar/users/29371917/outfits?outfitType=Avatar&page=1&itemsPerPage=100&isEditable=true
In the case of that user ID, you will get something that looks like this:
{"data":[{"id":152266819767,"name":"X","isEditable":true,"outfitType":"Avatar"},{"id":26926749690,"name":"I","isEditable":true,"outfitType":"Avatar"},{"id":11706768233,"name":"H","isEditable":true,"outfitType":"Avatar"},{"id":7277992048,"name":"A","isEditable":true,"outfitType":"Avatar"},{"id":3977261404,"name":"B","isEditable":true,"outfitType":"Avatar"},{"id":87611659,"name":"F","isEditable":true,"outfitType":"Avatar"},{"id":87610579,"name":"G","isEditable":true,"outfitType":"Avatar"}],"paginationToken":""}
That will work if you put it in the browser's URL, but you can also do this from Roblox using HttpService (which is probably what you're here for)
local URL = "https://roxytheproxy.com/avatar.roblox.com/v2/avatar/users/29371917/outfits?outfitType=Avatar&page=1&itemsPerPage=100&isEditable=true"
print(HttpService:GetAsync(URL))
Adding &prettyprint=true
makes the JSON easier to read (this is specific to Roxy,
and also works for all request types).
Pretty-printed GET
https://roxytheproxy.com/avatar.roblox.com/v2/avatar/users/29371917/outfits?outfitType=Avatar&page=1&itemsPerPage=100&isEditable=true&prettyprint=true
{
"data": [
{ "id": 152266819767, "name": "X", "isEditable": true, "outfitType": "Avatar" },
{ "id": 26926749690, "name": "I", "isEditable": true, "outfitType": "Avatar" },
{ "id": 11706768233, "name": "H", "isEditable": true, "outfitType": "Avatar" },
{ "id": 7277992048, "name": "A", "isEditable": true, "outfitType": "Avatar" },
{ "id": 3977261404, "name": "B", "isEditable": true, "outfitType": "Avatar" },
{ "id": 87611659, "name": "F", "isEditable": true, "outfitType": "Avatar" },
{ "id": 87610579, "name": "G", "isEditable": true, "outfitType": "Avatar" }
],
"paginationToken": ""
}
Example: PATCH Request
local HEADERS = {
["X-Roblox-Token"] = "YOUR_ROBLOX_TOKEN",
["Content-Type"] = "application/json",
}
HttpService:RequestAsync({
Url = "https://roxytheproxy.com/users.roblox.com/v1/users/YOUR_USER_ID/display-names",
Method = "PATCH",
Headers = HEADERS,
Body = HttpService:JSONEncode({ newDisplayName = "Roxy" }),
})
Example: POST Request
local HEADERS = {
["X-Roblox-Token"] = "YOUR_ROBLOX_TOKEN",
}
HttpService:PostAsync(
`https://roxytheproxy.com/accountinformation.roblox.com/v1/description`,
HttpService:JSONEncode({description = "New Description!"}),
Enum.HttpContentType.ApplicationJson,
false,
HEADERS
)
-- Or using RequestAsync:
local HEADERS = {
["X-Roblox-Token"] = "YOUR_ROBLOX_TOKEN",
["Content-Type"] = "application/json",
}
HttpService:RequestAsync({
Url = "https://roxytheproxy.com/accountinformation.roblox.com/v1/description",
Method = "POST",
Headers = HEADERS,
Body = HttpService:JSONEncode({ description = "New Description!" }),
})
Example: DELETE Request (remove badge)
local HEADERS = { ["X-Roblox-Token"] = "YOUR_ROBLOX_TOKEN" }
HttpService:RequestAsync({
Url = "https://roxytheproxy.com/badges.roblox.com/v1/user/badges/4396259312169682",
Method = "DELETE",
Headers = HEADERS,
})
Token Safety & White Hats
You can pass your own ROBLOSECURITY
token via the X-Roblox-Token
header
for authenticated requests. This is optional for GET
calls (unless required by Roblox).
If you do pass it for GET
requests (not recommended for your general safety) you will
just help alleviate the internal tokens throttling potential. Thank you, but prioritize your safety.
Passing your ROBLOSECURITY token is very risky. Even if the server is secure and the headers
are encrypted, you never know if that server is storing your token. So please be careful and
make sure you trust whatever it is you are sending your token to.
Also, even if the
code for a server is open source, you never actually know what is running on the server. Anyone
can lie at anytime. So again, please be very careful.
If you're a White Hat and find a vulnerability, I'm offering rewards from $50–$250 USD depending on severity. Any serious exploit report is always paid and appreciated. I'm still learning web development, so there may be a lot of issues.
Roxy Internals
Roxy was made using Python and Flask. It is hosted using the second tier option of Lightsail on AWS. Which means there is 2TB of transfer data per month. So if the site goes down that is probably why. Hopefully 2TB is enough, but I will monitor.
Internally, whenever a request is made, Roxy will try to make a direct call to the API. If that call is throttled (about 60 seconds per request, and this is tracked so no unnecessary calls are made), Roxy will then try Roproxy. If Roproxy is also throttled (same cooldown applies as above), Roxy will then start iterating through a list of internally used tokens. If those tokens expire, I get an email and I can update them in a few minutes.
How much does Roxy cost to maintain? As of right now, 7 USD per month (for the Lightsail instance) + 15 USD per year (for the domain). So right now it is very manageable to maintain, but if you want to support me beyond just using anything I make then you can find a way to support me below :).
Support Me
If you would like to support me, you can support me at at Ko-fi. Any amount is appreciated! You never have to donate though, you just using anything I make is enough support for me. If you ever make anything with something I create, please tag me in it, I'd love to see it!