Friday, 19 July 2013

SharePoint 2013: Get UserProfile Properties with REST API

In my last post SharePoint 2013: Working with User Profiles & JavaScript CSOM we saw how to get SharePoint UserProfile Properties using the JavaScript Client Object Model. In this post lets have a look at how to get them using the REST API. Here is a quick reference for the REST API endpoints.

(List of All User Properties and UserProfile Properties at the end of the post)


1) Get all properties of current user:

http://siteurl/_api/SP.UserProfiles.PeopleManager/GetMyProperties



2) Get single property of current user:

http://siteurl/_api/SP.UserProfiles.PeopleManager/GetMyProperties/PictureUrl
OR
http://siteurl/_api/SP.UserProfiles.PeopleManager/GetMyProperties?$select=PictureUrl



3) Get Multiple Properties for the current user:

http://siteurl/_api/SP.UserProfiles.PeopleManager/GetMyProperties?$select=PictureUrl,AccountName



4) Get all properties of Specific User:


For Office 365/SharePoint Online:
http://siteurl/_api/SP.UserProfiles.PeopleManager/GetPropertiesFor(accountName=@v)?@v='i:0%23.f|membership|vardhaman@siteurl.onmicrosoft.com'

For SharePoint 2013 On-Premise:
http://siteurl/_api/SP.UserProfiles.PeopleManager/GetPropertiesFor(accountName=@v)?@v='domain\username'



5) Get Specific UserProfile Property of Specific User:


For Office 365/SharePoint Online:
http://siteurl/_api/SP.UserProfiles.PeopleManager/GetUserProfilePropertyFor(accountName=@v,propertyName='LastName')?@v='i:0%23.f|membership|vardhaman@siteurl.onmicrosoft.com'


For SharePoint 2013 On-Premise:
http://siteurl/_api/SP.UserProfiles.PeopleManager/GetUserProfilePropertyFor(accountName=@v,propertyName='LastName')?@v='domain\username'



6) Get Multiple UserProfile Properties for Specific User:


Update (01/06/2016): Since the time I wrote this post, REST API batching has been implemented in SharePoint Online. As a result, we can make multiple REST requests to the GetUserProfilePropertiesFor function in a single REST call. This way, we can get Multiple custom/OOB UserProfile Properties for a Specific User without making multiple calls.

Here is my post on it:
SharePoint Online: Get UserProfile Properties with REST API Batching

Original Post Continues:

http://siteurl/_api/SP.UserProfiles.PeopleManager/GetUserProfilePropertiesFor
_api/SP.UserProfiles.PeopleManager/GetUserProfilePropertiesFor

As far as my research is concerned, this method is NOT supported in the REST API. The call to this method returns the following error:

"The method GetUserProfilePropertiesFor cannot be invoked as its parameter propertiesForUser is not supported."

If anybody finds any additional information on this, then I would love to update my blog on it. Here is my code for executing the above method:



-------

List of User Properties (Use the GetPropertiesFor function for these):

AccountName
DirectReports
DisplayName
Email
ExtendedManagers
ExtendedReports
IsFollowed
LatestPost
Peers
PersonalUrl
PictureUrl"
Title
UserProfileProperties
UserUrl

List of User Profile Properties (Use the GetUserProfilePropertyFor function for these):

