Rest Message From scripted rest API
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
09-29-2025 04:15 AM
I have a rest message with OAuth token of third party vendor
when I try with the test button in the rest message it works fine
but when I try with the scripted rest api I got this
"errorCode":"AUTHORIZATION_INVALID_TOKEN","message":"The access token provided is expired, revoked or malformed."}
this is my script
(function process(request, response) {
var J = new global.JSON();
// --- get IDs from your payload (adapt as needed) ---
var raw = (request.body && request.body.dataString) || "";
var p = {};
try { p = raw ? J.decode(raw) : {}; } catch(e){}
var accountId = (p.accountId || p.data && p.data.accountId || "").trim();
var envelopeId = (p.envelopeId || p.data && p.data.envelopeId || "").trim();
if (!accountId || !envelopeId) {
gs.error("[DS] Missing accountId/envelopeId. accountId=" + accountId + " envelopeId=" + envelopeId);
response.setStatus(400); return;
}
// ---- use your REST Message + Method ----
var r = new sn_ws.RESTMessageV2('Docusign Auth', 'Get Envelope');
// 🔒 1) FORCE the OAuth profile BY SYS_ID (no ambiguity across scopes)
// How to get it: open your OAuth Entity Profile record → right-click header → Copy sys_id
var OAUTH_PROFILE_SYS_ID = 'bc873919875cb25040f210273cbb3582';
r.setAuthenticationProfileId('oauth2', OAUTH_PROFILE_SYS_ID);
// 2) Vars must match your method's variable names exactly
r.setStringParameter('accountid', accountId);
r.setStringParameter('envelopeid', envelopeId);
// 3) Helpful logs
gs.info("[DS] Endpoint -> " + r.getEndpoint());
var resp = r.execute();
var code = resp.getStatusCode();
var body = (resp.getBody() || "") + "";
var errm = resp.getErrorMessage();
gs.info("[DS] HTTP " + code + (errm ? (" | err=" + errm) : ""));
gs.info("[DS] Body preview: " + body.substr(0, 1500));
// 🔁 Fallback: if 401, manually fetch token from that SAME profile and retry once
if (code === 401) {
gs.info("[DS] 401 -> retry with manual Bearer from OAuth profile");
var oauth = new sn_auth.GlideOAuthClient();
var tok = oauth.getTokenByProfileId(OAUTH_PROFILE_SYS_ID);
var access = tok && tok.getAccessToken();
if (!access) { gs.error("[DS] Could not fetch access token. Re-authorize profile (Get OAuth Token)."); response.setStatus(500); return; }
var r2 = new sn_ws.RESTMessageV2('Docusign Auth', 'Get Envelope');
r2.setStringParameter('accountid', accountId);
r2.setStringParameter('envelopeid', envelopeId);
r2.setRequestHeader('Authorization', 'Bearer ' + access);
gs.info("[DS] Endpoint (retry) -> " + r2.getEndpoint());
var resp2 = r2.execute();
gs.info("[DS] HTTP (retry) " + resp2.getStatusCode() + " | " + (resp2.getErrorMessage() || ""));
gs.info("[DS] Body preview (retry): " + (resp2.getBody() || "").substr(0,1500));
}
response.setStatus(200);
})(request, response);
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
09-29-2025 05:03 AM
I created oAuth profile
and linked it with the rest message
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
09-29-2025 06:09 AM
then simply use REST Message and don't give any OAuth profile etc as REST Message already has linked OAuth profile
try this once
(function process(request, response) {
var J = new global.JSON();
// --- get IDs from your payload (adapt as needed) ---
var raw = (request.body && request.body.dataString) || "";
var p = {};
try {
p = raw ? J.decode(raw) : {};
} catch (e) {}
var accountId = (p.accountId || p.data && p.data.accountId || "").trim();
var envelopeId = (p.envelopeId || p.data && p.data.envelopeId || "").trim();
if (!accountId || !envelopeId) {
gs.error("[DS] Missing accountId/envelopeId. accountId=" + accountId + " envelopeId=" + envelopeId);
response.setStatus(400);
return;
}
// ---- use your REST Message + Method ----
var r = new sn_ws.RESTMessageV2('Docusign Auth', 'Get Envelope');
// 🔒 1) FORCE the OAuth profile BY SYS_ID (no ambiguity across scopes)
// How to get it: open your OAuth Entity Profile record → right-click header → Copy sys_id
var OAUTH_PROFILE_SYS_ID = 'bc873919875cb25040f210273cbb3582';
// 2) Vars must match your method's variable names exactly
r.setStringParameter('accountid', accountId);
r.setStringParameter('envelopeid', envelopeId);
// 3) Helpful logs
gs.info("[DS] Endpoint -> " + r.getEndpoint());
var resp = r.execute();
var code = resp.getStatusCode();
var body = (resp.getBody() || "") + "";
var errm = resp.getErrorMessage();
gs.info("[DS] HTTP " + code + (errm ? (" | err=" + errm) : ""));
gs.info("[DS] Body preview: " + body.substr(0, 1500));
// 🔁 Fallback: if 401, manually fetch token from that SAME profile and retry once
if (code === 401) {
gs.info("[DS] 401 -> retry with manual Bearer from OAuth profile");
var oauth = new sn_auth.GlideOAuthClient();
var tok = oauth.getTokenByProfileId(OAUTH_PROFILE_SYS_ID);
var access = tok && tok.getAccessToken();
if (!access) {
gs.error("[DS] Could not fetch access token. Re-authorize profile (Get OAuth Token).");
response.setStatus(500);
return;
}
var r2 = new sn_ws.RESTMessageV2('Docusign Auth', 'Get Envelope');
r2.setStringParameter('accountid', accountId);
r2.setStringParameter('envelopeid', envelopeId);
r2.setRequestHeader('Authorization', 'Bearer ' + access);
gs.info("[DS] Endpoint (retry) -> " + r2.getEndpoint());
var resp2 = r2.execute();
gs.info("[DS] HTTP (retry) " + resp2.getStatusCode() + " | " + (resp2.getErrorMessage() || ""));
gs.info("[DS] Body preview (retry): " + (resp2.getBody() || "").substr(0, 1500));
}
response.setStatus(200);
})(request, response);
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
09-30-2025 12:16 AM
hey, tried this also but still same issue for the token
401 - Invalid username/password combo
{"errorCode":"AUTHORIZATION_INVALID_TOKEN","message":"The access token provided is expired, revoked or malformed."}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
09-30-2025 12:54 AM
Why "Test" works but Scripted call fails
Test button uses the linked OAuth Entity Profile (from Application Registry). When you test, ServiceNow fetches/refreshes the token properly before making the call.
-
Scripted REST API → your script may be:
-
Not binding the correct OAuth profile sys_id.
-
Using a cached/expired token from the wrong profile.
-
Overriding the Authorization header incorrectly
-
Revised Code :-
(function process(request, response) {
var J = new global.JSON();
var raw = (request.body && request.body.dataString) || "";
var p = {};
try { p = raw ? J.decode(raw) : {}; } catch(e){}
var accountId = (p.accountId || "").trim();
var envelopeId = (p.envelopeId || "").trim();
if (!accountId || !envelopeId) {
gs.error("[DS] Missing accountId or envelopeId");
response.setStatus(400);
return;
}
var OAUTH_PROFILE_SYS_ID = 'bc873919875cb25040f210273cbb3582';
// Always fetch the latest token
var oauth = new sn_auth.GlideOAuthClient();
var tok = oauth.getTokenByProfileId(OAUTH_PROFILE_SYS_ID);
if (!tok) {
gs.error("[DS] Could not fetch access token. Re-authorize profile.");
response.setStatus(500);
return;
}
var access = tok.getAccessToken();
// Call REST API with fresh token
var r = new sn_ws.RESTMessageV2('Docusign Auth', 'Get Envelope');
r.setStringParameter('accountid', accountId);
r.setStringParameter('envelopeid', envelopeId);
r.setRequestHeader('Authorization', 'Bearer ' + access);
var resp = r.execute();
var code = resp.getStatusCode();
var body = resp.getBody();
gs.info("[DS] HTTP " + code + " | body: " + body.substr(0,1000));
response.setStatus(code);
response.setBody(body);
})(request, response);
If you found my response helpful, I would greatly appreciate it if you could mark it as "Accepted Solution" and "Helpful."
Your support not only benefits the community but also encourages me to continue assisting. Thank you so much!
Thanks and Regards
Ravi Gaurav | ServiceNow MVP 2025,2024 | ServiceNow Practice Lead | Solution Architect
CGI
M.Tech in Data Science & AI
YouTube: https://www.youtube.com/@learnservicenowwithravi
LinkedIn: https://www.linkedin.com/in/ravi-gaurav-a67542aa/
