Published on July 22, 2020.
Here's a follow-up to this post. Learn how you can use SuiteScript and SuiteQL to work with the File Cabinet, including querying it to get lists of folders and files, creating and deleting folders, uploading files, getting file contents, and more.
I've written quite a bit about how I'm using the SuiteQL capabilities of NetSuite's SuiteTalk REST Web Services for integration projects. One of the projects that I'm working on involves integrating with the NetSuite File Cabinet, and I'm using SuiteQL for that project as well. I thought I'd share some information about what you can do with SuiteQL when it comes to the File Cabinet.
Let's start by taking a quick look at the File Cabinet for a relatively new Sandbox instance. In terms of folders and files, there isn't much to this instance's File Cabinet. Note that I've selected the SuiteScripts folder, and that there are a few scripts in the folder, as well as a couple of subfolders. As we work through some example queries, referring to this screen shot might be helpful.
Now let's take a look at some queries.
NetSuite provides access to folders via the MediaItemFolder table. Here's a query that I wrote to get the top-level (root) folders in the File Cabinet.
SELECT * FROM MediaItemFolder WHERE ( IsTopLevel = 'T' )
And here's the response.
{ "links": [ { "rel": "self", "href": "https:\/\/signal_promos.r2021.a1.suitetalk.api.netsuite.com\/services\/rest\/query\/v1\/suiteql?limit=1000&offset=0" } ], "count": 8, "hasMore": false, "items": [ { "links": [], "appfolder": "App Packages", "enablecompression": "F", "foldersize": "0", "foldertype": "APPPACKAGES", "id": "-18", "isinactive": "F", "isprivate": "F", "istoplevel": "T", "lastmodifieddate": "6\/27\/2020", "name": "App Packages", "numfolderfiles": "0", "owner": "-4" }, { "links": [], "appfolder": "Attachments Received", "description": "Attachments Received Folder", "enablecompression": "F", "foldersize": "712531", "foldertype": "ATTACHMENTSRECEIVED", "id": "-10", "isinactive": "F", "isprivate": "F", "istoplevel": "T", "lastmodifieddate": "6\/27\/2020", "name": "Attachments Received", "numfolderfiles": "82", "owner": "-4" }, { "links": [], "appfolder": "Attachments to Send", "description": "Attachments to Send Folder", "enablecompression": "F", "foldersize": "0", "foldertype": "ATTACHMENTSTOSEND", "id": "-14", "isinactive": "F", "isprivate": "F", "istoplevel": "T", "lastmodifieddate": "6\/27\/2020", "name": "Attachments to Send", "numfolderfiles": "0", "owner": "-4" }, { "links": [], "appfolder": "Images", "description": "Images Folder", "enablecompression": "F", "foldersize": "4347.4892578125", "foldertype": "IMAGES", "id": "-4", "isinactive": "F", "isprivate": "F", "istoplevel": "T", "lastmodifieddate": "6\/11\/2020", "name": "Images", "numfolderfiles": "32", "owner": "-4" }, { "links": [], "appfolder": "SuiteApps", "enablecompression": "F", "foldersize": "3145220", "foldertype": "SUITEAPPS", "id": "-19", "isinactive": "F", "isprivate": "F", "istoplevel": "T", "lastmodifieddate": "6\/27\/2020", "name": "SuiteApps", "numfolderfiles": "10", "owner": "-4" }, { "links": [], "appfolder": "SuiteScripts", "description": "SuiteScripts Folder", "enablecompression": "F", "foldersize": "6.0224609375", "foldertype": "SUITESCRIPTS", "id": "-15", "isinactive": "F", "isprivate": "F", "istoplevel": "T", "lastmodifieddate": "6\/7\/2020", "name": "SuiteScripts", "numfolderfiles": "1", "owner": "-4" }, { "links": [], "appfolder": "Temp", "enablecompression": "F", "foldersize": "1872", "foldertype": "DEFAULT", "id": "9", "isinactive": "F", "isprivate": "F", "istoplevel": "T", "lastmodifieddate": "6\/20\/2020", "name": "Temp", "numfolderfiles": "2", "owner": "4" }, { "links": [], "appfolder": "Templates", "description": "Templates Folder", "enablecompression": "F", "foldersize": "162120", "foldertype": "TEMPLATES", "id": "-9", "isinactive": "F", "isprivate": "F", "istoplevel": "T", "lastmodifieddate": "6\/27\/2020", "name": "Templates", "numfolderfiles": "3", "owner": "-4" } ], "offset": 0, "totalResults": 8 }
As you can see, each folder has a name and an ID. NetSuite also assigns a folder type, and automatically calculates the size of a folder, the number of files in a folder, and more.
Suppose that we want to see a folder's subfolders. In this example, I'm querying for the subfolders in the SuiteScripts folder.
SELECT MediaItemFolder.* FROM MediaItemFolder WHERE ( MediaItemFolder.Parent = -15 )
And here's the response.
{ "links": [ { "rel": "self", "href": "https:\/\/signal_promos.r2021.a1.suitetalk.api.netsuite.com\/services\/rest\/query\/v1\/suiteql?limit=1000&offset=0" } ], "count": 2, "hasMore": false, "items": [ { "links": [], "appfolder": "SuiteScripts : checkout", "description": "Checkout Web App", "enablecompression": "F", "foldersize": "20.03515625", "foldertype": "DEFAULT", "id": "10", "isinactive": "F", "isprivate": "F", "istoplevel": "F", "lastmodifieddate": "6\/30\/2020", "name": "checkout", "numfolderfiles": "6", "owner": "4", "parent": "-15", "parentfoldername": "SuiteScripts" }, { "links": [], "appfolder": "SuiteScripts : sales portal", "enablecompression": "F", "foldersize": "4.087890625", "foldertype": "DEFAULT", "id": "11", "isinactive": "F", "isprivate": "F", "istoplevel": "F", "lastmodifieddate": "7\/16\/2020", "name": "sales portal", "numfolderfiles": "1", "owner": "4", "parent": "-15", "parentfoldername": "SuiteScripts" } ], "offset": 0, "totalResults": 2 }
In the query, I'm specifying that I want folders whose parent folder is SuiteScripts (which has ID -15). As you can see, there are currently two subfolders in that folder.
Using these queries, you could provide an external interface to the File Cabinet and give users a way to "drill into" its folders and subfolders.
Of course, NetSuite also provides access to the files in a File Cabinet, and it does so via the File table. Let's take a look at a query and response.
For the query, I'm asking for files in the "checkout" subfolder, which has an ID of 10.
SELECT File.* FROM File WHERE ( File.Folder = 10 )
Here's the response.
{ "links": [ { "rel": "self", "href": "https:\/\/signal_promos.r2021.a1.suitetalk.api.netsuite.com\/services\/rest\/query\/v1\/suiteql?limit=1000&offset=0" } ], "count": 6, "hasMore": false, "items": [ { "links": [], "addtimestamptourl": "F", "bundleable": "F", "createddate": "6\/21\/2020", "filesize": "2661", "filetype": "JAVASCRIPT", "folder": "10", "hideinbundle": "F", "id": "734", "iscompanywidereadaccess": "F", "isinactive": "F", "islink": "F", "isonline": "F", "lastmodifieddate": "6\/21\/2020", "name": "chk-events-api.restlet.js" }, { "links": [], "addtimestamptourl": "F", "bundleable": "F", "createddate": "6\/7\/2020", "filesize": "3421", "filetype": "JAVASCRIPT", "folder": "10", "hideinbundle": "F", "id": "733", "iscompanywidereadaccess": "F", "isinactive": "F", "islink": "F", "isonline": "F", "lastmodifieddate": "6\/7\/2020", "name": "chk-noninventoryitem-api.restlet.js" }, { "links": [], "addtimestamptourl": "F", "bundleable": "F", "createddate": "6\/7\/2020", "filesize": "4869", "filetype": "JAVASCRIPT", "folder": "10", "hideinbundle": "F", "id": "732", "iscompanywidereadaccess": "F", "isinactive": "F", "islink": "F", "isonline": "F", "lastmodifieddate": "6\/7\/2020", "name": "chk-so-api.restlet.js" }, { "links": [], "addtimestamptourl": "F", "bundleable": "F", "createddate": "6\/7\/2020", "filesize": "3714", "filetype": "JAVASCRIPT", "folder": "10", "hideinbundle": "F", "id": "730", "iscompanywidereadaccess": "F", "isinactive": "F", "islink": "F", "isonline": "F", "lastmodifieddate": "6\/17\/2020", "name": "chk-so-buttons.client-script.js" }, { "links": [], "addtimestamptourl": "F", "bundleable": "F", "createddate": "6\/7\/2020", "filesize": "2333", "filetype": "JAVASCRIPT", "folder": "10", "hideinbundle": "F", "id": "731", "iscompanywidereadaccess": "F", "isinactive": "F", "islink": "F", "isonline": "F", "lastmodifieddate": "6\/27\/2020", "name": "chk-so-buttons.user-event-script.js" }, { "links": [], "addtimestamptourl": "F", "bundleable": "F", "createddate": "6\/30\/2020", "filesize": "3518", "filetype": "JAVASCRIPT", "folder": "10", "hideinbundle": "F", "id": "735", "iscompanywidereadaccess": "F", "isinactive": "F", "islink": "F", "isonline": "F", "lastmodifieddate": "6\/30\/2020", "name": "journalentry-api.restlet.js" } ], "offset": 0, "totalResults": 6 }
As you can see, there are 6 files in that subfolder. There are a number of interesting columns returned, including the name, file size, creation and last modification dates, and more.
The query that I used specified a folder, but you can also query for files directly. For example, suppose you wanted to find all files whose name includes "restlet." Here's the query.
SELECT File.Name, File.CreatedDate, File.LastModifiedDate, File.FileType, File.FileSize, File.URL, MediaItemFolder.AppFolder FROM File INNER JOIN MediaItemFolder ON (MediaItemFolder.id = File.Folder) WHERE ( File.Name LIKE '%restlet%' )
In that example, I specified the columns that I wanted, and also joined to the MediaItemFolder table so that I can get the names of the folders that the files are in.
In this post I've shown how you can use SuiteQL to easily get information about the files and folders in an instance's File Cabinet. In a future blog post I'll show how you can use SuiteScript to get to a files contents.
If you have any questions, please feel free to contact me.
Hello, I'm Tim Dietrich. I develop custom software for businesses that are running on NetSuite, including mobile apps, Web portals, Web APIs, and more.
I'm the developer of several popular NetSuite open source solutions, including the SuiteQL Query Tool, SuiteAPI, and more.
I founded SuiteStep, a NetSuite development studio, to provide custom software and AI solutions - and continue pushing the boundaries of what's possible on the NetSuite platform.
Copyright © 2025 Tim Dietrich.