AboutMe
SPS-LastKeywordAdded
AccountName
SPS-Locale
ADGuid
SPS-Location
Assistant
SPS-MasterAccountName
CellPhone
SPS-MemberOf
Department
SPS-MUILanguages
EduExternalSyncState
SPS-MySiteUpgrade
EduOAuthTokenProviders
SPS-O15FirstRunExperience
EduPersonalSiteState
SPS-ObjectExists
EduUserRole
SPS-OWAUrl
Fax
SPS-PastProjects
FirstName
SPS-Peers
HomePhone
SPS-PersonalSiteCapabilities
LastName
SPS-PersonalSiteInstantiationState
Manager
SPS-PhoneticDisplayName
Office
SPS-PhoneticFirstName
PersonalSpace
SPS-PhoneticLastName
PictureURL
SPS-PrivacyActivity
PreferredName
SPS-PrivacyPeople
PublicSiteRedirect
SPS-ProxyAddresses
QuickLinks
SPS-RegionalSettings-FollowWeb
SID
SPS-RegionalSettings-Initialized
SISUserId
SPS-ResourceAccountName
SPS-AdjustHijriDays
SPS-ResourceSID
SPS-AltCalendarType
SPS-Responsibility
SPS-Birthday
SPS-SavedAccountName
SPS-CalendarType
SPS-SavedSID
SPS-ClaimID
SPS-School
SPS-ClaimProviderID
SPS-ShowWeeks
SPS-ClaimProviderType
SPS-SipAddress
SPS-ContentLanguages
SPS-Skills
SPS-DataSource
SPS-SourceObjectDN
SPS-Department
SPS-StatusNotes
SPS-DisplayOrder
SPS-Time24
SPS-DistinguishedName
SPS-TimeZone
SPS-DontSuggestList
SPS-UserPrincipalName
SPS-Dotted-line
SPS-WorkDayEndHour
SPS-EmailOptin
SPS-WorkDayStartHour
SPS-FeedIdentifier
SPS-WorkDays
SPS-FirstDayOfWeek
Title
SPS-FirstWeekOfYear
UserName
SPS-HashTags
UserProfile_GUID
SPS-HireDate
WebSite
SPS-Interests
WorkEmail
SPS-JobTitle
WorkPhone
SPS-LastColleagueAdded

37 comments:

Mads said...

Per http://msdn.microsoft.com/en-us/library/jj163800.aspx#bkmk_CommonTasks the GetUserProfilePropertiesFor REST request must be GET (yes a message body). But it doesn't work either with the type changed.

Vardhaman Deshpande said...

Yes I tried with GET as well as PUT but I get back the same error message for both.

Chris O'Connor said...

I had to do a TEXT replace in some instances - for the URL with "#" :

i:0#.f|membership|vardhaman@tsunami684.onmicrosoft.com

i:0%23.f|membership|vardhaman@tsunami684.onmicrosoft.com

That was a gotcha for me

Anonymous said...

Can you specify how to use SetMyProfilePicture for REST in Sharepoint 2013?I went through this doc(http://msdn.microsoft.com/en-us/library/jj163800.aspx) and found this: REST: POST http:///_api/SP.UserProfiles.PeopleManager/SetMyProfilePicture and pass the picture parameter in the request body. So what is the fashion in which the picture parameter should be entered?

Vardhaman Deshpande said...

You can find that info in this post:

http://www.vrdmn.com/2013/11/set-userprofile-picture-using-net.html

Fredrik L said...

Hi

Regarding the issue in section 6). Add $select, and it will get multiple properties

url: _spPageContextInfo.webAbsoluteUrl + "/_api/SP.UserProfiles.PeopleManager/GetPropertiesFor(accountName=@v)?@v='" + loginName + "'&$select=PictureUrl,PersonalUrl"

jitendra pfbworldwide said...

Does any one able to get the solution for issue number 6.

Solution provided by @Fredrik doesn't work

jitendra pfbworldwide said...

@Fredrik : your solution does not worked.

Any other solutions???

Vardhaman Deshpande said...

@Jitendra,

You can use the javascript client object model to get that value

Anonymous said...

Can I use REST API in Office 365 to create users and groups on sharepoint office 365?

Shafaqat Ali said...

I am trying to get "QuickLinks" through java script but getting empty string, I have posted my code here, could you please check and see why I am getting empty string?

I also want to add new links in "QuickLinks" list, how can i do that, I am unable to find any help in google.

admin said...

to get all properties for a different user, use JSOM.

var peopleManager = new SP.UserProfiles.PeopleManager(ctx.appContext);
var profileProperties = peopleManager.getMyProperties();

