Back to Blog
Developer

Microsoft Graph Presence API: Get and Set Teams Status

The Microsoft Graph presence API reads and changes Microsoft Teams status. GET /me/presence returns your availability and activity, POST /communications/getPresencesByUserId returns up to 650 users per call, and setPresence, setUserPreferredPresence and setStatusMessage change what Teams shows. Every endpoint, the permission it needs, request examples, and the timeout rules that trip people up.

Slack Green Team
September 27, 2026
September 27, 2026
5 min read
Share:
microsoft graph
microsoft teams
presence
api

The Microsoft Graph presence API is how code reads and changes Microsoft Teams status. GET /me/presence returns your own availability and activity, such as Busy and InAMeeting. GET /users/{id}/presence returns one user, and POST /communications/getPresencesByUserId returns up to 650 users per request. To change status, setUserPreferredPresence sets the status a user would pick by hand, setPresence sets an app's own presence session, and setStatusMessage sets the status message. Reading needs Presence.Read or Presence.Read.All; writing needs Presence.ReadWrite or, as an application, Presence.ReadWrite.All. It works for work or school accounts only, not personal Microsoft accounts.

Everything here comes from the Microsoft Graph v1.0 reference pages and "Manage presence state using the Microsoft Graph API", read on 27 September.

Presence APIs are what we build on. Slack Green keeps a Slack status green during the hours you set, and the Slack side of this page is the Slack presence API and setting a Slack status with the API.

Microsoft Graph presence API: GET /me/presence, getPresencesByUserId for up to 650 users, setPresence and setUserPreferredPresence

Presence endpoints and permissions

Graph presence endpoints and the least permission each needs: me/presence, users/id/presence, getPresencesByUserId, setPresence, setUserPreferredPresence, setStatusMessage
RequestWhat it doesDelegated permissionApplication permission
GET /me/presenceYour own presencePresence.ReadNot available on /me
GET /users/{id}/presenceOne user's presence, by object IDPresence.Read.AllPresence.Read.All
POST /communications/getPresencesByUserIdUp to 650 users per requestPresence.Read.AllPresence.Read.All
POST /users/{id}/presence/setPresenceSet your app's presence session for the userPresence.ReadWritePresence.ReadWrite.All
POST /users/{id}/presence/clearPresenceEnd your app's sessionPresence.ReadWritePresence.ReadWrite.All
POST /users/{id}/presence/setUserPreferredPresenceSet the status the user chosePresence.ReadWritePresence.ReadWrite.All
POST /users/{id}/presence/clearUserPreferredPresenceClear it, like Reset status in TeamsPresence.ReadWritePresence.ReadWrite.All
POST /users/{id}/presence/setStatusMessageSet the status message and its expiryPresence.ReadWritePresence.ReadWrite.All

Two limits from the reference: the read endpoints allow 1,500 requests in 30 seconds per application per tenant, and {id} must be the user's object ID (a GUID), not their email address.

Get presence

GET https://graph.microsoft.com/v1.0/me/presence
Authorization: Bearer {token}

The response:

{
  "id": "fa8bf3dc-eca7-46b7-bad1-db199b62afc3",
  "availability": "Busy",
  "activity": "InAMeeting",
  "statusMessage": null
}

availability is the colour of the dot, and activity is the detail. Teams shows "In a meeting" for Busy plus InAMeeting, and "Presenting" for DoNotDisturb plus Presenting.

The same calls from PowerShell with the Microsoft Graph module:

# PowerShell, Microsoft Graph module (Install-Module Microsoft.Graph)
Connect-MgGraph -Scopes "Presence.Read.All"

# your own status
Invoke-MgGraphRequest -Method GET -Uri "https://graph.microsoft.com/v1.0/me/presence"

