Presence
Check from your server whether users are online, for example to fall back to SMS or email when a user isn't.
curl -X POST "$IM_API/$ORG/$APP/presence/query" \
-H "Authorization: Bearer $APP_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "usernames": ["alice", "bob"] }'A user is online when at least one of their devices holds a long-lived connection to the server (the client SDKs open and keep one after sign-in; devices that only signed in without a connection don't count). The returned presence includes:
| Content | Field |
|---|---|
| Whether they're online | online |
Online platforms, with the same values as the platform reported at sign-in (ios, android, harmony, web, windows, macos, linux, mini_program, other) | platforms |
| When they last went offline, only when offline | last_seen_at |
To learn about users coming online and going offline in real time, subscribe to the presence.changed event callback. It's a best-effort event that can be lost, so rely on this page's queries for important decisions.
- Background counts as online: a mobile app in the background is still online while its connection is up. These APIs don't distinguish foreground from background.
- Going offline is detected with a delay: users become offline immediately when they sign out or close the connection normally; when a device loses its network abruptly, the server only notices after the connection idles out (90 seconds in the foreground, 360 in the background by default) and shows them online until then. When switching networks, the new connection replaces the old one, so there's no "offline then online".
- Retention: last-seen times are kept for 30 days; users not online in 30 days have
last_seen_atnullandversion0.
How the runtime policy relates
Presence settings in the runtime policy only limit clients (users viewing each other's presence) and don't apply to these APIs: the server can always query any user and see last-seen times:
| Policy | Default | Effect on clients |
|---|---|---|
presence_enabled | Off | Clients can only query and subscribe to others' presence when it's on |
presence_scope | friends | Whose presence clients can see: friends only friends, all any user in the app |
presence_last_seen_visible | On | When off, clients only see whether someone is online, not when they were last seen |
For how to set them, see Runtime policy.
Query presence in batches
Query presence for up to 100 users at once. It counts as one call however many users you query.
/{org_name}/{app_name}/presence/queryPath parameters
For org_name and app_name, see the server overview.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
usernames | Array<String> | Yes | Usernames to query, 1 to 100. Case-insensitive; duplicates are returned once |
Request example
curl -X POST "$IM_API/$ORG/$APP/presence/query" \
-H "Authorization: Bearer $APP_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"usernames": ["alice", "bob", "carol", "nobody"]
}'Response
On success you get 200 OK, with each item in items a presence object in request order; nonexistent or deleted users are left out.
{
"items": [
{
"username": "alice",
"online": true,
"platforms": ["ios", "windows"],
"last_seen_at": null,
"version": 1790968803807
},
{
"username": "bob",
"online": false,
"platforms": [],
"last_seen_at": "2026-10-02T19:12:04.903Z",
"version": 1790968324903
},
{
"username": "carol",
"online": false,
"platforms": [],
"last_seen_at": null,
"version": 0
}
]
}In the example, alice is online on iOS and Windows, bob is offline, and carol has never been online.
Errors
| HTTP status | code | Description |
|---|---|---|
| 400 | invalid_argument | usernames is empty or has more than 100 entries; details.field is usernames |
| 500 | internal | details.reason dependency_unavailable: the presence service is temporarily unavailable; wait for the Retry-After header and retry |
Get a user's presence
Get one user's presence.
/{org_name}/{app_name}/users/{username}/presencePath parameters
For org_name and app_name, see the server overview.
| Parameter | Type | Description |
|---|---|---|
username | String | The username, case-insensitive |
Request example
curl "$IM_API/$ORG/$APP/users/alice/presence" \
-H "Authorization: Bearer $APP_TOKEN"Response
On success you get 200 OK with a presence object.
{
"username": "alice",
"online": true,
"platforms": ["ios", "windows"],
"last_seen_at": null,
"version": 1790968803807
}This API only returns online platforms, not per-device info. For which devices a user is signed in on, see List devices (signed in isn't the same as online); each connection's platform, foreground or background state, IP and connection time can be seen in the user details in the console.
Errors
| HTTP status | code | Description |
|---|---|---|
| 404 | not_found | The user doesn't exist or was deleted |
| 500 | internal | details.reason dependency_unavailable: the presence service is temporarily unavailable; wait for the Retry-After header and retry |
Data structures
Presence object
| Field | Type | Description |
|---|---|---|
username | String | The username |
online | Boolean | Whether online: at least one device holds a long-lived connection (devices in the background included) |
platforms | Array<String> | Online platforms, sorted alphabetically, each listed once even with several devices; empty when offline |
last_seen_at | String | When they last went offline. null while online, and for users not online in 30 days |
version | Number | Presence version, increasing on every change (online, offline, platforms added or removed), so you can tell whether anything changed between queries and discard older results. 0 for users never online or unchanged for 30 days |
{
"username": "bob",
"online": false,
"platforms": [],
"last_seen_at": "2026-10-02T19:12:04.903Z",
"version": 1790968324903
}