ctx.appContext.load(profileProperties);
ctx.appContext.executeQueryAsync(function () {
ctx.profileProperties = profileProperties.get_userProfileProperties();
console.log(ctx.profileProperties);
}

A Man Down Under said...

Hi,

I have tried to use the code for obtaining User Profiles that I've seen on various blogs and even copied your code into my Office365 page as well but still receive a similar error message each time:


SCRIPT438: Object doesn't support property or method 'get_context'
SP.UserProfiles.js, line 1 character 121117


var peopleManager = new SP.UserProfiles.PeopleManager(ctx.appContext);
var profileProperties = peopleManager.getMyProperties();

ctx.appContext.load(profileProperties);
ctx.appContext.executeQueryAsync(function () {
ctx.profileProperties = profileProperties.get_userProfileProperties();
console.log(ctx.profileProperties);
});

Have you come across this issue before?

kaviya Balasubramanian said...

Hi Vardhanam,

Thanks for the post. I want to get all users from user profile using Java script object Model. Could you please help on this?

Vardhaman Deshpande said...

Hi kaviya,

You will have to use people search for that. So far, that functionality is not exposed via the user profile service (for REST API and CSOM)

snake said...

I want to use the HTTP Web Service in an Sharepoint Online 2013 Workflow to get an users profile property such as manager or department.
I used "https://mysite/_api/SP.UserProfiles.PeopleManager/GetUserProfilePropertyFor(accountName=@v,propertyName='Manager')?@v='i:0%23.f|membership|user@domain'" in a browser and got the result I expected.
In the Workflow I get an error saying: "{"odata.error":{"code":"-2147024891, System.UnauthorizedAccessException","message":{"lang":"de-DE","value":"Access denied. You don't have permissions to execute this process or to access this ressource."}}}" (translated from german)

How do I get the Workflow working?

Krauti said...

Hi, I'm calling the Getpropertiesfor REST service from within the Call https web service action within SharePoint Designer 2013. This call i have wrapped inside an App Step action to run this call with elevated permissions. I'm always getting an access denied error. Have you ever tried calling this endpoint from a workflow in order to get specific user information?

Vardhaman Deshpande said...

Hi Krauti,

Does your Workflow have permissions to read from the User Profile Service? You need to set this permission in the AppInv.aspx

See here for more details:
https://msdn.microsoft.com/en-us/library/office/jj822159.aspx

EI9GTB said...

Hi Vardhaman,

Thanks for your very informative article. Well written and very concise.

I have a question.... I want to query the User profile property to see if the PictureURL is populated. This works fine for my admin account but it I get an access denied message for other users. Do you know what permissions are required to do this?

http://site/_api/SP.UserProfiles.PeopleManager/GetMyProperties/PictureURL

If this returns a value (URL) I want to do something, otherwise I don't!

Any thought on how this can be achieved?

Thanks

Brian

Humbir Banerjee said...

Is there a way I can $select multiple custom user profile profiles using REST as I am getting below results:

https:///_api/SP.UserProfiles.PeopleManager/GetMyProperties?$select=DisplayName,Email - This works

https:///_api/SP.UserProfiles.PeopleManager/GetMyProperties?$select=DisplayName,Email,CustomeProperties1,CustomeProperties2 - This doesn't

All custom properties are coming inside UserProfileProperties node.

Do you have any workaround to minimize the output response?

Vardhaman Deshpande said...

Hi Brian,

How are you calling your code? Is it part of a SharePoint App (Add-In) or are you embedding it directly in the page using JavaScript?

If it is the former, make sure your App (Add-In) has Read access on "User Profiles (Social)". If it is the later, then I am not aware of the current user requiring any special permissions to access his/her own user profile properties.

Vardhaman Deshpande said...

Hi Humbir,

You are absolutely right. There is currently a limitation where you cannot $select custom user profile properties with PeopleManager/GetMyProperties

There is a user voice request open for this here:
https://officespdev.uservoice.com/forums/224641-general/suggestions/6533015-enable-selecting-custom-user-profile-properties-fr

One workaround I can think of is to use the CSOM or JSOM instead of the REST API until this bug is resolved. Both CSOM and JSOM support returning selected custom user profile properties.

Met@lTux said...

Hi Vardhaman.

I'm trying to put the user Picture in a image tag. In this moment I can show the Picture for the Admin User, but when I try to get the Image in any other user (I've using the Logged User), I got an Error like this:
"System.UnauthorizedAccessException"

