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!