Building REST Integrations with SuiteScript 2.0

One of the most common tasks in a NetSuite implementation is integrating with external systems. Whether it’s syncing orders to a warehouse, pushing invoices to a third-party accounting tool, or pulling data from a CRM, you’ll eventually need to call an external REST API from SuiteScript.

Here’s a pattern I’ve settled on after doing this repeatedly.

The Basic Shape

SuiteScript 2.0 provides the https module for making outbound HTTP requests. The core call looks like this:

/**
 * @NApiVersion 2.1
 * @NScriptType ScheduledScript
 */
define(['N/https', 'N/log'], function(https, log) {
    function execute(context) {
        var response = https.get({
            url: 'https://api.example.com/v1/orders',
            headers: {
                'Authorization': 'Bearer ' + getToken(),
                'Content-Type': 'application/json'
            }
        });

        if (response.code === 200) {
            var data = JSON.parse(response.body);
            processData(data);
        } else {
            log.error('API Error', response.code + ' - ' + response.body);
        }
    }

    return { execute: execute };
});

Handling Authentication

Most modern APIs use OAuth 2.0 or API keys. For API keys, store them in a Script Parameter (not hardcoded). Go to Customization > Scripting > Scripts > [Your Script] > Parameters and add a string parameter for the key.

Then access it in the script:

define(['N/https', 'N/runtime', 'N/log'], function(https, runtime, log) {
    function execute(context) {
        var script = runtime.getCurrentScript();
        var apiKey = script.getParameter({ name: 'custscript_api_key' });

        // use apiKey in your headers
    }
});

This keeps credentials out of source code and lets you change them without a deployment.

Sending Data (POST)

For sending data outbound:

var payload = JSON.stringify({
    order_id: '12345',
    status: 'shipped',
    tracking: 'JD014600006321'
});

var response = https.post({
    url: 'https://api.example.com/v1/shipments',
    headers: {
        'Authorization': 'Bearer ' + apiKey,
        'Content-Type': 'application/json'
    },
    body: payload
});

Governance Limits

NetSuite caps outbound HTTP calls per script execution. For Scheduled Scripts, you have 5,000 units per execution — each HTTP call costs 10 units. That means you can make at most 500 calls per run.

If you need to process more records, batch them or use Map/Reduce scripts, which reset governance per stage.

Error Handling and Retries

External APIs fail. Network timeouts happen. Build in logging and consider a retry queue (store failed records in a custom record and re-process them in the next scheduled run).

try {
    var response = https.post({ /* ... */ });
    if (response.code >= 400) {
        logFailure(recordId, response.code, response.body);
    }
} catch (e) {
    log.error('Request failed', e.message);
    logFailure(recordId, 'EXCEPTION', e.message);
}

This is just the foundation. OAuth flows, pagination, and webhook receivers each deserve their own post. Those are coming.