Skip to main content

Presence

Reading presence needs Presence.Read.All. Writing it needs Presence.ReadWrite, which is in the default delegated scope set — if you signed in before it was added, run teams auth login again to consent to it. The write commands act on /me, so they are delegated-only and reject an app-only token before sending anything.

Read​

Read your own presence:

teams presence get --output json

Read another user:

teams presence get --user "$USER_ID" --output json

Read several at once:

teams presence get-batch --user-ids "$USER_ID_1,$USER_ID_2" --output json

Your own presence carries two fields the others do not. Microsoft Graph only returns statusMessage.expiryDateTime and statusMessage.publishedDateTime for /me/presence; a lookup of another user omits them.

{
"availability": "Away",
"activity": "Away",
"statusMessage": {
"message": { "content": "Back on Monday", "contentType": "text" },
"publishedDateTime": "2026-08-27T09:14:22.9411568Z",
"expiryDateTime": { "dateTime": "2026-09-01T08:00:00.0000000", "timeZone": "UTC" }
}
}

expiryDateTime is an object with dateTime and timeZone, not a string.

Set​

Microsoft Graph accepts exactly five --availability/--activity pairs:

--availability--activity
AvailableAvailable
BusyInACall
BusyInAConferenceCall
AwayAway
DoNotDisturbPresenting

Values such as Offline and InAMeeting appear when reading someone's presence but are not accepted by presence set.

teams presence set --availability Busy --activity InACall --expiration PT1H --output json

--expiration is an ISO 8601 duration between PT5M and PT4H, checked locally before the request is sent — an out-of-range or malformed value fails as invalid input (exit 2) rather than costing a round trip. Leaving it out applies Graph's own five-minute default, so a presence set this way lapses on its own either way. An agent that sets Available and then dies does not leave a green light behind indefinitely.

Status message​

teams presence status --message "In deep focus" --output json
teams presence status --message "Back Monday" --expiry "2026-09-01T08:00:00" --output json

Clear​

teams presence clear --output json

Graph keys a presence session to the application that opened it, so set and clear both send that application's ID as the session ID — a configured client_id when there is one, otherwise the application claim on the access token itself. Both commands report the value back, so a clear run under different configuration than the set is visible rather than silent.

clear succeeds whether or not a session was open, and says which happened:

statusMeaning
presence_clearedGraph closed an application presence session.
no_presence_sessionGraph knew of no session under that ID. Also what a retry sees when the attempt before it succeeded but its response was lost.

Clearing reverts presence to whatever Teams calculates automatically — unless a preferred presence is set, which outranks every session. See below.

Preferred presence​

Microsoft Graph keeps two writable layers. presence set opens an application presence session, which Teams weighs against your calendar and activity. Above every session sits the user-preferred presence — the layer the Teams client writes when you pick a status from the menu, including Appear offline. presence set cannot reach it, which is why a set on an account that is appearing offline returns success while the account stays offline.

teams presence set-preferred --availability Away --output json
teams presence set-preferred --availability Offline --expiration P1D --output json
teams presence clear-preferred --output json

Each of the six availabilities Graph accepts here has exactly one activity, so the command derives it and reports both back:

--availabilityActivity
AvailableAvailable
BusyBusy
DoNotDisturbDoNotDisturb
BeRightBackBeRightBack
AwayAway
OfflineOffWork

--expiration is an ISO 8601 duration in whole day, hour, minute or second units, such as P1D, PT8H or PT30M. It is checked for shape locally but not bounded, because Graph documents defaults rather than a range: one day for Busy and DoNotDisturb, seven days for the rest. Leaving it out applies that default.

set-preferred answers with status: preferred_presence_set plus the availability, activity and expiration it sent. clear-preferred answers with status: preferred_presence_cleared and takes no session ID, because the preferred presence belongs to the user rather than to an application. Clearing it hands control back to Teams' own calculation and to any application session still open.

Both commands need Presence.ReadWrite, the same scope as presence set, and both are delegated-only.