Changing user role via API

Context:
I am trying to change an existing user role from ā€˜userā€™ to ā€˜observerā€™ via Update User API: https://developer.pagerduty.com/api-reference/ce6799fc6191a-update-a-user
I am able to create new users with the ā€˜observerā€™ role via API but in this case Iā€™d like to update an existing user.

As the first step I get a user (and it works fine): in user.role = user.
Then I change it user.role = observer and call the Update API.

Expected behaviour:
The role is changed to ā€˜observerā€™ and the user is returned with the new role.

Witnessed behaviour:
It seems the role is not changed as the user is returned with the ā€˜userā€™ role via API and shown as ā€˜Managerā€™ on the web.

Hi @yury.beltrikov,

Could you share the HTTP request youā€™re making? For your reference, here is an example curl command that works to do what you are looking to do:

curl https://api.pagerduty.com/users/PXXXXXX \
 -X PUT \
 -H 'Content-Type: application/json' \
 -H 'Authorization: YOUR_AUTH_INFO' \
 -d '{
 "user": {
   "name": "The user's name is required",
   "email": "The user's email is also required",
   "role": "observer",
   "type": "user_reference"
 }
}'

Hope this helpsā€¦

My code is in PowerShell but I do not think it would be an issue as itā€™s pretty simple:

Step 1. Get the user.

$headers = @{
    "Accept"= "application/vnd.pagerduty+json;version=2";
    "Authorization"= "Token token=$APIkey"
    "Content-Type" = "application/json"
}
$id = 'Pxxxxx' #id of an existing user
$GetAPIUri = "https://api.pagerduty.com/users/$id"
$user = Invoke-RestMethod -Method GET -Uri $GetAPIUri -Headers $headers -Proxy $proxy -ProxyUseDefaultCredentials -UseBasicParsing

Step 2. Update the role field.
$user.user.role = 'observer'

Step 3. Update the PagerDuty user
$UpdateAPIUri = ā€œhttps://api.pagerduty.com/users/$idā€
$user = Invoke-RestMethod -Method PUT -Uri $UpdateAPIUri -Headers $headers -Body $user -Proxy $proxy -ProxyUseDefaultCredentials -UseBasicParsing

Hi @yury.beltrikov,

Ok, that makes sense. And I see why it might seem like a good idea to read in the whole user object, update a field and send back the whole thing. But that wonā€™t work reliably ā€“ partly because the user object as returned by GET /users/{id} contains fields that are not permitted in PUT /users/{id} payloads (computed or otherwise immutable fields)

Instead, you should construct a JSON object that contains only the user.name, user.email, user.role and user.type. I hope this helps, please let me know how it goesā€¦

Thanks!
Martin

I see. I slightly modified the code.

Step 1. Get the user.
$headers = @{
ā€œAcceptā€= ā€œapplication/vnd.pagerduty+json;version=2ā€;
ā€œAuthorizationā€= ā€œToken token=$APIkeyā€
ā€œContent-Typeā€ = ā€œapplication/jsonā€
}
$id = ā€˜Pxxxxxā€™ #id of an existing user
$GetAPIUri = ā€œhttps://api.pagerduty.com/users/$idā€
$user = Invoke-RestMethod -Method GET -Uri $GetAPIUri -Headers $headers -Proxy $proxy -ProxyUseDefaultCredentials -UseBasicParsing

Step 2. Modify role in a new user object
$updated_user = @{
ā€˜Nameā€™ = $user.user.name
ā€˜emailā€™ = $user.user.email
ā€˜roleā€™ = ā€˜userā€™ #this is a change. Current role = observer
}

Step 3. Update the PagerDuty user.
$UpdateAPIUri = ā€œhttps://api.pagerduty.com/users/$idā€

$user = Invoke-RestMethod -Method PUT -Uri $UpdateAPIUri -Headers $headers -Body $updated_user -Proxy $proxy -ProxyUseDefaultCredentials -UseBasicParsing

However, I get the following error.
Invoke-RestMethod : {ā€œerrorā€:{ā€œmessageā€:ā€œArguments Caused Errorā€,ā€œcodeā€:2002}}
At line:1 char:9

  • $user = Invoke-RestMethod -Method PUT -Uri $UpdateAPIUri -Headers $he ā€¦
  •     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    • CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
    • FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand

Hi @yury.beltrikov,

Looks like in your Step 2 you are setting a key ā€˜Nameā€™ but it should be ā€˜nameā€™ and you arenā€™t setting ā€˜typeā€™ which should be ā€˜user_referenceā€™. If I am correctly inferring PowerShell syntax from your snippet, the following should be closer to what you need:

$updated_user = @{
'name' = $user.user.name
'email' = $user.user.email
'role' = 'user'
'type' = 'user_reference'
}

Hope this helps, let me know what you observeā€¦

Thanks,
Martin

@martin Thank you!
I was able to change the user role via API with the changed code

1 Like

Nice work @yury.beltrikov, glad you got it working!