NetSuite: Saved Search API

Published on December 7, 2021.

Earlier this week, I released the NetSuite SuiteQL Query API, and the response has been somewhat overwhelming. I want to thank everyone who reached out to me about the RESTlet, and for all of the kind words and feedback.

One question that I've been asked several times isn't so much about the RESTlet itself, but instead, whether or not I have a similar RESTlet that can be used to retrieve the results of saved searches.

I do have a RESTlet for that, and I'm happy to share it. I'm calling it the "Saved Search API." (Clever, eh?) You can find the script at the end of this post.

The Saved Search API

Like the SuiteQL Query API, the Saved Search API is remarkably simple - with regards to the script itself, and in how you use it.

To make a call to the Saved Search API, you send an HTTP POST request to the RESTlet's deployment URL, and the request body is a JSON-encoded payload that includes either NetSuite's internally assigned ID or the script ID of the saved search that you want to run. The response will include the complete set of records that meet the search criteria.

Here's an example of a call to the RESTlet from cURL.

curl -X "POST" "https://tstdrv2355109.restlets.api.netsuite.com/app/site/hosting/restlet.nl?script=899&deploy=1" \
     -H 'Content-Type: application/json' \
     -H 'Authorization: OAuth oauth_consumer_key="7d2c8326a648d4ac7e3013bb492a4a77570677ac2bdba24b30cc24d3dfae722e", oauth_nonce="U8mgCkrNJa5evQdh7ARaoxERtE2beDVr", oauth_signature="Ao4sydHcRTXMPqhzkv8k%2B12NS%2FbzicaqX1js02UlrSM%3D", oauth_signature_method="HMAC-SHA256", oauth_timestamp="1633340518", oauth_token="029e4df8d69a6ad6313e732cd59dccbd430096e4d6c3ed773c24e2ff6321a842", oauth_version="1.0", realm=TSTDRV2355109' \
     -H 'Cookie: NS_ROUTING_VERSION=LAGGING' \
     -d $'{
  "searchID": "customsearch_esc_my_customers_2"
}'

To give you a sense of what the results look like - and how quickly they're returned - here's an animation of a call to the RESTlet. In this example, I'm making the call from Paw, an advanced API tool for macOS. The Saved Search returns a filtered list of inventory items.

Click the image to view a larger version.

If you need help installing the RESTlet, or information on how to setup NetSuite so that you can call it, please refer to my previous post about the SuiteQL Query API. With the exception of the payload contents, nearly everything else is identical.

Roles and Permissions

One important difference between this RESTlet and the other involves Roles and permissions. The SuiteQL Query API needed the "Reports - SuiteAnalytics Workbook" permission, which was required to run SuiteQL queries. Obviously, to use the Saved Search API, the role used for the integration does not need that permission.

The permissions that are needed to use the Saved Search API depend on the type of the data that you're retrieving from the Saved Search. For example, if the Saved Search that you are referring to returns Customers, then the role that you're using for the integration will need "Lists - Customers (View)." Similarly, if the Saved Search returns Items, then the role will need "Lists - Items (View)."

Something that might not be immediately obvious about the Saved Search API is its flexibility. When calling it, you can specify different saved searches without needing to modify the script itself. Again, you just need to make sure that the role that you're using has whatever permissions that are needed.

As always, I hope you find the script to be helpful. If you have any questions about it, please feel free to contact me, and I'll do my best to help.

The RESTlet

The script is shown below, and is also available for download.

/**
* @NApiVersion 2.1
* @NScriptType Restlet
* @NModuleScope Public
*/

/* 

------------------------------------------------------------------------------------------
Script Information
------------------------------------------------------------------------------------------

Name:
Saved Search API

ID:
_saved_search_api

Description
An API that can be used to provide data via saved searches.


------------------------------------------------------------------------------------------
MIT License
------------------------------------------------------------------------------------------

Copyright (c) 2021 Timothy Dietrich.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


------------------------------------------------------------------------------------------
Developer
------------------------------------------------------------------------------------------

Tim Dietrich
* timdietrich@me.com
* https://timdietrich.me


------------------------------------------------------------------------------------------
History
------------------------------------------------------------------------------------------

20211207 - Tim Dietrich
- Initial public release.


*/


var 
     log,
     search,
     response = new Object();     


define( [ 'N/log', 'N/search' ], main );


function main( logModule, searchModule ) {

     log = logModule;
     search = searchModule;

    return { post: postProcess }

}


function postProcess( request ) {     
     
     try {
     
          if ( ( typeof request.searchID == 'undefined' ) || ( request.searchID === null ) || ( request.searchID == '' ) ) {          
               throw { 'type': 'error.SavedSearchAPIError', 'name': 'INVALID_REQUEST', 'message': 'No searchID was specified.' }               
          }     

          var searchObj = search.load( { id: request.searchID } );

          response.results = [];

          var resultSet = searchObj.run();

          var start = 0;

          var results = [];

          do {
     
               results = resultSet.getRange( { start: start, end: start + 1000 } );
          
               start += 1000;
          
               response.results = response.results.concat( results ) ;
          
          } while ( results.length );          
                                             
          return response;
                    
     } catch( e ) {     
          log.debug( { 'title': 'error', 'details': e } );
          return { 'error': { 'type': e.type, 'name': e.name, 'message': e.message } }
     }     
          
}
About 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.