The code I'm using:
jQuery.ajax({
url: "/_api/sp.userprofiles.peoplemanager/getmyproperties",
type: "GET",
headers: { "accept": "application/json;odata=verbose" },
success: successHandler,
error: errorHandler
});

function successHandler(values) {
var info = values.d;
/*Do something with the data*/
}

function errorHandler(values) {
alert("Error");
}


Can you help me with this?

Vipin Tanwar said...

Hi Vardhan - I didnt find one aspect in post. had query on the same. How do we get all user profiles i.e. all users ?

Vardhaman Deshpande said...

Hi Vipin, you will have to use SharePoint People search for that. Or if you are on SharePoint Online/Office 365, you can use the Azure AD graph API:
https://msdn.microsoft.com/en-GB/library/azure/dn151678.aspx

Dhaval Raval said...

Hi Vardhaman,

I do not see any code on this blog as well, if you can provide a link which shows how to make rest api call from the beginning

Vardhaman Deshpande said...

Hi Dhaval,

Are you reading the blog from an RSS reader? If yes, then the Gists (code) will not be visible. If you are reading the blog from a browser, then ensure that https://gist.github.com/ is not blocked.

Dhaval Raval said...

That helped thank you

Dhaval Raval said...

Hi Varhdaman, I am getting json response back from the server and there are nested json objects within main json object. for e.g. {"d": {"__metadata":"id ..."},"AccountName":"", ...}. As I am naive to json format I am not sure how do i parse through this nested json objects to get property values. Would you be able to point me in right direction ?

Dhaval Raval said...

Solution For 6) Get Multiple UserProfile Properties for Specific User

