Payroll REST Integration
Check Your License
The RESTful Web Service for Payroll is an additional add-on and must be enabled as part of your license before it can be used. The REST based web service is specifically for payroll activity.
Key Concepts
The following key concepts need to be understood before developing a REST client to consume the Payroll REST Web service. This section is broken down into the following:
- Authentication - using Token Based Authentication
- End Point - the URL address that REST requests should be made to
- Supported HTTP Request Methods - Which methods are supported
- Request Actions - How to specify the operation you wish to request
- Response Model - The Structure or the response to GET and POST requests
Authentication
Token-based Authentication (OAuth)
For details, see Setup NetSuite Token Based (TBA) Authentication.
End Points
Concurrency and Restrictions
The NetSuite 2017.2 release has changed the way concurrency works and concurrency is now limited to 5 connections per account that are shared across REST and SOAP connections. When consuming the end point you must ensure that your system can handle a retry. For more information, see RESTlet Governance and Session Management.
Unlike other REST based web services the end point (URL you are querying or sending information to) will be different for each NetSuite Account depending upon other scripts deployed in the account you are querying. However it will not change after the initial install. The end point will comprise of a domain (which varies based on locale and type of account: production, sandbox, beta), a path and two url parameters (script and deploy).
https://<accountid>.restlets.api.netsuite.com/app/site/hosting/restlet.nl?script=<scriptid>&deploy=<deployid>
To find the exact URL go to Payroll > Setup > View License, if you do not see the REST information box, ensure your license has been updated by clicking Update License. If it is still not visible contact support@infinetcloud.com.
Supported HTTP Request Methods
The Payroll REST web service supports GET, POST and DELETE request methods (PUT is not supported).
GET
The GET method requires only url parameters and returns a JSON response object. The example below shows a query to get a time entry record with NetSuite ID of 42.
https://rest.netsuite.com/app/site/hosting/restlet.nl?script=1&deploy=2&recordtype=timeentry&id=42
POST
The POST method requires a valid JSON Request as the body of the HTTP request, as well as URL parameters to specify the script and deploy ids. The JSON request is processed by the REST Web Service returning a JSON response. The action to perform for a given request is specified with the action parameter.
https://rest.netsuite.com/app/site/hosting/restlet.nl?script=1&deploy=2 { "action" : "get", "recordtype" : "timeentry", "id" : "42" }
Common Mistake
NetSuite requires URL parameters and a http body containing a valid JSON object. Many REST Clients automatically strip the script and deploy parameters resulting in a call to the REST service returning a generic error message.
DELETE
The delete request method is only used for delete actions, deleting one or more records of a given recordtype.
https://rest.netsuite.com/app/site/hosting/restlet.nl?script=1&deploye=2&recordtype=timeentry&id=42
No Response Returned
The NetSuite RESTlet does not return any response from a delete request, if a HTTP STATUS CODE of 200 is returned, it should be assumed the delete has completed successfully. Alternatively a delete action can be sent by GET or POST in which case a response will be returned.
Request Actions
The Web services exposes a range of request actions which specify the action to be invoked by a REST Request. Each action requires a specific set of URL parameters, or parameters to be included in the JSON request. The following table outlines the available actions that can be processed using the Payroll REST interface, and the HTTP Request Method that support it. All actions are supported for the post request method, with a subset available for GET and DELETE.
Action | Description | GET | POST | DELETE | Returns |
---|---|---|---|---|---|
get | get record data for a specified record type and an internalid (or external id) returns a single record object | Data Object representing the record or Error Response | |||
list | used to obtain get all key fields (name, internalid, external id) for all rows of a particular recordtype | Data Array representing the results or Error Response | |||
search | TBD currently only supports searchtype | Array of data objects | |||
add | add one or more record types | Array of response data objects | |||
update | update one or more records | ||||
delete | delete one or more records | no response | |||
function | performs a combined set of actions as defined in the function parameter not necessarily linked to a record | success or failure response |
Functions
The following functions are currently supported
Function | Description |
---|---|
getinfo | Returns deatils about the configuration of the current account. |
syncemployee | Performs a create or update of an employee |
synctimesheet | For a given employee and time period combines the search to find existing, delete, and create of time records in that period |
bulkupdate | Fastest way to update individual employee records which does not require business logic to be applied (employee only used for external leave balance updates) |
getleaverequests | Search that returns leave requests based on search criteria (results are manipulated to return the required hours per day) |
updateleaverequest | Update An Individual Leave Request provides additional validation above a standard record update |
Response Model
All GET and POST Responses will return a JSON response object. Each response will always contain the success parameter, if true will be accompanied by a data block, if false it will contain an error block. If the request contains multiple elements, for example the submission of multiple time records, the response will contain individual success responses for each record, with the parent success being true unless one of the individual responses is false.
// Success response the operation completed successfully, the response may or may not contain a data component. // Example 1: response returns a single data object { "success": true, "data": { "success": true }, "id": "136473" } // Example 2: response returns an array of data objects { "success": true, "data": [ { "success": true, "id": "135871" }, { "success": true, "id": "135872" } ] } // Example 3: Failed response { "success":false, "error": { "code":"RCRD_DSNT_EXIST", "message":"That record does not exist." } }
Internal vs External IDs
All NetSuite records have an internal id (primary key) that is unique for the given record type and can be used when referencing the record. NetSuite also allows an external ID to be set which must be unique to that record type. The external ID must be alpha numeric and can only be set on add by the REST interface.
For all add and update actions you must use internal id references. If you do not know the internal id reference for a record but know the external id you can perform a lookup of the external reference using get or list.
GOTCHA: External ID only matches uppercase
When an external id is set on a record it comprises of two parts the label thats displayed and the actual value that matches. The value that matches is stored in upper case, if you are using the criteria externalidstring then a match will occur for the search string 'entityid' but would not if you tried to match 'externalid'.
By default the REST interface automatically changes the search value to uppercase before attempting to match.
Pagination
By default a search or list operation paginates to 1000 results, the paging size can be specified in the request, along with a pageno to allow more than the page size results to be returned. If a pageno is not specified it automatically defaults to 1.
// no paging is specified will return the first 1000 records. { "action": "list", "recordtype": "department" } // will return the first 10 results { "action": "list", "recordtype": "department", "pagesize": 10 } // will return the next 10 results (11 - 20) { "action": "list", "recordtype": "department", "pagesize": 2, "pageno": 2 }
List Lookups
If you are using a list request to obtain a lookup list for the purposes of mapping a record from an external system to NetSuite make sure your code is pagination safe and future proof for growth. As an example: An external system does not have a way to hold employee NetSuite internal ID's so performs a list view of employees to match externalids. If the employee count rises to 1,005 the most recent 5 employees will not be returned in the list request unless a second request for pageno: 2 is submitted.
NetSuite Configuration
Netsuite can be configured in a number of different ways that can impact the way the REST interface is used. Configuration options include:
- If the account is a NetSuite One World Account, the system has been setup to support the running of multiple companies (known as subsidiaries in the same account). A One world account requires each employee has a subsidiary set on create of employee, which cannot be changed.
- Classification, Department, Location are segmentation which if enabled in accounts will be returned in list, search and get queries.
To find the configuration options used in an account use the getInfo function call.
{ "action": "function", "function": "getinfo" }// returns { "success": true, "data": { "subsidiary": "T", "department": "T", "location": "T", "classification": "T", "nsversion": "2021.1", "accountid": "TSTDRV1234", "environment": "PRODUCTION" }, "processms": "0" }
Getting Started
The easiest way to test the REST interface without the need to develop functionality is to install the chrome extension ARC (Advanced Rest Client) available at https://chromerestclient.appspot.com/. Then follow these steps to test the most basic request and authentication details:
- enter the URL from the view license section
- set method to post
- set Content-Type header to application/json
- add a new custom header Authorization and add the details from the view license section.
- In the Raw payload add the request {"action":"function","function":"getinfo"}
Click send and if the access has been successful you will see a 200 response. If you get a 401: Unauthorized response check the authentication details
Logging
All rest requests are logged to a custom record Payroll REST Log, the log contains date created, user, the raw request and the response. To access the REST log, you must be using a payroll role, or administrator role. To view the log:
- Enter "Record Types" in the global search and select the page.
- Navigate to Payroll Rest Log and click List