Open Cloud | Place Publishing API (node.js)

Place Publishing API

Greetings everyone!

Today I will be creating a tutorial on how you can use the Open Cloud Place Publishing API. This API in the Open Cloud is based off the “Save” and “Publish” button in Roblox studio but allow us to save or publish an experience file from outside of Roblox in our own applications. This API has been out a while now but I have decided to make it so that there is a tutorial on how to use this API in node.js due to the tutorial Roblox has made there are examples in CURL only.

Quick Note: This tutorial is for how to use the Roblox API through the use of the Roblox Open Cloud. This tutorial is NOT for the Roblox internal API which uses Roblox security cookies to authenticate requests. This tutorial will also contain examples off how to use the Place Publishing API which are written using JavaScript (in the runtime environment node.js). Sending requests will be different for different programming languages however the basic idea of how to use the Place Publishing API are the same.

Tutorial Contents:

  • An explanation of what this Open Cloud API is and how it can be used.

  • Explaining and showing how to use it/send a request to the API endpoint.

  • Showing the errors that you may get (with an example of basic error management).

Please before using this tutorial learn how to send basic API requests before attempting to use this tutorial. Although it will explain how to use the Place Publishing API endpoint I will not be going into major details into how to send requests.


What is the Place Publishing API and what can we use it for?

The Place Publishing API has been out for around a 1-2 years now (it came out in September 2020). It is based off the “Publish” and “Save” button which is inside of studio that allow developers to save or publish the experience however this API allows us to publish or save an experience remotely outside of Roblox studio. Currently of making this post there is only one API endpoint in the Place Publishing API which is to publish or save an experience file.

At the moment there are not a ton of usage for the Place Publishing API because it does not allow us to get the experience file however some possible use cases is if we wanted to create some type of automated system where you put the game file in and it will auto upload (however I personally don’t see a massive use case out of that).

How to use the Place Publishing API?

To use the Place Publishing API we must first create an Open Cloud API key which acts as our authentication for the API request. To create our Open Cloud API key we simply go to https://create.roblox.com/credentials and then click the large blue button which says “CREATE API KEY”. Once clicked you need fill in the name and if you want you can also add a description (description is not required however). After putting a name and description if you scroll down the page there will be an area called “Access Permissions”. In this section you click the selection menu, then choose the “Place Publishing” option and press the white button which says “Add API System”. You then need to search for your experience, add the experience and then on the select down menu where it allows you to add operations click “Write”. You then need to move down to the last section called “Security”. This area you need to place your IP address (or hosting of the API address). If you wish any IP to be able to use it you should be able to just add 0.0.0.0/0 as the IP address. This is however not recommended due to anyone being able to use the key if they get access to it. You should then copy your API key, you must write this down somewhere as you cannot see it again once you go off the page.

Now we can get into the main programming. The request type is a POST request to the endpoint: https://apis.roblox.com/universes/v1/universe/{universeId}/place/{placeId}/versions
In the endpoint we require to have two parameters which is the universe ID and the place ID. Some people get mixed up with the difference between the universe ID and the place ID so let me explain the difference between them so you don’t get mixed up. Inside of an experience you can have multiple places (for example you have the default one which may be a lobby but you may also have a game place with the main game in and you get teleport from the main place/lobby to this other place) so the place ID is the ID of the place you wish to overwrite. The universe ID however on the other hand is like the experience ID which is the ID over all for all the places. The reason why you require to add both the universe ID and the place ID is because you require to say what experience it is you wish to edit the place off and then the place ID is so you can say what place you wish to change. The way that you get the universe ID is by going to https://create.roblox.com/creations, clicking on your experience and then in the URL on the page is the universe ID (you can see this in the first image below). To get the place ID, you can either go into Roblox studio, get up the “Asset Manager” which is under the “View” tab, click on “Places” and then right click and copy the ID of the place you wish OR if you wish to get the default place you can just go to the URL (e.g. Prison Life (Cars fixed!) - Roblox) and then copy the ID inside of the URL (I will send a picture of both methods after I show the universe ID).

Universe ID:

Place ID:

OR

After we have changed the URL to have the place ID and the universe ID in we now need to add in another parameter called “versionType” however this one is not inside of the URL as a path but rather inside of the main part of the request. The versionType is so that we can choose if we wish to either save the place or publish the place. The value to this parameter must be either “Saved” OR “Published”, no other option is allowed and you will get an error if you include anything else. We also require to select the place file which we wish to either publish or save. The file types which are allowed are either a .rbxl file type or a .rbxlx file type. To select the file and put it into the body of the request we can use the package which comes with node.js by default which is fs that has a function called readFileSync() which we can get the file of and then the file name. The last part is the headers of the request which there are two off. The two headers is an x-api-key which is the API key we made and copied before and the Content-Type which the value off will be different depending on the type of place file you are uploading. For .rbxl file type the content type will be “application/octet-stream” but for the .rbxlx will be “application/xml”. If the request is successful then in the response body it should have the version type meaning it has been successfully done.

Example Module:

module.exports.Write = async function Write() {

    const Axios = require(`axios`)

    const fs = require(`fs`)

    Axios.post(`https://apis.roblox.com/universes/v1/2282454601/places/6220039459/versions`, fs.readFileSync(`APITest.rbxl`),{

        params:{

            'versionType': "Published"

        },

        headers:{

            'x-api-key': "APIKEYHERE",

            'Content-Type': "application/octet-stream"

        }

    }).then(response =>{

        console.log(response.data)

    }).catch(err =>{

        console.log(err.response.status)

        if (err.response.status == 400) return console.log("Invalid request / Invalid file content.")

        if (err.response.status == 401) return console.log("API key not valid for operation, user does not have authorization.")

        if (err.response.status == 403) return console.log("Publish not allowed on place.")

        if (err.response.status == 404) return console.log("Place or universe does not exist.")

        if (err.response.status == 409) return console.log("Place not part of the universe.")

        if (err.response.status == 500) return console.log("Server internal error / Unknown error.")

    })

}

Error Handling

I will now be moving onto my last section of this tutorial which will be about Error handling. Error handling is very important because if you don’t your system can get issues and break. one of the main part of error handling is first to catch the error. After a request with axios if we get an error, axios will attempt to show us this error. If we just leave this error unattended it will break out bot/application so due to this we can use .catch() to catch any errors we get. We can then use the information from the error we get to send a response back explaining what the issue is.

The main error codes for the Place Publishing API as stated inside of the documentation are:

Conclusion of tutorial

I will now be ending my tutorial on how to use the Place Publishing API. I hope this tutorial helped some people who may not understand curl or in general was confused about the Roblox documentation. If you have any questions or issues your welcome to commend them down below or send me a direct message here on the forums.

If you have any issues you can also check below:

5 Likes

You just gave me an idea. Create a program that can publish the game every 5 minutes so that you don’t lose progress. Is it possible in Java?

1 Like

Yes, it is possible, you could do that in any programming language including Java.

1 Like

Just as an update to anyone who may not know, currently the documentation for the Place Publishing API is incorrect. The path they are saying you should add onto the base URL is:

/v1/universe/{universeId}/place/{placeId}/versions

This however seems to be the incorrect path and rather should be set as (base URL + path below):

/v1/{universeId}/place/{placeId}/versions

Already reported this documentation bug to the bug support team, just awaiting a response from them. I will write up a reply to this message when they fix this.

This tutorial should still be correct (as it seems the docs are wrong) I just wanted to let anyone know who reads the documentation Roblox made and is confused, that is why it will give you an error when trying to use this path.