- The auditLogs/signIns API does not support server-side “distinct” aggregation on location (city/state/country). The supported query options are
$top, $skiptoken, and $filter, and the guidance is to filter primarily by time range to avoid timeouts.
To constrain data volume for a 90‑day window, apply a time-based filter and then de-duplicate on the client:
GET https://graph.microsoft.com/v1.0/auditLogs/signIns
?$filter=createdDateTime ge 2024-01-01T00:00:00Z and createdDateTime le 2024-03-31T23:59:59Z
Then, for each signIn record, use the location object (of type signInLocation) and aggregate distinct combinations of city, state, and countryOrRegion client-side.
The signInLocation resource provides exactly the fields needed:
-
city
-
state
-
countryOrRegion
-
geoCoordinates
There is no documented way to push this distinct/aggregation logic into the Microsoft Graph sign-ins endpoint itself.
- Alternative approaches are limited in terms of getting distinct locations directly from an API, but there are two main patterns:
- Continue using Microsoft Graph sign-ins with better filtering and paging:
- Use
$filter on createdDateTime to restrict to the last 90 days.
- Use
$top and follow @odata.nextLink to page through results.
- Aggregate and rank locations (e.g., by count) in the application.
- Use Azure Monitor / Log Analytics if sign-in logs are streamed there:
- When sign-in logs are replicated to Azure Monitor, Kusto queries can perform server-side aggregation and distinct operations. For example, the
AADNonInteractiveUserSignInLogs table can be queried for patterns like “users with multiple cities” or “most active IP addresses” using KQL.
- A similar KQL query can be written to summarize sign-ins by
LocationDetails (city/country) for a given user and time range, then return the top locations. This offloads aggregation from the client to the log analytics backend.
For UX scenarios that must show “top sign-in locations” efficiently, routing sign-in logs to Azure Monitor / Log Analytics and querying with KQL is the most scalable way to get pre-aggregated, distinct locations for a user over a time window.
References: