- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
04-11-2025 05:32 AM
Another team in my company has the need to create records in ServiceNow. We have done some analysis and decided that a Scripted RestAPI is the correct implementation for this need so that we can do through validation on required fields on the creation of this record.
One consideration that we are struggling with is if we should allow an API user to the be the user that is the creator of the record, or if as part of the payload we ask the user that the API user is working on behalf of.
What does ServiceNow suggest in this situation? Is there a best practice for this?
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
04-11-2025 05:39 AM
whenever you use Scripted REST API you will use GlideRecord to update/create
if you use GlideRecord then ACLs won't be evaluated on that table
if you use GlideRecordSecure then ACLs will be evaluated on that table
If this is integration between 2 systems then better let the record be created with that API user
In this way within the instance you can track how many records got created via API.
If my response helped please mark it correct and close the thread so that it benefits future readers.
Ankur
✨ Certified Technical Architect || ✨ 9x ServiceNow MVP || ✨ ServiceNow Community Leader
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
04-11-2025 05:39 AM
whenever you use Scripted REST API you will use GlideRecord to update/create
if you use GlideRecord then ACLs won't be evaluated on that table
if you use GlideRecordSecure then ACLs will be evaluated on that table
If this is integration between 2 systems then better let the record be created with that API user
In this way within the instance you can track how many records got created via API.
If my response helped please mark it correct and close the thread so that it benefits future readers.
Ankur
✨ Certified Technical Architect || ✨ 9x ServiceNow MVP || ✨ ServiceNow Community Leader
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
4 weeks ago
Hello @Ankur Bawiskar ,
We are implementing Scripted REST APIs as well, but I am not able to successfully update the record using GlideRecordSecure. I am able to update the same record using standard GlideRecord api. However, when I test my logic in a background script as an admin, I don't have an issue updating using GlideRecordSecure. Is there something I may have missed to understand? Please see my sample code below:
Scripted REST API Resource (Please see comments in the code below)
(function process(/*RESTAPIRequest*/ request, /*RESTAPIResponse*/ response) {
var sysID = request.pathParams.sysID;
if (!sysID) {
response.setError(new sn_ws_err.BadRequestError('sysID not provided'));
response.setStatus(400);
return;
}
var requestBody = request.body.data;
var state = requestBody.state;
var closeCode = requestBody.closeCode;
var closeNotes = requestBody.closeNotes;
var workNotes = requestBody.workNotes;
if (!state && !closeCode && !closeNotes && !workNotes) {
response.setError(new sn_ws_err.BadRequestError('Object contains no or invalid properties'));
response.setStatus(400);
return;
}
// Query the incident table with the provided sysID
var incidentTable = 'incident';
var incidentGr = new GlideRecordSecure(incidentTable);
incidentGr.addQuery('sys_id', sysID);
incidentGr.addQuery('active', true);
incidentGr.query();
// Generate a 404 if no record is found.
if (!incidentGr.hasNext()) {
response.setError(new sn_ws_err.NotFoundError('No record found.'));
response.setStatus(404);
return;
}
// Had to write this logic to catch errors in the event user is not able to update due to ACL
// Can't seem to find a way to return a custom error message when update fails due to ACL.
if (!incidentGr.canWrite()) {
var forbiddenError = new sn_ws_err.ServiceError();
forbiddenError.setStatus(403);
forbiddenError.setMessage('Access Denied!');
forbiddenError.setDetail('The server could not process the request.');
response.setError(forbiddenError);
return;
}
if (incidentGr.next()) {
if (state) {incidentGr.state = parseInt(state);}
if (closeCode) {incidentGr.close_code = closeCode;}
if (closeNotes) {incidentGr.close_notes = closeNotes;}
if (workNotes) {incidentGr.work_notes = workNotes;}
incidentGr.update();
// the record does not show any updates, but the below response is seen when testing from Postman.
var responseObj = {
"sysID": incidentGr.getUniqueValue(),
"number": incidentGr.getValue('number'),
"message": "Record successfully updated."
};
response.setStatus(200);
response.setBody(responseObj );
}
})(request, response);
Sample Call from Postman (see attached screenshot)
Please advise if you spot anything wrong with my logic.
Thank you
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
4 weeks ago
It's not what you asked about,but I have found I get odd results when doing this:
response.setBody(responseObj);
If I send back a property with a value of 100 for example, I get "100.0", whci creates havoc if the calling code was expecting an int. So I do this instead:
response.getStreamWriter().writeString(JSON.stringify(responseObj));