NetSuite SuiteScript 2.1 RESTlet Skeleton Generator
A RESTlet is the quickest way to give an external system a custom endpoint into NetSuite. The structure is always the same: an annotated define block, a get and a post entry point, and careful error handling. This generator writes that structure for the record type you choose.
Fill in
RESTlet script file
/**
* @NApiVersion 2.1
* @NScriptType Restlet
* @NModuleScope SameAccount
* @description Work order status lookup
* @author Integration Team
* @since 2026-10-20
*/
define(['N/record', 'N/log', 'N/error'], (record, log, error) => {
const get = (requestParams) => {
try {
if (!requestParams || !requestParams.id) {
throw error.create({ name: 'MISSING_ID', message: 'Query parameter id is required', notifyOff: true });
}
const rec = record.load({ type: record.Type.WORK_ORDER, id: requestParams.id, isDynamic: false });
return {
success: true,
id: requestParams.id,
tranid: rec.getValue({ fieldId: 'tranid' }),
trandate: rec.getValue({ fieldId: 'trandate' })
};
} catch (e) {
log.error({ title: 'GET work order failed', details: e });
return { success: false, name: e.name, message: e.message };
}
};
const post = (requestBody) => {
try {
if (!requestBody || !requestBody.values) {
throw error.create({ name: 'MISSING_BODY', message: 'Body must contain a values object', notifyOff: true });
}
const rec = record.create({ type: record.Type.WORK_ORDER, isDynamic: true });
Object.keys(requestBody.values).forEach((fieldId) => {
rec.setValue({ fieldId: fieldId, value: requestBody.values[fieldId] });
});
const newId = rec.save({ enableSourcing: true, ignoreMandatoryFields: false });
log.audit({ title: 'Created work order', details: newId });
return { success: true, id: newId };
} catch (e) {
log.error({ title: 'POST work order failed', details: e });
return { success: false, name: e.name, message: e.message };
}
};
return { get, post };
});Deployment checklist as comments
// 1. Upload the file to the File Cabinet, for example SuiteScripts/restlets/ // 2. Customization > Scripting > Scripts > New, choose the file, create the script record // 3. Deploy it, set status to Testing, restrict Audience to the integration role // 4. Call the External URL from the deployment record with OAuth 2.0 or token based authentication // 5. Move status to Released only after a sandbox test with the same role
This is a skeleton, not production code. Validate the field ids against your record, add input validation, and check governance usage: a RESTlet gets 5,000 units per call. Many real integrations return a standard HTTP error instead of success false, so adapt the error branch to your client.
Planning a NetSuite integration?
Get a short expert review of your endpoint design, roles and governance exposure.
Optional. The tool and every export work without this. No spam.
How to use the skeleton
Select the record.Type constant, name the two fields you want returned, and copy the script. Save it as a .js file in the File Cabinet, create the script record and deploy it. The generated GET handler loads one record by id. The POST handler creates a record from a values object, which is simple enough to test but not enough for complex transactions with sublists.
- Replace the field ids with fields that exist on your record
- Add sublist handling with selectNewLine and commitLine where needed
- Keep the deployment on Testing until a sandbox call succeeds
- Limit the audience to the integration role, not all roles
Why 2.1 and these modules
SuiteScript 2.1 supports modern JavaScript syntax such as arrow functions, const and let, which is why the skeleton uses them. N/record handles loading and saving, N/log writes to the execution log, and N/error creates named errors that are easier to filter. Use N/search or N/query when you need to read many records instead of loading each one, because record.load consumes far more governance than a search result.
Authentication and permissions
A RESTlet runs with the permissions of the role attached to the calling token or OAuth client. If the role cannot edit a work order, the POST fails regardless of what the script does. Create a dedicated integration role with only the permissions the endpoint needs, and never reuse an administrator token for a script that accepts external input.
Common mistakes
Frequent problems include returning the whole record object, which is not valid JSON, setting values before the form or subsidiary is known so sourcing misfires, and swallowing errors so the caller sees success. Always log the error details and return a message the caller can act on.
- Using dynamic mode when standard mode would do
- Not validating the request body before saving
- Hard coding internal ids that differ between sandbox and production
- Deploying to all roles with an open audience
Frequently Asked Questions
What is the governance limit for a RESTlet?
A RESTlet script gets 5,000 governance units per invocation. A record.load or record.save on a transaction costs a noticeable share, so batch work through searches and keep each request small. The execution log shows remaining units when you query it.
Should I use a RESTlet or the REST record API?
Use the standard REST record API when the default record shape is enough, because there is no code to maintain. Use a RESTlet when you need custom logic, a combined response from several records, or a simpler payload than the standard API provides.
Can I use SuiteScript 2.0 instead?
Yes, 2.0 still runs, but 2.1 is the current version and supports modern syntax. Existing 2.0 scripts do not need to be rewritten, though new scripts are usually written in 2.1 to avoid a later migration.
Is the generated code safe to deploy as is?
No. It is a starting point. Add validation, permission thinking, retries on the caller side and tests in a sandbox. Review field ids and mandatory fields for your own forms and customizations before releasing.
If you are building integrations between NetSuite and shop floor or engineering systems, we can review the design and the governance risks with you before you deploy.
Related Tools
NetSuite SuiteQL Transaction Query Generator
Pick a transaction type, date range and row limit and get ready-to-run SuiteQL for headers, lines and the REST call that executes it.
Developer ToolsNetSuite SuiteScript Governance Units by Script Type
A lookup of governance unit limits for each SuiteScript script type and the design guidance that follows from them.
NetSuiteNetSuite Manufacturing and Item Record Types Reference
Find the record id for assembly items, BOMs, revisions, routings and the manufacturing transactions, with a note on what each is for.
NetSuiteNetSuite Transaction Type Codes Reference
Look up the short type code stored in transaction.type for common NetSuite transactions, with the matching record id.
More Developer Tools tools
See all- NetSuite API Retry Backoff Wait Time Calculator
- NetSuite OAuth 2.0 Access Token Refresh Calculator
- NetSuite REST Web Services Headers and Query Parameters Reference
- SuiteScript 1.0 to 2.1 API Mapping Reference for NetSuite
- NetSuite REST API SuiteQL Request Generator
- NetSuite REST API Sales Order and Journal Entry Request Generator
- NetSuite Token-Based Auth OAuth 1.0 Signature Code Generator
- NetSuite OAuth 2.0 Client Credentials (M2M) JWT Code Generator
- SuiteScript 2.1 Scheduled Script Generator for NetSuite
New to NetSuite? Start with the NetSuite guide and toolkit, or plan with NetSuite Cost Calculator, Training Path Builder, ERP Certification Study Planner.
Keep exploring
Free tools
- SuiteScript 2.1 RESTlet Skeleton GeneratorFill in a few fields and get a SuiteScript 2.1 RESTlet starter with all four handlers, logging and structured error responses.
- SuiteScript 2.1 User Event Script SkeletonA copy-ready SuiteScript 2.1 user event script with the JSDoc annotations, entry points, context checks and error logging you need to start.
- NetSuite Workflow Action Script Generator (SuiteScript 2.1)Generate a working workflow action script that reads a threshold parameter, looks up an approver and returns a value your workflow can store in a field.
ERP fixes and how-tos
- N/query versus N/search: choosing the right SuiteScript data access moduleCompare NetSuite's N/query (SuiteQL) and N/search modules for performance, governance cost and capability, and decide which to use for joins, aggregation, sublist reads and large exports in SuiteScript 2.1.
- Fix NetSuite SSS_MISSING_REQD_ARGUMENT ErrorSSS_MISSING_REQD_ARGUMENT means a NetSuite API call is missing a required parameter like type or id. Learn the common causes and how to fix it fast.
Integrations
- How to add WhatsApp to Oracle NetSuiteHow to connect WhatsApp Business to Oracle NetSuite: SuiteScript triggers, RESTlets, template messages, opt-in rules and two-way replies that post back to records.
- How to add AI agents to Oracle NetSuiteHow to add AI agents to Oracle NetSuite: SuiteQL and REST tool layer, RESTlet writes, role-scoped tokens, human approval, and where a private model fits.