RESTlets are one of the most powerful extension points in NetSuite. They let you expose custom HTTP endpoints that can be consumed from any external system — or from inside NetSuite itself.
What is a RESTlet?
A RESTlet is a SuiteScript script exposed as an HTTP endpoint. Unlike Suitelets (which generate UI), RESTlets return data — JSON, XML, plain text.
/**
* @NApiVersion 2.1
* @NScriptType Restlet
*/
define(['N/record', 'N/log', 'N/error'], (record, log, error) => {
const get = (params) => {
const { id } = params;
if (!id) {
throw error.create({
name: 'MISSING_PARAM',
message: 'The id parameter is required',
notifyOff: true,
});
}
const customer = record.load({
type: record.Type.CUSTOMER,
id: Number(id),
});
return {
id: customer.id,
name: customer.getValue('companyname'),
email: customer.getValue('email'),
};
};
const post = (body) => {
const customerId = record.create({
type: record.Type.CUSTOMER,
});
// ...
return { success: true, id: customerId };
};
return { get, post };
});
Authentication
RESTlets support two authentication methods:
1. Token-Based Authentication (TBA)
The recommended method. You use a Consumer Key/Secret + Token Key/Secret pair to generate an OAuth 1.0a header.
Authorization: OAuth realm="...",
oauth_consumer_key="...",
oauth_token="...",
oauth_signature_method="HMAC-SHA256",
oauth_timestamp="...",
oauth_nonce="...",
oauth_version="1.0",
oauth_signature="..."
2. User Credentials
Only recommended for development. Never in production.
Error handling
The pattern I use in production:
const handleError = (e) => {
log.error({ title: 'RESTlet Error', details: e });
if (e.name) {
return JSON.stringify({
error: e.name,
message: e.message,
});
}
return JSON.stringify({
error: 'UNEXPECTED_ERROR',
message: 'An unexpected error occurred',
});
};
Governance limits
Watch out for governance unit limits:
| Operation | Cost |
|---|---|
record.load | 10 units |
record.save | 20 units |
search.run | 10 units |
A RESTlet has a maximum of 5,000 governance units per execution.
Conclusion
RESTlets are the foundation of any serious NetSuite integration. With TBA, solid error handling, and attention to governance, you can build robust, maintainable APIs.
In the next post I’ll cover how to structure larger integration projects with multiple RESTlets and shared logic.