API Patch Role - Semantically Invalid

Hi all,

Trying to add users to a role via: patch-role | SailPoint Developer Community

The body I am using is:

[
  {
    "op": "add",
    "path": "/membership",
    "value": "443214bb99a04aa3b7b4b2710973591c"
  }
]

Have also tried:

"path": "/membership/aliasList/-",
&

[
  {
    "op": "add",
    "path": "/membership/aliasList/-",
    "value": {
        "id" : "443214bb99a04aa3b7b4b2710973591c"
    }
  }
]

Every attempt I am, getting the same 400 bad request:

“localeOrigin”: “REQUEST”,
“text”: “The request was syntactically correct but its content is semantically invalid.”,
“locale”: “en-US”

Does anybody have an idea as to what I’m getting wrong :eyes: ?

Cheers

Can you share the json of the role?

Have you tried doing a “replace” instead of an “add”?

Hello @SeanK-W

Could you please try the following cURL and let me know if it works as expected?

curl --location --request PATCH 'https://sailpoint.api.identitynow.com/beta/roles/2c91808a7813090a017814121e121518' \
--header 'Content-Type: application/json-patch+json' \
--header 'Accept: application/json' \
--data-raw '[
  {
    "op": "add",
    "path": "/membership",
    "value": "New description"
  }
]'

Thank you

@SeanK-W -

Use the request payload in the below format -

[
  {
    "op": "replace",
    "path": "/membership",
    "value": {
      "type": "IDENTITY_LIST",
      "identities": [
        {
          "id": "7afb1775939c47d6a760d885b028aa44",
		  "type": "IDENTITY"
        }
      ]
    }
  }
]

Mark it as solved, If this helps.

Hi Amit,

Thank you for the idea, I’ve tried this code and did successfully get a 200 response; however, this didn’t actually add the user to the role so unfortunately didn’t achieve what I am trying to do.

Ideally trying to have a API call that I can add and/or remove people from roles.

Please let me know if you have any other ideas :slight_smile:

Also odd that when I now run a call to get the role, it seems the Identity is there but the object looks empty. Nothing in the UI to imply the user has the role either? Maybe I need to wait a while for it to update or something?

Hi Edwin,

I’ve tried the replace method for this user ID (with results posted as replies to Amit in this thread) - getting odd results.

Here is the JSON for the role:

{
    "id": "14c0dd4132bd44d5af2b8dde4609b7a5",
    "name": "Manual - Block IT Access and Authentication",
    "created": "2025-04-11T05:17:02.523649Z",
    "modified": "2025-04-13T21:49:12.154459Z",
    "description": "Users added to this will be given access to groups in AD and AAD. Conditional policies are applied to these groups to block access and authentication",
    "owner": {
        "type": "IDENTITY",
        "id": "7eae9659b2a74564b1408a3feb7284f2",
        "name": "Sean Kriegerwill"
    },
    "entitlements": [],
    "accessProfiles": [],
    "membership": {
        "type": "IDENTITY_LIST",
        "criteria": null,
        "identities": [
            {
                "type": "IDENTITY",
                "id": "7afb1775939c47d6a760d885b028aa44",
                "name": null,
                "aliasName": null
            }
        ]
    },
    "legacyMembershipInfo": null,
    "enabled": true,
    "requestable": false,
    "accessRequestConfig": {
        "commentsRequired": null,
        "denialCommentsRequired": null,
        "approvalSchemes": [],
        "reauthorizationRequired": false
    },
    "revocationRequestConfig": {
        "approvalSchemes": []
    },
    "segments": [],
    "dimensional": false,
    "dimensionRefs": [],
    "accessModelMetadata": {
        "attributes": []
    }
}

@SeanK-W -

Check this post and let me know if that works as a workaround for you -

Thank you!

Using the replace syntax did work in the end, the UI took quite long time to reflect the change… Which is a real shame because it delays access management.

[
  {
    "op": "replace",
    "path": "/membership",
    "value": {
      "type": "IDENTITY_LIST",
      "identities": [
        {
          "id": "7afb1775939c47d6a760d885b028aa44",
		  "type": "IDENTITY"
        }
      ]
    }
  }
]

However, the replace operation isn’t quite what I’m after, I’m trying to remove or add people to the list.

Even when I change the ‘replace’ op to ‘add’, it still seems to replace the identities… Any ideas on how to do an add or remove rather than a full replace?

Hey @SeanK-W,

You should be able to do the patch on the identities field like so.


 [
   {
     "op": "add",
     "path": "/membership/identities/-",
     "value": {
                 "type": "IDENTITY",
                 "id": "d4d367cda6774571ad4183b83028f52f",
                 "name": "Adam.Kennedy",
                 "aliasName": "Adam.Kennedy"
             }
   }
 ]
1 Like

Thanks Tyler, this is exactly what I was after. Looks like I needed to update my path and add an additional curly bracket inside of the value to get a 200 response.

Thank you!

Although, when I try a “remove” operation I get the 400 response again :frowning:

Does the remove body need to be different in some way?

Also it seems to allow duplicates being added which is odd, I would’ve thought it reject this if the data already exists:

The duplicates should not be allowed. I will raise a ticket with the team to dig into that further.

To remove you must know the index at which the identity you want to remove is at. For example, if you wanted to remove the first identity in the list, you could use the patch structure below.

[
   {
     "op": "remove",
     "path": "/membership/identities/0"
   }
 ]

Hi Tyler,

Thank you for this, I can confirm this has worked and successfully removed the user.

Do you know if the pathing is limited via hardcoding to the position of the identity in the list? For example, say if I have 50 users and would like to remove an identity. Would I need to identify the position they appear against the role? EG: /membership/identities/23

Additionally, I have noticed that when we add users to the list using ID, when I get info about the role, they appear in the response but not in the UI?

With that, how do you avoid race condition during the period between knowing the index position, and committing the patch request?