# several people at once: object IDs, up to 650 per call
$body = @{ ids = @("fa8bf3dc-eca7-46b7-bad1-db199b62afc3", "66825e03-7ef5-42da-9069-724602c31f6b") }
Invoke-MgGraphRequest -Method POST -Body $body `
  -Uri "https://graph.microsoft.com/v1.0/communications/getPresencesByUserId"

For live updates rather than polling, Graph supports change notifications on the presence resource: subscribe to /communications/presences/{id}, or to several IDs at once, and Graph calls your webhook when the status changes.

How Graph values map to Teams statuses

Never appear "away" on Slack again

Cloud-based. No downloads. Works 24/7 even when your laptop is off.

Teams showsavailabilityactivity
AvailableAvailableAvailable
BusyBusyBusy
In a callBusyInACall
In a meetingBusyInAMeeting
Do not disturbDoNotDisturbDoNotDisturb
PresentingDoNotDisturbPresenting
AwayAwayAway
Be right backBeRightBackBeRightBack
Appear offlineOfflineOffWork
Out of officeOutOfOffice

Set presence: two different methods

setUserPreferredPresence sets the status a user would pick in the Teams menu, and it wins over everything else. The supported pairs are Available, Busy, DoNotDisturb, BeRightBack, Away, and Offline with OffWork (Appear offline). If you leave out expirationDuration, Busy and Do not disturb expire after 1 day and the others after 7 days, the same as in the Teams app.

POST https://graph.microsoft.com/v1.0/users/{user-id}/presence/setUserPreferredPresence
Content-Type: application/json

{
  "availability": "DoNotDisturb",
  "activity": "DoNotDisturb",
  "expirationDuration": "PT8H"
}

It only shows while the user has at least one presence session, meaning a signed-in Teams client or an app session from setPresence. With no session, the user shows Offline whatever you set.

setPresence creates or updates your application's own presence session for the user, next to the sessions from their desktop, web and mobile Teams clients. sessionId must be your app's client ID. Supported pairs: Available/Available, Busy/InACall, Busy/InAConferenceCall, Away/Away, and DoNotDisturb/Presenting. This is how calling and contact-center apps show a user as In a call.

POST https://graph.microsoft.com/v1.0/users/{user-id}/presence/setPresence
Content-Type: application/json

{
  "sessionId": "{your-app-client-id}",
  "availability": "Busy",
  "activity": "InACall",
  "expirationDuration": "PT1H"
}

Neither method can set In a meeting or Out of office. Microsoft says those come from calendar events and automatic replies: to show Out of office, create an event with showAs set to oof or turn on automatic replies through mailboxSettings.

Timeouts, expiration and precedence

What happens to an app presence session set to Available: AvailableInactive after 5 minutes, Away after 10, Offline at expiration

This part causes most "my status reverted" bug reports:

  • • Expiration. An app session lasts for expirationDuration, from 5 minutes to 4 hours (PT5M to PT4H), default 5 minutes. After that the session ends.
  • • Timeout. A session set to Available fades if you do not refresh it: to Available with activity AvailableInactive after 5 minutes, then to Away 5 minutes later. Call setPresence again before each timeout to keep it.
  • • Precedence. A user-preferred status beats every session. Among sessions, DoNotDisturb beats Busy, Busy beats Available, and Available beats Away. So an app cannot show a user as Available while their own Teams client says Busy.
  • • Delay. Teams clients poll, so a change made through Graph can take a few minutes to appear in Teams.

The same rules drive the Teams app itself, which is why a manual Busy seems stuck for a day; see Teams status stuck on Busy.

Set a status message

Never appear "away" on Slack again

Cloud-based. No downloads. Works 24/7 even when your laptop is off.

POST https://graph.microsoft.com/v1.0/users/{user-id}/presence/setStatusMessage
Content-Type: application/json

{
  "statusMessage": {
    "message": { "content": "Heads down until 3 PM", "contentType": "text" },
    "expiryDateTime": { "dateTime": "2026-10-01T15:00:00", "timeZone": "Pacific Standard Time" }
  }
}

The message shows in Teams next to the user's name, and it clears at expiryDateTime. Leave the expiry out to keep it until someone changes it. Tips on wording are in how to set an away message in Teams.

Who can see presence set through Graph

Presence set through Graph is the same presence everyone sees in Teams, including people in other organizations if your admin allows external access. Microsoft's presence guide says cross-tenant presence needs trust on both sides: each organization must allow the other's domain under Users > External access in the Teams admin center.

For how Teams calculates status without any API, see how long before Teams shows Away and Microsoft Teams status icons meaning.

FAQ

Can I get Teams presence by email address? Not directly. Look up the user's object ID first, for example with GET /users/{email}?$select=id, then call the presence endpoint with the ID.

Can I set my Teams status to Available forever with the API? No. A user-preferred Available expires after 7 days by default, and app sessions expire after at most 4 hours and fade to Away if not refreshed.

Does the presence API work with personal Microsoft accounts? No. Every presence endpoint lists personal Microsoft accounts as not supported.

How many users can I read at once? 650 object IDs per getPresencesByUserId request.

Always Active

Stop Jiggling Your Mouse.

Join hundreds of remote workers who never worry about their Slack status. Set it up once, stay green forever.

Related Articles

Guide

Does Slack Notify When You View Someone's Profile? No

No. Opening someone's Slack profile, hovering over their name or checking their status sends them nothing, and Slack has no list of who viewed your profile. Admins cannot see profile views either. What does get noticed: typing in a DM, messages, reactions, mentions and huddles. What a profile shows, and what Slack admins can see instead.

Slack Green Team•5 min read
Guide

Teams: Keep My Current Status When Active Outside of Teams

Keep my current status when I'm active outside of Teams on the web is a Teams web setting under Settings, Notifications and activity, Presence. Turn it on and click Allow, and Teams stops setting you Away while you work in other tabs or apps. It needs Chrome or Edge. What it detects, why it can fail, and what it does not do.

Slack Green Team•5 min read
Guide

Does Teams Notify When You Leave a Chat? No Alert, but a Line

Teams sends no notification when you leave a group chat, but it adds a line to the chat saying you left, which everyone sees the next time they open it. Muting or hiding the chat leaves no trace. What others see for each option, how to leave, and what happens when you leave a team.

Slack Green Team•5 min read