Getting error for web service API call

Hi Team,

I am getting below error for web service entitlement revoke in which we need to remove roles and teams and mentioned “teamIds“ and “roleIds“ going to be retained

but I am able to trigger in Postman API at https://test.1234.sample.net/cxrestapi/auth/users/123456

[“Exception while updating account.Url: https://test.1234.test.net/cxrestapi/auth/users/469, Message: 400 : Bad Request : {“Message”:“A non-empty request body is required.”}, HTTP Error Code: 400”]

{
“firstName”: “$plan.firstName$”,
“lastName”: “$plan.lastName$”,
“active”: $plan.active$,
“email”: “$plan.email$”,
“cellPhoneNumber”: “$plan.cellPhoneNumber$”,
“country”: “$plan.country$”,
“expirationDate”: “$plan.expirationDate$”,
“jobTitle”: “$plan.jobTitle$”,
“other”: “$plan.other$”,
“phoneNumber”: “$plan.phoneNumber$”,
“roleIds”: [
$plan.roleIds$
],
“teamIds”: [
$plan.teamIds$
],
“localeId”: $plan.localeId$
}

Thanks

Kalyan

Based on the error message the post json body is empty.

Hi, but I am able to trigger this API in Postman with hard coded values.

if hardcoded is working in postman, check provisioning policy is created properly or not

Hi, thank you and will check on this. Here the requirement is that the reviewer will try to remove the roles ids/teams ids during user access review and remaining roles ids/teams ids need to be updated back to the user as per the below body payload .

{
“firstName”: “$plan.firstName$”,
“lastName”: “$plan.lastName$”,
“active”: $plan.active$,
“email”: “$plan.email$”,
“cellPhoneNumber”: “$plan.cellPhoneNumber$”,
“country”: “$plan.country$”,
“expirationDate”: “$plan.expirationDate$”,
“jobTitle”: “$plan.jobTitle$”,
“other”: “$plan.other$”,
“phoneNumber”: “$plan.phoneNumber$”,
“roleIds”: [ $plan.roleIds$ ],
“teamIds”: [ $plan.teamIds$ ],
“localeId”: $plan.localeId$
}

Thanks

Check your Attribute path for each attribute whether it is populating the needed values properly

Hi, I have checked the attributes path and looks like everything is fine as below.

Hi, I have written after provisioning web service rule for role revoke along with HTTP remove operation but still getting same error.

Hi everyone,

did anyone find any idea on this issue?

thanks

Kalyan

Hi Kalyan,
“400 : Bad Request : {“Message”:“A non-empty request body is required.”}” - typically indicates that the API endpoint is receiving an empty or improperly formatted payload.

A few things to check:

  1. Variable Substitution: Ensure that all $plan.*$ variables are being correctly resolved before the payload is sent. If any of them are null or not populated, the resulting JSON may be invalid or empty.

  2. Payload Formatting: Double-check that the final JSON being sent (after variable substitution) is valid and not empty. You can log or print the payload just before it’s sent to verify.

  3. Content-Type Header: Confirm that the request includes the correct header:

    Code

    Content-Type: application/json
    
    
  4. Empty Arrays: If roleIds or teamIds are empty arrays, some APIs may treat that as an empty body. Try removing those fields entirely if they’re not needed for the revoke operation.

  5. Endpoint Consistency: You mentioned two different URLs in your message - one with sample.net and another with test.net. Make sure the correct and consistent endpoint is being used.

Let us know what the resolved payload looks like, and we can help further if needed.

HI @kalyannambi2010 ,

The values you’re passing in the body right, from where the values passed, using provisioning policy or beforeprovisioning rule.

Hi @gogubapu

Example: During user access review using PUT API call if the user is having 3 roleIds/teamIds multivalued multiple entitlements then the reviewer tries to revoke one or more roleIds/teamIds from the user then the rest remaining should be updated accordingly after removal of the one or more roleIds/teamIds from the user.

Postman API looks like as below:

the method is PUT. so any details sent in payload are retained.So the above payload indicates that role 10 & team 12 are retained / created to the user. All other roles and teams are removed. if user is part of 3 teams with 3 roles the get user payload shows"roleIds": [12,13,15],“teamIds”: [10,11,20],if you want to remove roles 13,15 or teams 11 & 20 u should update user and pass only what you want to retain i.e.,“roleIds”: [ 12 ],“teamIds”: [ 10 ],

Thanks

Kalyan

Hi @dkumar,

Example: During user access review using PUT API call if the user is having 3 roleIds/teamIds multivalued multiple entitlements then the reviewer tries to revoke one or more roleIds/teamIds from the user then the rest remaining should be updated accordingly after removal of the one or more roleIds/teamIds from the user.

Postman API looks like as below:

the method is PUT. so any details sent in payload are retained.So the above payload indicates that role 10 & team 12 are retained / created to the user. All other roles and teams are removed. if user is part of 3 teams with 3 roles the get user payload shows"roleIds": [12,13,15],“teamIds”: [10,11,20],if you want to remove roles 13,15 or teams 11 & 20 u should update user and pass only what you want to retain i.e.,“roleIds”: [ 12 ],“teamIds”: [ 10 ],

Thanks

Kalyan

Hi,

I have written below Before-operation rule to remove specified roleIds/teamIds, update remaining, and update firstName/lastName.

<?xml version='1.0' encoding='UTF-8'?> Before-operation rule to remove specified roleIds/teamIds, update remaining, and update firstName/lastName. <![CDATA[

import java.util.Map;
import java.util.List;
import java.util.ArrayList;
import sailpoint.connector.webservices.EndPoint;
import sailpoint.object.Application;
import sailpoint.object.ProvisioningPlan;
import sailpoint.object.ProvisioningPlan.AccountRequest;
import sailpoint.object.ProvisioningPlan.AttributeRequest;
import sailpoint.tools.Util;
import connector.common.JsonUtil;

log.info(“CheckmarxBeforeOp: Start processing user update”);

// Validate endpoint & body
if (requestEndPoint == null) {
log.warn(“CheckmarxBeforeOp: requestEndPoint is null”);
return requestEndPoint;
}
Map bodyMap = requestEndPoint.getBody();
if (bodyMap == null) {
log.warn(“CheckmarxBeforeOp: Body map is null – initializing”);
bodyMap = new java.util.HashMap();
}
Object jsonBodyObj = bodyMap.get(“jsonBody”);
String jsonBody = null;
if (jsonBodyObj instanceof String) {
jsonBody = ((String) jsonBodyObj).trim();
}
if (Util.isNullOrEmpty(jsonBody)) {
// initialize an empty JSON object so we are not sending null/empty body
log.info(“CheckmarxBeforeOp: jsonBody was empty → initialising new JSON payload”);
jsonBody = “{}”;
}

Map<String,Object> jsonMap = null;
try {
jsonMap = JsonUtil.toMap(jsonBody);
} catch (Exception e) {
log.error("CheckmarxBeforeOp: Failed to parse incoming JSON body: " + e.getMessage(), e);
jsonMap = new java.util.HashMap<String,Object>();
}
if (jsonMap == null) {
jsonMap = new java.util.HashMap<String,Object>();
}

// — Update attributes: firstName, lastName, email, active, cellPhoneNumber, phoneNumber, jobTitle, other, country, localeId
if (provisioningPlan != null && provisioningPlan.getAccountRequests() != null) {
for (AccountRequest accReq : provisioningPlan.getAccountRequests()) {
if (accReq.getAttributeRequests() == null) continue;
for (AttributeRequest attReq : accReq.getAttributeRequests()) {
String attrName = attReq.getName();
Object attrVal = attReq.getValue();
if (attrVal == null) continue;
if (“firstName”.equalsIgnoreCase(attrName) && attrVal instanceof String) {
jsonMap.put(“firstName”, ((String)attrVal).trim());
log.info("CheckmarxBeforeOp: Updated firstName → " + attrVal);
} else if (“lastName”.equalsIgnoreCase(attrName) && attrVal instanceof String) {
jsonMap.put(“lastName”, ((String)attrVal).trim());
log.info("CheckmarxBeforeOp: Updated lastName → " + attrVal);
} else if (“email”.equalsIgnoreCase(attrName) && attrVal instanceof String) {
jsonMap.put(“email”, ((String)attrVal).trim());
log.info("CheckmarxBeforeOp: Updated email → " + attrVal);
} else if (“active”.equalsIgnoreCase(attrName) && attrVal instanceof Boolean) {
jsonMap.put(“active”, attReq.getValue());
log.info("CheckmarxBeforeOp: Updated active → " + attrVal);
} else if (“cellPhoneNumber”.equalsIgnoreCase(attrName) && attrVal instanceof String) {
jsonMap.put(“cellPhoneNumber”, ((String)attrVal).trim());
log.info("CheckmarxBeforeOp: Updated cellPhoneNumber → " + attrVal);
} else if (“phoneNumber”.equalsIgnoreCase(attrName) && attrVal instanceof String) {
jsonMap.put(“phoneNumber”, ((String)attrVal).trim());
log.info("CheckmarxBeforeOp: Updated phoneNumber → " + attrVal);
} else if (“jobTitle”.equalsIgnoreCase(attrName) && attrVal instanceof String) {
jsonMap.put(“jobTitle”, ((String)attrVal).trim());
log.info("CheckmarxBeforeOp: Updated jobTitle → " + attrVal);
} else if (“other”.equalsIgnoreCase(attrName) && attrVal instanceof String) {
jsonMap.put(“other”, ((String)attrVal).trim());
log.info("CheckmarxBeforeOp: Updated other → " + attrVal);
} else if (“country”.equalsIgnoreCase(attrName) && attrVal instanceof String) {
jsonMap.put(“country”, ((String)attrVal).trim());
log.info("CheckmarxBeforeOp: Updated country → " + attrVal);
} else if (“localeId”.equalsIgnoreCase(attrName) && attrVal instanceof Integer) {
jsonMap.put(“localeId”, attrVal);
log.info("CheckmarxBeforeOp: Updated localeId → " + attrVal);
}
}
}
}

// — Remove roleIds if present
List) jsonMap.get(“removeRoleIds”);
if (removeRoleIds != null) {
List) jsonMap.get(“roleIds”);
if (existingRoles == null) {
existingRoles = new ArrayList<>();
}
List newRoles = new ArrayList<>();
for (Object rid : existingRoles) {
if (!removeRoleIds.contains(rid)) {
newRoles.add(rid);
} else {
log.info("CheckmarxBeforeOp: Removing roleId → " + rid);
}
}
jsonMap.put(“roleIds”, newRoles);
jsonMap.remove(“removeRoleIds”);
}

// — Remove teamIds if present
List) jsonMap.get(“removeTeamIds”);
if (removeTeamIds != null) {
List) jsonMap.get(“teamIds”);
if (existingTeams == null) {
existingTeams = new ArrayList<>();
}
List newTeams = new ArrayList<>();
for (Object tid : existingTeams) {
if (!removeTeamIds.contains(tid)) {
newTeams.add(tid);
} else {
log.info("CheckmarxBeforeOp: Removing teamId → " + tid);
}
}
jsonMap.put(“teamIds”, newTeams);
jsonMap.remove(“removeTeamIds”);
}

// — Ensure we are sending something meaningful
if (jsonMap.isEmpty()) {
log.warn(“CheckmarxBeforeOp: jsonMap is empty. Adding a dummy field to avoid empty body”);
// Add e.g. an unchanged field so body is not empty
jsonMap.put(“id”, ((Application)application).getId());
// Note: adjust the above if “application” id is not the user id—maybe you retrieve userId separately
}

// — Render and set body
String newJsonBody = JsonUtil.render(jsonMap);
log.info("CheckmarxBeforeOp: Final JSON payload → " + newJsonBody);

bodyMap.put(“jsonBody”, newJsonBody);
requestEndPoint.setBody(bodyMap);

return requestEndPoint;

]]>

Thanks