A reference guide for building AI agents: every method, how to authenticate, and the permissions each one needs.
The Microsoft Entra ID API is how an app or AI agent works with an organization's directory: listing and creating users, adding and removing group members, registering applications, reading the sign-in logs, and assigning directory roles. Access is granted through an OAuth 2.0 token and a set of Graph permissions, where a delegated token is also bounded by the signed-in user's own roles and an app-only token applies across the tenant. Microsoft Entra ID can also push directory changes to a subscription instead of being polled.
How an app or AI agent connects to Microsoft Entra ID determines what it can reach. Access runs through Microsoft Graph, governed by an OAuth 2.0 token and the Graph permissions that token carries.
Microsoft Entra ID is reached through Microsoft Graph at https://graph.microsoft.com. The stable endpoint is /v1.0 and a separate /beta endpoint carries preview features that should not be used in production. A call authenticates with an OAuth 2.0 bearer token.
An app creates a subscription on a resource like users or groups, and Microsoft Graph POSTs a lightweight notification to a registered URL when a matching object is created, updated, or deleted. The receiver validates a token Graph sends on setup and can request encrypted resource data.
Microsoft's first-party MCP server at https://mcp.svc.cloud.microsoft/enterprise lets an AI agent query Microsoft Entra data in natural language. It is in public preview and covers read-only identity scenarios across users, groups, applications, and devices, exposing the tools microsoft_graph_suggest_queries, microsoft_graph_get, and microsoft_graph_list_properties. It honors the user's roles and the granted Graph scopes, and is limited to 100 calls per minute per user.
An app authenticates as itself with a client secret or certificate and acts with application permissions, which are app roles granted by an administrator and apply tenant-wide with no signed-in user. This is the route for unattended automation and background agents.
A user signs in and consents, and the app acts on their behalf with delegated permissions. The effective access is the overlap of the granted scope and what the signed-in user is allowed to do, so a delegated call is also bounded by the user's directory roles.
An Azure-hosted workload gets an identity managed by the platform and acquires Graph tokens without a stored secret. It uses application permissions like the client credentials flow, with the credential handled by Azure rather than the app.
The Microsoft Entra ID API is split into areas an agent can act on, like users, groups, applications, service principals, directory roles, and sign-in logs. Each area has its own methods and its own Graph permissions, and writes in some areas change who can sign in or what they can reach.
List, read, create, update, and delete users in the directory.
List, read, create, update, and delete groups, and add, list, and remove their members.
List, read, create, update, and delete the app registrations in the directory.
List, read, and create service principals, and list and grant app role assignments on them.
List and read activated directory roles, list their members, and add a member to a role.
Read the sign-in logs and the directory audit logs for the tenant.
List and read the conditional access policies configured in the tenant.
Filter by method, access, or permission, or search any path. Select a row for version detail, rate limits, the related webhook event, and the source.
| Method | Endpoint | What it does | Access | Permission | Version | |
|---|---|---|---|---|---|---|
UsersList, read, create, update, and delete users in the directory.5 | ||||||
| GET | /users | List the users in the organization. | read | User.Read.All | Current | |
User.Read.All is the least-privilege permission to read every user's full profile; User.ReadBasic.All reads only a limited basic profile. Works as either a delegated permission (acting as a signed-in admin) or an application permission (acting as the app itself). A guest signed-in user cannot query the whole /users collection. Acts onuser Permission (capability) User.Read.AllVersionAvailable since the API’s base version Webhook event user-changedRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /users/{id} | Get a single user by ID or userPrincipalName. | read | User.Read.All | Current | |
A signed-in user reading their own profile needs only User.Read. Reading another user's full profile needs User.Read.All, delegated or application. Acts onuser Permission (capability) User.Read.AllVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /users | Create a new user in the directory. | write | User.ReadWrite.All | Current | |
Creating a user needs User.ReadWrite.All. In a delegated call the signed-in user must also hold a Microsoft Entra role such as User Administrator. Acts onuser Permission (capability) User.ReadWrite.AllVersionAvailable since the API’s base version Webhook event user-changedRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PATCH | /users/{id} | Update a user's properties. | write | User.ReadWrite.All | Current | |
Some fields are sensitive, like accountEnabled, userPrincipalName, and passwordProfile, and only specific administrator roles can change them in a delegated call. A signed-in user updating their own basic profile needs only User.ReadWrite. Acts onuser Permission (capability) User.ReadWrite.AllVersionAvailable since the API’s base version Webhook event user-changedRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| DELETE | /users/{id} | Delete a user from the directory. | write | User.ReadWrite.All | Current | |
A deleted user moves to the recycle bin and can be restored within 30 days. Deleting a user is a sensitive action restricted to specific administrator roles in delegated calls. Acts onuser Permission (capability) User.ReadWrite.AllVersionAvailable since the API’s base version Webhook event user-changedRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
GroupsList, read, create, update, and delete groups, and add, list, and remove their members.8 | ||||||
| GET | /groups | List the groups in the organization. | read | Group.Read.All | Current | |
Group.Read.All reads every group. Delegated or application. A guest signed-in user cannot query the whole /groups collection. Acts ongroup Permission (capability) Group.Read.AllVersionAvailable since the API’s base version Webhook event group-changedRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /groups/{id} | Get a single group by ID. | read | Group.Read.All | Current | |
Reads one group's properties. Delegated or application. Acts ongroup Permission (capability) Group.Read.AllVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /groups | Create a security group or Microsoft 365 group. | write | Group.ReadWrite.All | Current | |
All group-related writes need administrator consent. Dynamic membership rules need a Microsoft Entra ID P1 license per member. Acts ongroup Permission (capability) Group.ReadWrite.AllVersionAvailable since the API’s base version Webhook event group-changedRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PATCH | /groups/{id} | Update a group's properties. | write | Group.ReadWrite.All | Current | |
The same PATCH on the group can add up to 20 members at once through members@odata.bind. Acts ongroup Permission (capability) Group.ReadWrite.AllVersionAvailable since the API’s base version Webhook event group-changedRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| DELETE | /groups/{id} | Delete a group from the directory. | write | Group.ReadWrite.All | Current | |
A deleted Microsoft 365 group can be restored within 30 days; security groups are removed permanently. Acts ongroup Permission (capability) Group.ReadWrite.AllVersionAvailable since the API’s base version Webhook event group-changedRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /groups/{id}/members | List the direct members of a group. | read | GroupMember.Read.All | Current | |
GroupMember.Read.All is the least-privilege permission to read membership; Group.Read.All also works. Delegated or application. Acts ongroup member Permission (capability) GroupMember.Read.AllVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /groups/{id}/members/$ref | Add a member to a security or Microsoft 365 group. | write | GroupMember.ReadWrite.All | Current | |
Adding a service principal member also needs Application.ReadWrite.All; adding a member to a role-assignable group also needs RoleManagement.ReadWrite.Directory. Up to 20 members can be added in one request through the PATCH form. Acts ongroup member Permission (capability) GroupMember.ReadWrite.AllVersionAvailable since the API’s base version Webhook event group-changedRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| DELETE | /groups/{id}/members/{memberId}/$ref | Remove a member from a group. | write | GroupMember.ReadWrite.All | Current | |
Removing a member can revoke that principal's access to resources the group grants. Acts ongroup member Permission (capability) GroupMember.ReadWrite.AllVersionAvailable since the API’s base version Webhook event group-changedRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
ApplicationsList, read, create, update, and delete the app registrations in the directory.5 | ||||||
| GET | /applications | List the application registrations in the organization. | read | Application.Read.All | Current | |
Reads the app registrations. Delegated or application. Acts onapplication Permission (capability) Application.Read.AllVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /applications/{id} | Get a single application registration by ID. | read | Application.Read.All | Current | |
The appId property is a supported alternate key, so an app can also be addressed by its application (client) ID. Acts onapplication Permission (capability) Application.Read.AllVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /applications | Create (register) a new application. | write | Application.ReadWrite.All | Current | |
Registering an app defines what it can request and how it authenticates, so this write is sensitive. Acts onapplication Permission (capability) Application.ReadWrite.AllVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PATCH | /applications/{id} | Update an application registration's properties. | write | Application.ReadWrite.All | Current | |
Changing requiredResourceAccess here changes which permissions the app asks for. Acts onapplication Permission (capability) Application.ReadWrite.AllVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| DELETE | /applications/{id} | Delete an application registration. | write | Application.ReadWrite.All | Current | |
A deleted application can be restored within 30 days from the directory recycle bin. Acts onapplication Permission (capability) Application.ReadWrite.AllVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Service principalsList, read, and create service principals, and list and grant app role assignments on them.5 | ||||||
| GET | /servicePrincipals | List the service principals in the organization. | read | Application.Read.All | Current | |
A service principal is the local instance of an application or managed identity in this tenant. Delegated or application. Acts onservice principal Permission (capability) Application.Read.AllVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /servicePrincipals/{id} | Get a single service principal by ID. | read | Application.Read.All | Current | |
Can also be addressed by appId as an alternate key. Acts onservice principal Permission (capability) Application.Read.AllVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /servicePrincipals | Create a service principal for an application. | write | Application.ReadWrite.All | Current | |
Creating a service principal makes an application usable in this tenant. Acts onservice principal Permission (capability) Application.ReadWrite.AllVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /servicePrincipals/{id}/appRoleAssignedTo | List the users, groups, and service principals assigned app roles on this service principal. | read | Application.Read.All | Current | |
Shows who has been granted access to this app or service. Delegated or application. Acts onapp role assignment Permission (capability) Application.Read.AllVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /servicePrincipals/{id}/appRoleAssignedTo | Assign an app role on this service principal to a user, group, or service principal. | write | AppRoleAssignment.ReadWrite.All | Current | |
Also needs Application.Read.All. Granting an app role to a service principal is how application permissions are granted, so this write can give an app broad access to the directory. Acts onapp role assignment Permission (capability) AppRoleAssignment.ReadWrite.AllVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Directory rolesList and read activated directory roles, list their members, and add a member to a role.4 | ||||||
| GET | /directoryRoles | List the directory roles that are activated in the tenant. | read | RoleManagement.Read.Directory | Current | |
Only activated roles are listed; a role must be activated from its template before it can be read or have members. Delegated or application. Acts ondirectory role Permission (capability) RoleManagement.Read.DirectoryVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /directoryRoles/{id}/members | List the members of a directory role. | read | RoleManagement.Read.Directory | Current | |
Shows which users hold an administrative role, like Global Administrator. Delegated or application. Acts ondirectory role Permission (capability) RoleManagement.Read.DirectoryVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /directoryRoles/{id}/members/$ref | Add a user as a member of a directory role. | write | RoleManagement.ReadWrite.Directory | Current | |
Adding a member grants that user the role's administrative privileges over the directory. Microsoft recommends the unified RBAC API for new work. Acts ondirectory role Permission (capability) RoleManagement.ReadWrite.DirectoryVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /directoryRoles | Activate a directory role from its role template in the tenant. | write | RoleManagement.ReadWrite.Directory | Current | |
Only the Company Administrators role is active by default; other roles must be activated with the roleTemplateId before they can be read or assigned. Acts ondirectory role Permission (capability) RoleManagement.ReadWrite.DirectoryVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Sign-in & audit logsRead the sign-in logs and the directory audit logs for the tenant.2 | ||||||
| GET | /auditLogs/signIns | List the Microsoft Entra user sign-ins for the tenant. | read | AuditLog.Read.All | Current | |
AuditLog.Read.All is the only supported permission, delegated or application. Reading the applied conditional access policies on a sign-in also needs Policy.Read.All. Only events within the default retention window are returned, and a time-range $filter is recommended. Acts onsign-in Permission (capability) AuditLog.Read.AllVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /auditLogs/directoryAudits | List the directory audit events for the tenant, such as who changed what. | read | AuditLog.Read.All | Current | |
Records directory changes like role assignments and group edits. Delegated or application; AuditLog.Read.All. Acts onaudit event Permission (capability) AuditLog.Read.AllVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Conditional access policiesList and read the conditional access policies configured in the tenant.2 | ||||||
| GET | /identity/conditionalAccess/policies | List the conditional access policies configured in the tenant. | read | Policy.Read.All | Current | |
Policy.Read.All is the least-privilege permission, delegated or application. These policies decide who can sign in and under what conditions, like requiring multifactor authentication. Acts onconditional access policy Permission (capability) Policy.Read.AllVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /identity/conditionalAccess/policies/{id} | Get a single conditional access policy by ID. | read | Policy.Read.All | Current | |
Reads one policy's full conditions and grant controls. Delegated or application. Acts onconditional access policy Permission (capability) Policy.Read.AllVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Microsoft Entra ID can notify an app or AI agent when a directory object changes, like a user or group being created or updated, instead of the app repeatedly asking. A change-notification subscription sends a lightweight message to a registered URL when the chosen resource changes.
| Event | What it signals | Triggered by |
|---|---|---|
users (created / updated / deleted) | Fires when a user object is created, updated, or deleted, for an app subscribed to the users resource through change notifications. | /users/users/users/{id}/users/{id} |
groups (created / updated / deleted) | Fires when a group is created, updated, or deleted, including membership changes, for an app subscribed to the groups resource through change notifications. | /groups/groups/groups/{id}/groups/{id}/groups/{id}/members/$ref/groups/{id}/members/{memberId}/$ref |
Microsoft Graph limits how fast an app or AI agent can call, through throttling that varies by service and by whether the call reads or writes, and it returns a wait time when a client goes over.
Microsoft Graph protects the service with throttling rather than a fixed published request budget, and the threshold varies by scenario, so a high volume of writes is throttled sooner than reads. Limits apply both per app across a single tenant and per app across all tenants, and a tenant-wide ceiling counts requests from every app together. When a threshold is crossed, Graph returns HTTP 429 Too Many Requests with a Retry-After header giving the seconds to wait. Requests inside a JSON batch are each metered separately, so one entry can be throttled while the batch itself returns 200. Service-specific numbers are published per workload, and large bulk extraction should use Microsoft Graph Data Connect instead of the REST API.
List responses are paged. A page that has more results includes an @odata.nextLink property holding the full URL for the next page, which should be followed as given rather than built by hand, until no nextLink is returned. The page size is controlled with $top where the endpoint supports it. The sign-in logs default and cap each page at 1,000 objects and page through a $skiptoken carried on the nextLink.
Adding members to a group is capped at 20 per request through the members@odata.bind form. Sign-in and audit log reads are bounded by the Microsoft Entra retention window for that data rather than by a single payload size. Some user and group properties, like skills and allowExternalSenders, are stored outside the main directory and are not returned by default or tracked by change notifications.
The status codes an agent should handle, and what to do about each.
| Status | Code | Meaning | What to do |
|---|---|---|---|
| 400 | badRequest / invalidRequest | The request is malformed or a property is invalid, like a missing required field or a member that is already in the group. A recently created group can also return this while it replicates across directory replicas. | Read the error message, fix the request, and for the replication case wait a few seconds and retry. |
| 401 | InvalidAuthenticationToken | The access token is missing, expired, or invalid. | Acquire a fresh token and send it in the Authorization header as a bearer token. |
| 403 | Authorization_RequestDenied | The token is valid but lacks the permission the call needs, or in a delegated call the signed-in user lacks the required Microsoft Entra role. | Grant the missing Graph permission, get admin consent, or assign the signed-in user the required directory role. |
| 404 | Request_ResourceNotFound | The object does not exist, or the token cannot see it. | Confirm the ID is correct and the caller has access to the resource. |
| 429 | TooManyRequests | A throttling threshold was exceeded. Microsoft Graph returns 429 with a Retry-After header giving the seconds to wait, and the error code TooManyRequests with an innerError of 429. | Wait the number of seconds in the Retry-After header, then retry; if no header is present, back off exponentially. |
| 503 | serviceNotAvailable | The service is temporarily unavailable, which can also appear as a throttling response and may include a Retry-After header. | Honor the Retry-After header if present, otherwise retry with exponential backoff. |
Microsoft Graph serves Microsoft Entra ID through two named endpoints, the stable v1.0 used here and a separate beta, rather than dated version strings. New and changed methods are tracked through a dated changelog.
Microsoft Entra ID is served through Microsoft Graph at the named v1.0 endpoint, the stable surface for production. A separate beta endpoint carries preview features that can change or be removed and should not be used in production. Rather than minting dated versions, Microsoft Graph announces new and changed methods through a dated changelog, and breaking changes follow a published deprecation and retirement policy.
Microsoft Graph supersedes the older Azure AD Graph API, which has been retired, and Azure Active Directory was renamed Microsoft Entra ID. New integrations use Microsoft Graph at graph.microsoft.com with Microsoft Graph permission names.
An integration calls the v1.0 endpoint for production and beta only for previews.
Microsoft Graph changelog ↗Bollard AI sits between a team's AI agents and Microsoft Entra ID. Grant each agent exactly the access it needs, read or write, resource by resource, and every call is checked and logged.