- As per microsoft (https://msdn.microsoft.com/en-us/library/office/dn790354.aspx#bk_PeopleManagerGetUserProfilePropertyFor): The GetUserProfilePropertiesFor method is not implemented in the REST API.

I was able to get multiple properties for a specific user in sharepoint online. Call to GetPropertiesFor return root json object with multiple nested json objects, one of the nested dictionary objects is "UserProfileProperties" which has 101 user profile properties.

Below is my code to get multiple properties of a specific user in sharepoint online (may be little naive)

var requestHeaders = {
"Accept": "application/json;odata=verbose",
"X-RequestDigest": jQuery("#__REQUESTDIGEST").val()
};

jQuery.ajax({
url: _spPageContextInfo.webAbsoluteUrl + "/_api/SP.UserProfiles.PeopleManager/GetPropertiesFor(@v)?@v='i%3A0%23.f%7Cmembership%7Cdhaval.raval@custom.onmicrosoft.com'",
type: "GET",
//data: JSON.stringify(theData),
contentType: "application/json;odata=verbose",
headers: requestHeaders,
success: function (data) {

var obj = data;
var rootObj = obj["d"];
var userProfProps = rootObj["UserProfileProperties"];
var results = userProfProps["results"];

// results is array with 101 properties

//last name has index 6
var lNameObj = results[6];
var lNameKey = lNameObj["Key"];
var lNameValue = lNameObj["Value"];

//first name has index 4
var fNameObj = results[4];
var fNameKey = fNameObj["Key"];
var fNameValue = fNameObj["Value"];


console.log(lNameKey);
console.log(lNameValue);

console.log(fNameKey);
console.log(fNameValue);

},
error: function (jqxr, errorCode, errorThrown) {
console.log("Error" + jqxr.responseText);
}
});



Similarly other properties can be retrieved using other index numbers

Vardhaman Deshpande said...

Hi Dhaval,

Thanks for your code! Yes it is possible to get the UserProfileProperties object and then get your required properties from that. The downside of this being that you are bringing back all 101 properties which would increase the data travelling over the wire.

If the GetUserProfilePropertiesFor was implemented in the REST API, we would be able to get back only the properties we want and that would not consume unnecessary bandwidth.

Ravi Kuppala said...

Hello ,

I am trying to call RETS send email ( /_api/SP.Utilities.Utility.SendEmail) using java script but it is throwing " {"error":{"code":"-2147024891, System.UnauthorizedAccessException","message":{"lang":"en-US","value":"Access denied. You do not have permission to perform this action or access this resource."}}}"

Any help would be appreciated .

var urlTemplate = siteurl + "/_api/SP.Utilities.Utility.SendEmail";

$.ajax({
contentType: 'application/json',
url: urlTemplate,
type: "POST",
crossDomain: true,
data: JSON.stringify({
'properties': {
'__metadata': { 'type': 'SP.Utilities.EmailProperties' },
'From': from,
'To': { 'results': [to] },
'Body': body,
'Subject': subject
}
}
),
headers: {
"Accept": "application/json;odata=verbose",
"content-type": "application/json;odata=verbose",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Credentials": true,
"Access-Control-Allow-Methods": "GET, POST, OPTIONS",
"Access-Control-Allow-Headers": "DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type",


"X-RequestDigest": $("#__REQUESTDIGEST").val()
},
success: function (data) {
console.log ("Email sent");
alert('Email sent');
history.go(-1);

},
error: function (err) {
console.log(err)
console.log (err.responseText);
}
});

Bimi Bimi said...

Hi,

I want to use this option:
http://siteurl/_api/SP.UserProfiles.PeopleManager/GetMyProperties

but what is the siteurl ???
is it the AD Domain Name ??

Seems not to work for me

Ashwani Vashishtha said...

Hi Vardhmaan,

Is it possible to Set WorkPhone property via any client object model ?

Artur Tarnowski said...

Hi,

For me option with domain\account doesn't work("For SharePoint 2013 On-Premise: http://siteurl/_api/SP.UserProfiles.PeopleManager/GetPropertiesFor(accountName=@v)?@v=’domain\username’").
If I have setup like above I getting response in data.d.Email that Email = undefined.
When I inspected JSON page body request I saw where was the problem (it was domainusername without '\' between them).
Fiddler show me GetPropertiesFor=(null). It's because domain and login must be added like that:
url: _spPageContextInfo.webAbsoluteUrl + "/_api/SP.UserProfiles.PeopleManager/GetPropertiesFor(accountName=@v)?@v='domain\\username'",



Best wishes,
Arthur

abhinav said...

Thanks All,

Easiest way to achieve this, I think is using web services-
Steps :
1. Add Web Reference to your project
2. PropertyData is collection of properties, which can be created like -
PropertyData[] newdata = new PropertyData[1];

//For each my site property, a newdata field is required
newdata[0] = new PropertyData();
newdata[0].Name = ""; //User Profile Field Internal Name
newdata[0].IsValueChanged = true;
newdata[0].Values = new ValueData[1];//If the field is multivalued, choose ValueData Array accordingly
newdata[0].Values[0] = new ValueData();
newdata[0].Values[0].Value = Value;

UserProfileService.ModifyUserPropertyByAccountName(item.AccountName, newdata);
Account Name is domain\username

Note : You can find internal names of field by -
PropertyData[] getAllProperties = userProfileService.GetUserProfileByName("domain\\username");
foreach (var property in getAllProperties)
{
Console.WriteLine(property.Name);
}

Mritunjaya Pradhan said...

Please suggest how to retrieve all reporties information for a manager(mean If the manager will log in to a page it will shown him all the employee those are direct reporting under him) using CSOM.