Search code examples
javascriptoutlookmsdnoutlook-restapi

Getting a Count of Contacts from Outlook Office REST API - Javascript


I'm having difficulty distinguishing between Microsoft's absurd amount of conflicting API documentations: outlook.office.com, outlook.office365.com, microsoft graph, Azure, and so on

I've successfully authenticated and pulled contacts, but I can't seem to get a count to know when I should stop pagination.

I've been using:

Access Token url: 
    https://login.microsoftonline.com/common/oauth2/v2.0/token;
Successful Contact url: 
    https://outlook.office.com/api/v2.0/me/contacts;

Their REST API Resource says I should be able to simply make a call to https://outlook.office.com/api/v2.0/me/contacts/$count but this keeps returning a plaintext MIME type with body -1.

If anyone has struggled with this before or knows what's going on, I'd appreciate a point in the right direction - and hopefully some easy points for you!


EDIT: Thanks to Jason below for his helpful support. Using the sandbox I was able to reproduce the issue with the following:

Logged in to my account -> Received Access Tokens -> Made a GET call to https://outlook.office.com/api/v2.0/me/contacts/$count

Request Headers:

GET https://outlook.office.com/api/v2.0/me/contacts/$count HTTP/1.1
Accept: text/*, application/xml, application/json; odata.metadata=none
User-Agent: PlayGroundAgent/1.0
Authorization: Bearer [standard-access-token]
client-request-id: 8f605[client-id-obscured-for-security]7289
X-AnchorMailbox: [email-address-removed-for-security on stackOverflow]

Response

HTTP/1.1 200 OK
Transfer-Encoding: chunked
request-id: de95eaa8-95a7-40bb-b0f9-ced7270f0433
X-CalculatedBETarget: SN1PR05MB1998.namprd05.prod.outlook.com
X-BackEndHttpStatus: 200
OData-Version: 4.0
X-DiagInfo: SN1PR05MB1998
X-BEServer: SN1PR05MB1998
X-FEServer: SN1PR0501CA0035
X-MSEdge-Ref: Ref A: 657E0491C29D46978D8DD3B01B9F93A3 Ref B: DDDD64A109F4E842A8213F038BFDD5FA Ref C: Fri Aug 19 09:20:05 2016 PST
Cache-Control: private
Date: Fri, 19 Aug 2016 16:20:05 GMT
Set-Cookie: exchangecookie=6ca5fc4df96e458e8b879de61aa574ef; expires=Sat, 19-Aug-2017 16:20:05 GMT; path=/; HttpOnly
Server: Microsoft-IIS/8.5
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET

-1

2nd Edit: It looks like https://outlook.office.com/api/v2.0/me/contacts?$count=true returns @odata.count": -1 as well, even as it returns valid array of contacts.


3rd Edit: Working version (Same method was used as the errors above) Url: https://outlook.office.com/api/v2.0/me/contacts/$count

Request Headers:

GET https://outlook.office.com/api/v2.0/me/contacts/$count HTTP/1.1
Accept: text/*, application/xml, application/json; odata.metadata=none
User-Agent: PlayGroundAgent/1.0
Authorization: Bearer [access-token]
client-request-id: a7954db3-[client-id]-7a6e2e74dd9c
X-AnchorMailbox: [same-email-as-above]

Response:

HTTP/1.1 200 OK
Transfer-Encoding: chunked
request-id: 8c5db16b-3023-4968-9bdc-3d5ecac12ecb
X-CalculatedBETarget: SN1PR05MB1998.namprd05.prod.outlook.com
X-BackEndHttpStatus: 200
OData-Version: 4.0
X-DiagInfo: SN1PR05MB1998
X-BEServer: SN1PR05MB1998
X-FEServer: SN1PR0501CA0019
X-MSEdge-Ref: Ref A: 0574E46DB720491FBCEF23B73428F191 Ref B: FA4529229719F069B9D019E4D53E9200 Ref C: Fri Aug 19 09:42:55 2016 PST
Cache-Control: private
Date: Fri, 19 Aug 2016 16:42:55 GMT
Set-Cookie: exchangecookie=63a1de916a4c48be88569f05ce0361a7; expires=Sat, 19-Aug-2017 16:42:55 GMT; path=/; HttpOnly
Server: Microsoft-IIS/8.5
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET

29

Hope these help!


Solution

  • Sorry to hear that you're having trouble! There's a couple of things going on here.

    It's troubling that you're getting a negative number back from the $count call. If you go to https://oauthplay.azurewebsites.net and login with your account, do you get the same result from that call?

    For paging, if all you want to do is get all the results, it is better to not rely on the $count value. Instead, you should use the @odata.nextLink value that comes back in the response to get the next page. Of course if you're trying to indicate to a user how many pages are there before getting all the results, the $count is the way to do that.

    Paging is controlled by the page size (the $top parameter) and the "cursor" (the $skip parameter). If you're making a call to/me/contactswith no parameters, then you're getting the default page size of 10 and default cursor of 0. You can use the$top` parameter to request more results per page.

    The @odata.nextLink value will always return a URL you can use to get the next page based on the page size you specified in $top (or 10 if you did not specify). Here's the value from doing GET https://outlook.office.com/api/v2.0/me/contacts:

    "@odata.nextLink": "https://outlook.office.com/api/v2.0/me/contacts/?%24skip=10"
    

    This skips you ahead 10 results (based on the default page size of 10).

    And here's the value from GET https://outlook.office.com/api/v2.0/me/contacts/?$top=20:

    "@odata.nextLink": "https://outlook.office.com/api/v2.0/me/contacts/?%24top=20&%24skip=20"
    

    If there are no more pages, the @odata.nextLink value will not be present in the response. So you can use that as your indicator to stop paging.