Microsoft Graph
Microsoft Graph is a unified REST API that exposes data and functionality across Microsoft cloud services. Instead of calling separate APIs for Entra ID, Outlook, Teams, SharePoint, Intune, and dozens of other services, you call one endpoint:
https://graph.microsoft.com
Graph is the primary way builders programmatically interact with the Microsoft cloud. If you are automating anything in Microsoft 365 or Entra, you are almost certainly calling Graph.
What Graph Exposes
Graph organizes Microsoft cloud data as a connected graph of resources. Common resource types include:
| Area | Resources |
|---|---|
| Identity | Users, groups, applications, service principals, directory roles |
| Communication | Mail, calendars, contacts, Teams channels, chat messages |
| Files | OneDrive files, SharePoint sites and lists |
| Devices | Managed devices, compliance policies (via Intune) |
| Security | Alerts, secure scores, threat indicators |
| Organization | Licenses, subscriptions, domains, administrative units |
Resources are addressable by consistent URL patterns: /users/{id}, /groups/{id}/members, /applications/{id}.
How It Fits Together
flowchart TB
App["Your Application"]
MsGraph["Microsoft Graph\ngraph.microsoft.com"]
App -->|"REST calls"| MsGraph
MsGraph --- EntraID["Entra ID"]
MsGraph --- Outlook["Outlook / Exchange"]
MsGraph --- Teams["Teams"]
MsGraph --- SharePoint["SharePoint\n& OneDrive"]
MsGraph --- Intune["Intune"]
MsGraph --- Security["Security\nServices"]
style MsGraph fill:#4A90D9,color:#fff
Graph acts as the unified API layer. Each underlying service maintains its own data and logic; Graph provides the consistent interface over all of them.
Key Patterns
OData Queries
Graph supports OData query parameters for filtering, selecting, ordering, and paging:
GET /users?$filter=department eq 'Engineering'&$select=displayName,mail&$top=50
Common parameters: $filter, $select, $top, $skip, $orderby, $count, $expand, $search. Not all parameters work on all endpoints; check the docs for specific resources.
Delta Queries
Track changes to resources over time without polling for the full dataset:
GET /users/delta?$select=displayName,mail
Returns a @odata.deltaLink you store and re-use on the next call to get only what changed. This is the efficient way to keep local state in sync with Graph data.
Webhooks (Change Notifications)
Subscribe to real-time notifications when resources change:
POST /subscriptions
{
"changeType": "created,updated",
"notificationUrl": "https://your-app.com/webhook",
"resource": "users",
"expirationDateTime": "2026-12-01T00:00:00Z"
}
Graph sends POST requests to your endpoint when matching changes occur. Subscriptions expire and need renewal.
Batch Requests
Combine multiple Graph calls into a single HTTP request:
POST /$batch
{
"requests": [
{ "id": "1", "method": "GET", "url": "/users/user1-id" },
{ "id": "2", "method": "GET", "url": "/groups/group1-id/members" }
]
}
Useful for reducing round trips. Supports up to 20 requests per batch.
Graph Data Connect
For bulk, recurring data exports (millions of records), Graph Data Connect pipes Microsoft 365 data into Azure Data Factory pipelines and Azure storage. This is for analytics at scale, not for interactive API calls.
API Versions
- v1.0: Stable, production-ready. Use this by default.
- beta: Preview features and newer endpoints. May change without notice. Fine for development and testing; avoid in production unless you accept the risk.
https://graph.microsoft.com/v1.0/users
https://graph.microsoft.com/beta/users
Authentication
Graph uses the Microsoft identity platform (OAuth 2.0) for authentication. Two main flows:
Delegated permissions (user context). Your app acts on behalf of a signed-in user. The effective permissions are the intersection of what the app is granted and what the user can do.
Application permissions (app-only context). Your app acts as itself with no signed-in user. Common for background services, daemons, and automation. Requires admin consent.
Both flows produce an access token you send as a Bearer token:
Authorization: Bearer eyJ0eXAiOiJKV1Qi...
Permissions are granular: User.Read, Group.ReadWrite.All, Mail.Send, etc. Follow least privilege; request only what you need.
SDKs and Tooling
Microsoft provides Graph SDKs for C#, JavaScript/TypeScript, Java, Python, Go, PHP, and PowerShell. The SDKs handle authentication, retries, pagination, and serialization.
Graph Explorer (developer.microsoft.com/graph/graph-explorer) lets you run queries interactively against your own tenant or sample data.
When To Use Graph vs. Direct Service APIs
Graph is the right default for most scenarios. Consider direct service APIs when:
- You need functionality that Graph does not yet expose
- You need Azure Resource Manager (ARM) operations (Graph covers Microsoft 365 and Entra, not Azure resource provisioning)
- Performance-critical paths need lower-level control than Graph’s abstraction allows
In Entra-Adjacent Systems
Graph is the primary API surface for Entra ID operations. Common uses:
- User and group lifecycle: creating, updating, and deleting users and groups; managing membership
- Application management: registering apps, managing credentials, configuring permissions
- Provisioning automation: monitoring provisioning job status, reading audit logs, reconciling state
- Policy and governance: reading conditional access policies, access reviews, entitlement management configuration
- Delta sync: using delta queries to track directory changes efficiently, driving downstream automation
A typical pattern: a scheduled Azure Function calls Graph delta queries to detect changes, then enqueues follow-up work in Service Bus or stores state in Cosmos DB. Graph starts the flow; platform infrastructure carries it.
For deeper Entra-specific topics, see:
- Entra Connect Sync for hybrid sync internals.
- Entra Cloud Sync for the cloud-managed sync model.
- Entra Application Provisioning for SCIM and provisioning-engine behavior.