Search code examples
javascriptnode.jssynology

Synology NAS API get free and total space


I am trying to call the API of a Synology NAS to retrieve information on free space and total space available.

My Login works, and I am getting my Token, requests with that token are shown as "successful".

However, when I try to call for the list_share method, with the additional value set to volume_status which according the documentation of the API should give me the desired data, all I get is:

{
    "data": {
        "offset": 0,
        "shares": [],
        "total": 0
    },
    "success": true
}

The request I am making is:

https://NAME:5001/webapi/entry.cgi?api=SYNO.FileStation.List&version=2&method=list_share&additional=volume_status&_sid=TOKEN

Am I making the wrong request? Do I need to change the Method from list_share to list? Am I passing the additional value wrong?

The Documentation I am using can be found when googling for 'Synology NAS rest API'. I inserted the direct download link for the PDF here.


Solution

  • According to the linked documentation, the additional parameter needs additional brackets and quotes like this:

    https://NAME:5001/webapi/entry.cgi?api=SYNO.FileStation.List&version=2&method=list_share&additional=["volume_status"]&_sid=TOKEN

    Depending on the library you use you might need to encode the brackets and the quotes, but most libraries should do that for you :)


    To come to that conclusion, this is what i did:

    In the linked documentation i found the section about list_share and the provided example:

    GET /webapi/entry.cgi?api=SYNO.FileStation.List&version=2&method=list_share& additional=%5B%22real_path%22%2C%22owner%2Ctime%22%5D

    This is completely unreadable, since the url is already encoded, but opening the browser console and running

    decodeURIComponent("/webapi/entry.cgi?api=SYNO.FileStation.List&version=2&method=list_share&additional=%5B%22real_path%22%2C%22owner%2Ctime%22%5D")

    leads me to a readable url:

    /webapi/entry.cgi?api=SYNO.FileStation.List&version=2&method=list_share&additional=["real_path","owner,time"]


    This is an example, how to login, print out the data and logout again:

    const http = require("http");
    
    // Helper function to get JSON from an endpoint
    function getJson(url) {
      return new Promise((resolve, reject) => {
        http.get(url, (res) => {
          res.setEncoding("utf8");
          let rawData = "";
          res.on("data", (chunk) => {
            rawData += chunk;
          });
          res.on("end", () => {
            try {
              const parsedData = JSON.parse(rawData);
              resolve(parsedData);
            } catch (e) {
              reject(e);
            }
          });
        });
      });
    }
    
    (async () => {
      const host = "synology:5000";
      const user = "userHere";
      const password = "passwordHere";
    
      // login
      const {
        data: { sid },
      } = await getJson(
        `http://${host}/webapi/query.cgi?api=SYNO.API.Auth&method=login&version=3&account=${user}&passwd=${password}&session=test&format=sid`
      );
    
      const url = `http://${host}/webapi/query.cgi?api=SYNO.FileStation.List&method=list_share&version=2&_sid=${sid}&additional=["volume_status"]`;
      const { data } = await getJson(url);
    
      data.shares.forEach((share) => {
        console.log(share.name, "-", share.path);
        console.log(share.additional.volume_status);
      });
    
      //logout
      await getJson(
        `http://${host}/webapi/query.cgi?api=SYNO.API.Auth&method=logout&version=3&session=test`
      );
    })();