Pages Menu

Posted by on Jul 6, 2021 in Development, Microsoft Teams

How to: use the Microsoft Graph to SET and CLEAR a user’s Microsoft Teams Presence

How to: use the Microsoft Graph to SET and CLEAR a user’s Microsoft Teams Presence

Update 6th July 2021: Although this is published API documentation, there seem to be some problems with actually executing these API calls right now. Thanks to Mohamed Ashiq Faleel for reporting this. If you are seeing “ServiceError” 401 exceptions then you aren’t doing anything wrong, that’s what we are seeing too. I’ve asked Microsoft for assistance and will update when I know more.

Update 9th July 2021: It seems that this feature was still rolling out to all tenants worldwide when I first published this article, and since then the API calls have now started working for me, and for others who also experienced the same problem. You should find that everything on this page now works as described, but if you continue to have problems, let me know!

We’ve been able to use Microsoft Graph to get the presence status of a specific user (using Delegated permissions) for a while now, and almost exactly a year ago a new change notification resource enabled us to react to changes in the presence of multiple difference users.

Now though, thanks to a new API endpoint in Microsoft Graph it’s possible for an application to programmatically set the presence of any Teams user.

How do I set the presence of a user?

It’s a POST request to setPresence, and requires an Application Permission with the Presence.ReadWrite.All permission.

In the request body, as well as specifying the availability and activity (2 terms we are already familiar with from the GET call) a new expirationDuration must be provided (in ISO8601 for Durations). This tells Teams when to reset the presence. In addition, the applicationID of the application making the presence set request must be passed as the sessionID parameter (otherwise you will get an error). Here’s an example:

Content-Type: application/json

  "sessionId": "22553876-f5ab-4529-bffb-cfe50aa89f87",
  "availability": "Available",
  "activity": "Available",
  "expirationDuration": "PT1H"

Be aware that this API call is in Beta, meaning you shouldn’t use it in Production.

When finished, Clear Presence

For applications that have set presence that is no longer valid, rather than simply letting the expirationDuration timeout, it’s possible to explicitly clear presence state at an application level with a new clearPresence API call:

This call has the same permission requirements as the setPresence call and should be called with the same sessionID (the application ID) when clearing presence so that Teams can correlate the calls and correctly update the combined presence state.

How is Presence determined in Teams?

One of the challenges with allowing applications to set user presence is that now there could potentially be many different applications all setting presence, not to mention the various Teams clients that a user may be signed into.

Similar to how Skype for Business exposes an aggregated presence state, Microsoft Teams consumes all these presence-setting calls and then provides one combined presence state. This means that an application could decide to either show the system-provided presence (and thus mirror the client) or keep their own presence state if it made more sense to show that in the application.

In general terms, any user-configured presence change takes precedence over app-configured changes. Because there aren’t delegated permissions for the setPresence call, what this really means is that changes to presence in the Teams client will take precedence.

You can set the presence availability to be Available, Busy or Away. Within the Busy availability, the activity can be set to either InACall or InAConferenceCall. You can’t set DoNotDisturb. Where multiple applications are setting overlapping presences, in general, Busy will take precedence over Available, which will take precedence over Away.

To maintain a presence state after the expirationDuration, make another call to refresh the presence.

What does this actually mean / what does it unlock?

Giving applications the ability to set user presence makes sense for applications that know users will be pre-occupied or generally not available. For instance, if you are building a mindfulness app and a user chooses a 30 min meditation session, your application might choose to set their Teams presence to be Away for 30 mins so that they are less likely to be disturbed.

What’s really interesting (to me) is the ability for an application to set presence to being “in a call” or “in a conference call”. This isn’t something an application would need to set for users when they are making and receiving Teams calls because the Teams client would set it. So, why have they done this? Why let applications deliberate set the presence of users in being in calls that aren’t Teams calls?

One possible reason could be to support users making and receiving calls using alternative calling platforms and not Teams. For instance, if you were to join a Zoom or WebEx meeting via an application, theoretically your presence could be updated to reflect that. Maybe someone will build a small Teams application to be able to manually set your status to “in a call” when making/receiving mobile calls…

I’ve talked extensively about Azure Communication Services and its ability to make and receive both one-to-one and group calls so this new API functionality might be to support users that use both Teams and ACS together and want to ensure they won’t receive incoming Teams calls whilst on an ACS call, for instance.

Documentation reference & more information: presence: setPresence – Microsoft Graph beta | Microsoft Docs

Written by Tom Morgan

Tom is a Microsoft Teams Platform developer and Microsoft MVP who has been blogging for over a decade. Find out more.
Buy the book: Building and Developing Apps & Bots for Microsoft Teams. Now available to purchase online with free updates.


  1. What are your thoughts on why can’t an application cannot read Presence in the same way?

  2. Hi Tom, thanks, for the article, so I did try the new API and it kinda works, kinda not. Every time I do api call with a valid availability/activity, I get 200 OK but I don’t see the status actually changing in the Teams App. What’s funny, I can see it being changed if I am logged as another user and just observe the user I change the status for. The status updates only when I restart teams app.
    Also when I change user status to Away/Away, it actually changes to… Available (green).
    So it kinda looks like both issue in TeamsApp and in graph API.
    Did you experience anything like this?

  3. Hi Tom, I had the same experience as Lukasz.
    Also I have another problem: although I set the Presence State to “Busy – InACall”, incoming calls are not rejected. And yes, Busy on Busy (Busy Options) is activated. So if I have a real Teams call a new incoming call is rejected.
    Any ideas how to resolve these two issues?

  4. Very helpful, thanks!

    I REALLY wish there was the ability to GET / SET the ‘status message’ field in Teams in addition to this (acitivity and availability for Presence)

Post a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.