Netsuite Technical Interview Notes – SuiteScript 2.0 Tutorial for Netsuite

SuiteScript 2.0 Notes

  • It uses the entry point function to identify the script type
  • It is built on modular architecture
  • We can also create our own custom modules
  • First you need to enable client suitescript feature

When you include an entry point in your script, you tell the system that it should do something when that entry point is invoked. Specifically, you tell the system that it should execute a function defined within the script. This function is called an entry point function.

Every entry point script must use Define Function

You must add JSDoc tags

/** *@NApiVersion 2.0 *

@NScriptType ClientScript */

These tags reflect the following:
The version of SuiteScript you are using.
The script type you are using.

You must use the runtime.getCurrentScript() function in the runtime module to reference script

parameters. For example, use the following code to obtain the value of a script parameter named


define([‘N/runtime’], function(runtime) {

function pageInit(context) {

var strField = runtime.getCurrentScript().getParameter(‘SCRIPT’, ‘custscript_case_field



Bundle Installation Script

Before Install, After Install, Before Update, After Update, Before Uninstall

Standard mode vs dynamic mode

Sourcing occurs after data is submitted to the database, Sourcing occurs in real time

To get current record use context.currentRecord

sublistName = context.sublistId

sublistFieldName = context.fieldId

You use the currentRecord module to access the record that is active in the current client-side context

An entry point client script does not have to explicitly load the currentRecord

module Like the N/record Module, the currentRecord module provides access to body and sublist fields


module does not permit the editing of subrecords, although subrecords can be retrieved in view mode

Because clientDemo.js is a custom module script, it must manually load the currentRecord module by

naming it in the define statement. Additionally, it must actively retrieve a CurrentRecord object. It does

so by using the currentRecord.get() method.

use lookup field by loading n/search module and use search.lookupFields


var salesRepEmail = search.lookupFields({

type: ’employee’,

id: salesRep,

columns: [’email’]


Client Script Types


pageInit – Executed when the page completes loading or when the form is reset.
fieldChanged – Executed when a field is changed by a user or client side call.
validateField – Executes when a field is about to be changed by a user or client side call.
postSourcing – Executed on transaction forms when a field that sources information from another field is modified.
saveRecord – Executed after the submit button is pressed but before the form is submitted.


lineInit – Executed when an existing line is selected.
sublistChanged – Executed after a sublist has been inserted, removed, or edited.
validateDelete – Executed when removing an existing line from an edit sublist
validateInsert – Executed when you insert a line into an edit sublist.
validateLine – Executed before a line is added to an inline editor sublist or editor sublist.

Use the pageInit function to handle URLs that may contain updated field values

The scriptContext parameter is a JavaScript object. It is automatically passed to the script entry point by NetSuite.

Map Reduce Script

The stages are processed in the following order. Note that each stage must complete before the next stage begins.

Get Input Data – Acquires a collection of data. This stage is always processed first and is required. The input stage runs sequentially.

Map – Parses each row of data into a key/value pair. One pair (key/value) is passed per function invocation. If this stage is skipped, the reduce stage is required. Data is processed in parallel in this stage.

Shuffle – Groups values based on keys. This is an automatic process that always follows completion of the map stage. There is no direct access to this stage as it is handled by the map/reduce script framework. Data is processed sequentially in this stage.

Reduce – Evaluates the data in each group. One group (key/values) is passed per function invocation. If this stage is skipped, the map stage is required. Data is processed in parallel in this stage.

Summarize – Summarizes the output of the previous stages. Developers can use this stage to summarize the data from the entire map/reduce process and write it to a file or send an email. This stage is optional and is not technically a part of the map/reduce process. The summarize stage runs sequentially.

How does it works ?

Suppose we have to invoice all pending billing sales order.
In get input data we will create a search for finding all sales order having status pending billing or partially fulfilled. Then we will return the search.

In map Stage – map(context)
Search object from get input data is automatically passed to map stage as a key / value pair for each row of the search
We can see the data in map stage using
log.debug(‘context’, context.value);

To get each row of key value pair use the following

var rowJson = JSON.parse(context.value);

This is how you can get internal Id


You can use either of map or reduce functions, using both is not necessary
Summarize stage is optional and it can be used for sending emails or writing data to the file.

function summarize(summary)
log.debug(‘Summary Time’,’Total Seconds: ‘+summary.seconds);
log.debug(‘Summary Usage’, ‘Total Usage: ‘+summary.usage);
log.debug(‘Summary Yields’, ‘Total Yields: ‘+summary.yields);
log.debug(‘Input Summary: ‘, JSON.stringify(summary.inputSummary));
log.debug(‘Map Summary: ‘, JSON.stringify(summary.mapSummary));
log.debug(‘Reduce Summary: ‘, JSON.stringify(summary.reduceSummary));
//Grab Map errors
summary.mapSummary.errors.iterator().each(function(key, value) {

log.error(key, ‘ERROR String: ‘+value);
return true;

Can also be used for error handling or logging the result and usage
Note that you can create multiple deployments for one script record. This strategy is useful if you want to submit the same script for processing multiple times simultaneously, or within a short time
the times you set on the Schedule subtab are not necessarily the times the script will execute
In the server-side script where you want to submit the map/reduce script, call

var scriptTask = task.create({taskType: task.TaskType.MAP_REDUCE});
scriptTask.scriptId = ‘customscript1’;
scriptTask.deploymentId = ‘customdeploy1’;

If you need to submit multiple instances of a single map/reduce script for processing at the same time, or within a very short time frame, the correct approach is to create multiple deployments of the script and submit each deployment as needed. There are multiple advantages to this technique. For example, if you have a SuiteCloud Plus license, this approach lets you process two or more instances of the script in parallel.
Certain limits, if violated, cause an interruption to the current function invocation. These limits are known as hard limits.
Other limits are managed automatically by the system. These limits never interrupt a function invocation. Rather, after the completion of a function invocation, these limits can cause a job to yield and its work to be rescheduled for later. These limits are known as soft limits.

Hard Limits on Total Persisted Data

The total persisted data used by a map/reduce script cannot exceed 50MB at any one time.

If your script exceeds this limit at any point during its processing, the system throws a

STORAGE_SIZE_EXCEEDED error. Additionally, the script ends its current function invocation, exits the current stage, and goes immediately to the summarize stage.

Get Input Data – 10,000 units
Map – 1,000 units
Reduce – 5,000 units
Summarize – 10,000 units

You cannot use the SuiteScript Debugger for server-side script debugging of a Map/ Reduce script.
When you set the buffer size, you need to strike a balance between performance and the risk of data loss. The higher you set the buffer size, the lower the overhead, but the greater the risk of data loss. Higher buffer values are recommended for fast, algorithmic operations. Higher buffer values are not recommended for record handling operations. In case of application server crash, functions without output data stored have to be repeated, and the repeat of record handling operations may result in duplicate data being saved. To avoid this situation, make sure to use a lower buffer value for record handling operations. You can detect a restart that impacted a script using the isRestarted property for entry point functions.

To create a robust script use flags and check flags for already processed records use isrestared to check if system was restarted.

Mass Update Script Type

Mass update scripts allow you to programmatically perform custom updates to fields that are not available through general mass updates. Mass update scripts can run complex calculations, as defined in your script, across records.

The following code updates the probability field of all existing records to 61%.


*@NApiVersion 2.0

*@NScriptType MassUpdateScript



function(record) {

function each(params) {

// Set the probability to 61%

var recOpportunity = record.load({

type: params.type,



recOpportunity.setValue(‘probability’, 61);;


return {

each: each



Entry Point

each : Iterates through all applicable records so that you can apply logic to each record

The params parameter is a JavaScript object. It is automatically passed to the script entry point by NetSuite.

Portlet Script Type

The following portlet script types are supported:

FORM — A data entry form with up to one submit button embedded into a portlet. This type supports the Portlet module that can refresh and resize the portlet, as well as the use of recordlevel client-side script to implement validation. See N/portlet Module.

HTML — An HTML-based portlet that is used to display free-form HTML. (images, Flash, custom HTML)

LINKS — A portlet that consists of rows of formatted content.

LIST — A standard list of user-defined column headers and rows. The following image shows a form portlet and a links portlet displayed on the NetSuite dashboard.

Portlet objects are used to encapsulate scriptable dashboard portlets. They are automatically passed to the render(params) entry point by NetSuite

RESTlet Script Type

GET – Requests data from a specified resource

POST – Submits data to be processed to a specified resource

PUT – is preferred for updating an existing entity

DELETE – Deletes the specified resource

PUT and DELETE operations are idempotent means their result will always same no matter how many times these operations are invoked. Post is not idempotent

delete, get – Arguments must be embedded in the URL used to make the call.
post, put – Arguments must be included in a request body written in JSON (JavaScript Object Notation) or plain text.

RESTlets SuiteScript 2.0 RESTlet Script Type 175 SuiteScript 2.0 API allow 5,000 usage units per script

Use Rest role service to find the restlet main url don’t hard code it because data center changes and also the url

Rest role service url

Production and sandbox accounts hosted on the NetSuite domain, and Release Preview accounts – and similar variants

Sandbox accounts hosted on the sandbox domain

Authentication header for restrole service

NLAuth, nlauth_signature=Welcome123

Suitelet that Calls a RESTlet


* @NApiVersion 2.x

* @NScriptType Suitelet


define([‘N/https’, ‘N/url’], function(https, urlMod) {

return {

onRequest : function(options) {

var url = urlMod.resolveScript({

scriptId: ‘customscript196’,

deploymentId: ‘customdeploy1’,

returnExternalUrl: true,

params: {parametername: ‘value’}


var headers = {‘Authorization’: ‘NLAuth nlauth_account=12345, nlauth_email=john@s, nlauth_signature=Welcome123, nlauth_role=3′};

var response = https.get({url: url, headers: headers});





Scheduled Script Type

Scheduled scripts are server-side scripts that are executed (processed) with SuiteCloud Processors. You can deploy scheduled scripts so they are submitted for processing at a future time, or at future times on a recurring basis. You can also submit scheduled scripts on demand from the deployment record or from another script with the task.ScheduledScriptTask API.

Each scheduled script instance can use a maximum of 10,000 usage units

Scheduled Script Entry Points

Execute – Definition of the scheduled script trigger point

Runtime Status

Pending – The script is in the queue and ready to be processed
Deferred – The script is eligible for processing but has not been processed due to constraints. For example, deferred status will occur when one task must wait for another to finish.
Processing – The script is running
Complete – The script completed normally.
Cancelled – Due to a NetSuite server error, the script was cancelled during or before script execution.

Failed – The script began processing but failed to complete normally. Examine your script for possible errors.


SCHEDULED The normal execution according to the deployment options specified in the UI.
ON_DEMAND The script is executed via a call from a script

USER_INTERFACE The script is executed via the UI (the Save & Execute button has been clicked).
ABORTED The script re-executed automatically following an aborted execution (system went down during execution).
SKIPPED The script is executed automatically following downtime during which the script should have been executed.

Suitelet Script Type

Suitelets are extensions of the SuiteScript API that allow you to build custom NetSuite pages and backend logic. Suitelets are server-side scripts that operate in a request-response model, and are invoked by HTTP GET or POST requests to system generated URLs.

There are two types of Suitelets:
1. Suitelets use UI objects to create custom pages that look like NetSuite pages. SuiteScript UI objects encapsulate the elements for building NetSuite-looking portlets, forms, fields, sublists, tabs, lists, and columns.

2. Backend Suitelets do not use any UI objects and execute backend logic, which can then be parsed by other parts of a custom application. Backend Suitelets are best used for the following purposes:

Providing a service for backend logic to other SuiteScripts, or to other external hosts outside of NetSuite.

Offloading server logic from client scripts to a backend Suitelet shipped without source code to protect sensitive intellectual property.

If any of your parameters are named after any of the reserved parameter names, your Suitelet may throw an error saying, “There are no records of this type.

Reserved Suitelet URL Parameter Names
e id cp l popup s d _nodrop sc sticky print email q si st r displayonly nodisplay deploy script

User Event Script Type

User event scripts are executed on the NetSuite server. They are executed when users perform certain actions on records, such as create, load, update, copy, delete, or submit. Most standard NetSuite records and custom record types support user event scripts.

User event scripts cannot be executed by other user event scripts or by workflows with a Context of User Event Script. In other words, you cannot chain user event scripts. You can, however, execute a user event script from a call within a scheduled script, a portlet script, or a Suitelet.

Be careful when updating transaction line items in a beforeSubmit script because you have to ensure that the line item totals net taxes and discounts are equal to the summarytotal, discounttotal, shippingtotal, and taxtotal amounts

To set a field on a record or make any changes to a record being submitted, use the beforeSubmit event rather than the afterSubmit event. Changes made during an afterSubmit event duplicates the record.

Script Entry Point

afterSubmit(scriptContext) – Executed immediately after a write operation on a record
beforeLoad(scriptContext) – Executed whenever a read operation occurs on a record, and prior to returning the record or page.
beforeSubmit(scriptContext) – Executed prior to any write operation on the record.

context.UserEventType – Holds the string values for user event execution contexts.


beforeLoad user events cannot be triggered when you load/access an online form.
Data cannot be manipulated for records that are loaded in beforeLoad scripts. If you attempt to update a record loaded in beforeLoad, the logic is ignored.
Data can be manipulated for records created in beforeLoad user events.

Workflow Action Script Type

Workflow action scripts allow you to create custom Workflow Actions that are defined on a record in a workflow. Workflow action scripts are useful for performing actions on sublists because sublist fields are not currently available through the Workflow Manager. Workflow action scripts are also useful when you need to create custom actions that execute complex computational logic that is beyond what can be implemented with the built-in actions.
Workflow Action Script Sample This sample shows how to store a return value from a custom action script into a workflow field. This example can be useful to satisfy the following use cases:

You want to get a value from the Item sublist and use this value as a condition in the workflow. You use obj.getFieldValue in the script and return this in the workflow.
You want to check if a certain item is existing in the Item sublist. The script returns “0” if item is not existing and “1” if it does.

You want to make sure that all items in the Item sublist have a quantity equal to or greater than 1 (similar case as #2). This script sample assumes the following set-up in the NetSuite account:

Make sure that the script returns a value. You can specify this on the Parameters tab of the Script record page.
In SuiteFlow, create a workflow field. The field should be the of the same type as the return parameter of the Workflow Action script.
Within a state, add the custom action (this is the Workflow Action script).
Add the return value from the Workflow Action script to the Store Result In field.
Entry Points


Global Objects and Methods

Absolute Paths – Specifies the path from the root folder in the file cabinet. Absolute paths start with a forward slash (/). For example, “/SuiteScripts/MyApp/ Util”.

Relative Paths – Specifies the path relative to the dependent module’s location in the file cabinet. This provides greater flexibility when moving nested folders containing modules in the file cabinet. Relative Paths start with a period (.). For example, assume that the dependent module is located in the following folder: ”/SuiteScripts/MyApp”. The relative path for a sibling file under “SuiteScripts/ MyApp” could be “./Util”. The equivalent absolute path in this case would be ”/ SuiteScripts/MyApp/Util”.

If you need to debug your code on demand in the NetSuite Debugger, you must use a require() Function. The NetSuite Debugger cannot step though a define() Function.

When you use the require() Function, dependencies are not loaded until they are needed. This can help increase script performance.

log Object

The log Object is loaded by default by NetSuite for all script types. You do not need to load it manually. However, you can choose to load it via N/log Module, such as for testing purposes.

util Object The util Object is loaded by default by NetSuite for all script types. You do not need to load it manually. However, you can choose to load it via N/util Module, such as for testing purposes.
util Object

The util Object is loaded by default by NetSuite for all script types. You do not need to load it manually. However, you can choose to load it via N/util Module, such as for testing purposes.

util.isString(obj) The util object also includes the following utility methods:
util.each(iterable, callback)
util.extend(receiver, contributor)

toString() – Method used to determine an object’s type. This is a global method that is loaded by default for all native SuiteScript 2.0 API objects.

var type = mapContext.toString(); // When called on mapReduce.MapContext, toString returns “mapReduce.MapContext”

JSON object

JSON.parse(text) – Parse a string as a JSON object and returns the object. The text parameter must conform to the JSON standard.

var text = ‘{ “employees” : [‘ + ‘{ “firstName”:”John” , “lastName”:”Doe” },’ + ‘{ “firstName”:”Anna” , “lastName”:”Smith” },’ + ‘{ “firstName”:”Peter” , “lastName”:”Jones” } ]}’; var obj = JSON.parse(text);


Converts a JavaScript object value to a key-value pair string in the JSON format.

var contact = { firstName: ‘John’, lastName : ‘Doe’, jobTitle : ‘CEO’ };
var jsonString = JSON.stringify(contact);

This method converts the contact object to the following string: {“firstName”:”John”,”lastName”:”Doe”,”jobTitle”:”CEO”}

Promise object

In SuiteScript 2.0, all client scripts support the use of Promises. With Promises, developers can write asynchronous code that is intuitive and efficient. SuiteScript 2.0 provides promise APIs for selected modules (see SuiteScript 2.0 Promise APIs). In addition, you can create custom Promises in all client scripts (see Custom Promises).

SuiteScript 2.0 Modules

N/auth Module – Load the auth module when you want to change your NetSuite login credentials.
N/cache Module – Load the cache module to enable the caching of needed data and improve performance.
N/config Module – Load the config module when you want to access NetSuite configuration settings. See config.Type for a list of supported configuration pages.
N/crypto Module – Load the crypto module to work with hashing, hash-based message authentication (hmac), and symmetrical encryption. You can access a set of wrappers for OpenSSL’s hash, hmac, cipher, and decipher methods.
N/currency Module – Load the currency module to work with exchange rates within your NetSuite account. You can use the currency module to find the exchange rate between two currencies based on a certain date.
N/currentRecord Module – Load the currentRecord module to access the record instance that you are currently working on. You can then use the record instance in a clientside context.
N/email Module – Load the email module when you want to send email messages from within NetSuite. You can use the email module to send regular, bulk, and campaign email.
N/encode Module – Load the encode module when you want to convert a string to another type of encoding. See encode.Encoding for a list of supported character set encoding.
N/error Module – Load the error module when you want to create your own custom SuiteScript errors. Use these custom errors in try-catch statements to abort script execution.
N/file Module – Load the file module to work with files in NetSuite.
N/format Module – Load the format module to convert strings into a specified format and to parse formatted data into strings.
N/http Module – Load the http module to make http calls. All HTTP content types are supported.
N/https Module – Load the https module to make https calls. You can also use this module to encode binary content or securely access a handle to the value in a NetSuite credential field.
N/log Module – Use the log module to access methods for logging script execution details
N/plugin – Load the N/plugin module to load custom plug-in implementations.
N/portlet – Load the portlet module to resize or refresh a form portlet
N/record – Load the record module to work with NetSuite records. For example, to create, delete, copy, or load a record. You can also use this module to access body or sublist field properties on a record
N/render – The render module encapsulates functionality for printing, PDF creation, form creation from templates, and email creation from templates.
N/redirect – Use the redirect module to customize navigation within NetSuite by setting up a redirect URL that resolves to a NetSuite resource or external URL. You can redirect users to one of the following:

Task link
Saved search
Unsaved search

N/runtime Module – Load the runtime module when you want to access the current runtime settings for the script and script deployment, the user currently executing the script, and user-defined sessions.

runtime.User, runtime.getCurrentScrip t() , runtime.getCurrentUser() , runtime.accountId

N/search Module – Load the search module to create and run ad-hoc or saved searches and analyze and iterate through the search results. You can search for a single record by keywords, create saved searches, search for duplicate records, or return a set of records that match filters you define.

search.Search , search.Result, search.Column , search.Filter , search.ResultSet, search.Page , search.PagedData, search.PageRange

N/sftp Module – The sftp module provides a way to upload and download files from external SFTP servers. SFTP servers can be hosted by your organization or by a third party. NetSuite does not provide SFTP server functionality. All SFTP tranfers to or from NetSuite must originate from SuiteScript. It is not possible for external clients to initiate file transfers using SFTP.
sftp.Connection, sftp.createConnection( options)

N/sso Module – Use the sso module to generate outbound single sign-on (SuiteSignOn) tokens. For example, to create a reference to a SuiteSignOn record, or to integrate with an external application.

N/task Module – Load the task module to create tasks and place them in the internal NetSuite scheduling or task queue. Use the task module to schedule scripts, run Map/Reduce scripts, import CSV files, merge duplicate records, and execute asynchronous workflows. Each task type has its own corresponding object types. Use the methods available to each object type to configure, submit, and monitor the tasks.

N/transaction Module – Load the transaction module to void transactions. When you void a transaction, the total and all the line items for the transaction are set to zero. The transaction is not removed from the system. NetSuite supports two types of voids: direct voids and voids by reversing journal. For additional information, see the help topic Voiding, Deleting, or Closing Transactions.

The type of void performed with your script depends on the targeted account’s preference settings:

#If the Using Reversing Journals preference is disabled, a direct void is performed.

#If the Using Reversing Journals preference is enabled, a void by reversing journal is performed.

N/ui/dialog Module – Load the dialog module to create a modal dialog that persists until a button on the dialog is pressed

N/ui/message module – Load the message module to display a message at the top of the screen under the menu bar.

N/ui/serverWidget Module – Load the serverWidget module when you want to work with the user interface within NetSuite. You can use Suitelets to build custom pages and wizards that have a NetSuite look-and-feel. You can also create various components of the NetSuite UI (for example, forms, fields, sublists, tabs).

N/url Module – Use the url module to determine URL navigation paths within NetSuite and format URL strings.
url.resolveRecord(options) – Returns an internal URL string to a NetSuite record.

N/util Module- This module exposes the util Object and its members, made up primarily of methods that verify type on objects and primitives in a SuiteScript 2.0 script. Each type verification method (for example, util.isArray(obj)) returns a boolean value, based on evaluation of the obj parameter. If you need to identify a type specific to SuiteScript 2.0, use the toString() global method.

util.isArray(obj) – Returns true if the obj parameter is a JavaScript and false otherwise.
util.isBoolean(obj) – Returns true if the obj parameter is a Boolean and false otherwise.
util.isDate(obj) – Returns true if the obj parameter is a JavaScript Date object and false otherwise.
util.each(iterable, callback) – Iterates over each member in an Object or Array.

N/workflow Module – This module loads the workflow module to initiate new workflow instances or trigger existing workflow instances.

N/xml Module – Load the xml module to validate, parse, read, and modify XML documents.

Custom Modules

With SuiteScript 2.0, you have the ability to create custom modules (including third-party, AMD, and non-AMD modules). This supports modular and well-structured organization of code that is easier to read and modify. It also lets you build and access additional, customized API functionality. Build a custom module to help you do the following:

Group reusable functions into a common library file. Supporting code (such as helper functions and custom APIs) can be organized into reusable sections. These custom modules are loaded within your entry point script.
Add custom modules to SuiteApps and expose those modules to third parties.

Import a third-party API.
Organize and separate utilities from business logic.

Import a third-party library Some third-party libraries register as AMD compatible. In that case, you can specify a require configuration that sets up the path where the module is found.


* @NApiVersion 2.x

* @NScriptType usereventscript



paths: {

“coolthing”: “/SuiteScripts/myFavoriteJsLibrary”




function (coolthing)


return {

beforeLoad: function beforeLoad(ctx)


coolthing.times(2, function () {

log.debug(‘log’, ‘log’);






paths: {

‘jquery’: ‘<jquery file path>’



define([‘jquery’], function(jquery) {


Record-Level and Form-Level Scripts

A client script can be deployed in one of two ways: at the record level, or at the form level. When you deploy a client script at the record level, you deploy it globally on one or more record types. The script runs on all forms associated with the record type. By contrast, with a form-level deployment, you attach the script to a custom form associated with a record type, and the script runs only when that form is used.

Entry Point Script Validation

Callout Description

1 JSDoc tags

2 JSDoc tag values

3 entry point function definitions

4 interface (sometimes called script type interface)

5 entry points

6 entry point functions (sometimes called script type functions)

Correct Structure for Entry Point Scripts

An entry point script cannot be associated with a script record or custom form unless the script meets

certain criteria. That is, all of the following must be true:

1. The script must include one and only one properly structured define statement. The script cannot

include multiple define statements.

2. The define statement cannot include direct references to SuiteScript 2.0 API, objects or enums. All

such references must be wrapped in a function.

3. The script’s return statement must include an interface whose entry points are associated with one

and only one script type. Put another way, the return statement must include only one script type


4. The interface must include at least one entry point.

5. Each entry point must correspond with an entry point function. All entry point functions must be

defined in the same file.

6. The script type interface implemented must match the @NScriptType value.

7. JavaScript syntax errors are not permitted.

Possible Value – 2.0 2.x 2.X
@NScriptType – BundleInstallationscript, ClientScript, MapReduceScript, MassUpdateScript ,Portlet, Restlet, ScheduledScript, Suitelet, UserEventScript, WorkflowActionScript

Standard and Dynamic Modes

Standard mode:

When a SuiteScript 2.0 script creates, copies, loads, or transforms a record in standard mode, the record’s body fields and sublist line items are not sourced, calculated, and validated until the record is saved (submitted) with Standard mode is also called deferred dynamic mode and you see both terms in the SuiteScript help.

Dynamic mode:
When you work with a record in standard mode, in most cases, you don’t need to set values in any particular order. After a record is submitted, NetSuite processes the record’s body fields and sublist line items in the correct order, regardless of the organization of your script. See Getting and Setting in SuiteScript 2.0 Script Modes. When a SuiteScript 2.0 script creates, copies, loads, or transforms a record in dynamic mode, the record’s body fields and sublist line items are sourced, calculated, and validated in real-time. A record in dynamic mode emulates the behavior of a record in the UI.

SuiteScript 1.0 API

Notice the APIs marked with an asterisk consume a different number of units based on the type of record they are running on. This kind of governance model takes into account the NetSuite processing requirements for three categories of records: custom records, standard transaction records, and standard non-transaction records.

Custom records, for example, require less processing than standard records. Therefore, the unit cost for custom records is lower to be commensurate with the processing required for standard records. Similarly, standard non-transaction records require less processing than standard transaction records. Therefore, the unit cost for standard non-transaction records is lower to be commensurate with the processing required for standard transaction records.


Unit Usage per API









A user event script on a standard transaction record type (such as Invoice) that includes one call to nlapiDeleteRecord and one call to nlapiSubmitRecord – – consumes 40 units (assuming no other nlapi calls were made).

In this case, the user event script consumes 40 units out of a possible 1,000 units available to user event scripts. (See Script Usage Unit Limits for the total units allowed for a user event script.)



When used on standard transactions: 20

When used on standard non-transactions: 10

When used on custom records: 4


















A scheduled script on a standard non-transaction record type (such as Customer) that includes one call to nlapiLoadRecord, one call to nlapiTransformRecord, one call to nlapiMergeRecord, and one call to nlapiSendEmail consumes 30 units.

In this case, the scheduled script consumes 30 units out of a possible 10,000 units available to scheduled scripts. (See Script Usage Unit Limits for the total units allowed for a scheduled script.)

When used on standard transactions: 10
When used on standard non-transactions: 5
When used on custom records: 2

To conserve units, only use nlapiSubmitField on fields that are available through inline edit. For more information, seeUpdating a field that is available through inline edit and Updating a field that is not available through inline edit.






Within a 60 minute time period, a company is allowed to make up to 100,000 calls to nlapiLogExecution() across all of their scripts.





All other SuiteScript APIs


System errors older than 60 days and user-generated logs older than 30 days are purged.

SuiteScript API

nlapiResolveURL(type, identifier, id, displayMode)

Creates a URL on-the-fly by passing URL parameters from within your SuiteScript. For example, when creating a SuiteScript Portlet script, you may want to create and display the record URLs for each record returned in a search. When creating the URL, you can use either the RECORD reference as retrieved in a search result or a known TASKLINK. Each page in NetSuite has a unique Tasklink Id associated with it for a record type. Refer to the SuiteScript Reference Guide for a list of available NetSuite tasklinks. This API is supported in client, user event, scheduled, portlet, Suitelet, and RESTlet scripts.

nlapiSetRedirectURL(type, identifier, id, editmode, parameters)

Sets the redirect URL by resolving to a NetSuite resource. Note that all parameters must be prefixed with custparam otherwise an SSS_INVALID_ARG error will be thrown. This API is supported in beforeLoad and synchronous afterSubmit user events; it is also supported in Suitelet scripts. Note that nlapiSetRedirectURL is ignored in beforeSubmit and asynchronous

afterSubmit user events.

Generally, client scripts are used to validate user-entered data and to auto-populate fields or sublists at various form events. Such events can include loading or initializing a form, changing a field, or saving a record. Another use case for client scripts is to source data from an external data source to a field. This is accomplished using the API nlapiRequestURL(url, postdata, headers, callback, httpMethod).

nlapiSearchRecord(type, id, filters, columns) –

Performs a search using a set of criteria (your search filters) and columns (the results). Alternatively, you can use this API to execute an existing saved search. Results are limited to 1000 rows.

Usage metering allowed for nlapiSearchRecord is 10 units


Creates a recovery point and, when executed, continues from the recovery point. The newly resubmitted script has its governance units reset.

Calling this function consumes no governance units. Note also, calling this API resets the unit counter for the currently executing script. Be aware, however, all scheduled scripts have a 50 MB memory limit. Calling this API will not reset the memory size of the script to 0. It only resets the governance units
Script Usage Limit

Client Scripts – 1000 units

RESTlets – 5,000 usage units per script

Suitelets – 1,000 usage units per script

Scheduled scripts- 10,000 units

conte xt.getRemainingUsage()
Get parameter value nlapiGetContext().getSetting(‘SCRIPT’, ‘field_id’)

How Many User Events Can I Have on One Record?

There is no limit to the number of user event scripts you can execute on a particular record type. For example, you could have 10 beforeLoad, 9 beforeSubmit, and 15 afterSubmit executing functions on a Customer record. However, assigning this many executable functions to one record type is highly User Event Scripts 28 SuiteScript 1.0 Developer & Reference Guide discouraged

There is a limit of 10MB per string used as RESTlet input or output.

WorkFlow Event Sequence

Client Trigger – Before user edit, before field edit, after field edit, after field sourcing

Server Trigger – Before record load, Before Record submit, After record submit

Before Record Load -> Before user Edit -> Before Field Edit / After Field Edit / After field sourcing -> Before user submit -> Before Record submit -> After Record submit