Source profileQuality 94/100

WYRE-AI/msp-claude-plugins/msp-claude-plugins/m365/m365/skills/api-patterns/SKILL.md

Microsoft 365 API Patterns

Microsoft Graph fundamentals shared by every M365 skill: Entra token scopes and the per-request Bearer model, OData query operators and filter syntax, @odata.nextLink pagination, delta queries for incremental sync, 429 throttling and retry behavior, JSON batching, and the common Graph error codes.

Source repository stars
42
Declared platforms
0
Static risk flags
1
Last source update
2026-08-28
Source checked
2026-08-28

Decision brief

What it does: where it fits

Microsoft Graph fundamentals shared by every M365 skill: Entra token scopes and the per-request Bearer model, OData query operators and filter syntax, @odata. nextLink pagination, delta queries for incremental sync, 429 throttling and retry behavior, JSON batching, and the common Graph error codes.

Best for

    Not for

    • Tasks that require unconfirmed production actions or broad system permissions.
    • Environments where the pinned source and install steps cannot be inspected.

    Compatibility matrix

    Platform support, with evidence labels

    PlatformStatusEvidenceWhat to check
    CodexNot declaredNo explicit evidencePortability before use
    Claude CodeNot declaredNo explicit evidencePortability before use
    CursorNot declaredNo explicit evidencePortability before use
    Gemini CLINot declaredNo explicit evidencePortability before use
    Open the compatibility checker

    Installation

    Inspect first. Install second.

    The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.

    Source-detected install commandSource
    npx skills add https://github.com/WYRE-AI/msp-claude-plugins --skill "msp-claude-plugins/m365/m365/skills/api-patterns"
    Safe inspection promptEditorial

    Inspect the Agent Skill "Microsoft 365 API Patterns" from https://github.com/WYRE-AI/msp-claude-plugins/blob/5005f73ba2f52cd299f58aa6bb79f4e70ae87103/msp-claude-plugins/m365/m365/skills/api-patterns/SKILL.md at commit 5005f73ba2f52cd299f58aa6bb79f4e70ae87103. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.

    Workflow

    What the source asks the agent to do

    1. 01

      Anti-triggers

      This skill teaches you to compose Graph calls by hand. Two neighbouring plugins cover the same tenant with almost identical vocabulary, and choosing the wrong one is the most common routing mistake in the Microsoft estate:

      A read-only question about one tenant — "how many users", "whoAnything spanning more than one customer tenant — fleet-wideA tenant that authenticates but returns nothing — that is an app
    2. 02

      Authentication

      The Softeria MS-365 MCP server (--org-mode) accepts a Bearer token per request via the Authorization header. The token must be obtained from Microsoft Entra using the common endpoint (multi-tenant) with the following scopes:

      The Softeria MS-365 MCP server (--org-mode) accepts a Bearer token per request via the Authorization header. The token must be obtained from Microsoft Entra using the common endpoint (multi-tenant) with the following sc…All Graph API calls use:Beta features (preview, subject to change):
    3. 03

      Token Scope for MSP Operations

      The Softeria MS-365 MCP server (--org-mode) accepts a Bearer token per request via the Authorization header. The token must be obtained from Microsoft Entra using the common endpoint (multi-tenant) with the following scopes:

      The Softeria MS-365 MCP server (--org-mode) accepts a Bearer token per request via the Authorization header. The token must be obtained from Microsoft Entra using the common endpoint (multi-tenant) with the following sc…
    4. 04

      Base URL

      All Graph API calls use:

      All Graph API calls use:Beta features (preview, subject to change):
    5. 05

      OData Query Parameters

      Some filters require the ConsistencyLevel: eventual header and $count=true:

      Some filters require the ConsistencyLevel: eventual header and $count=true:

    Permission review

    Static risk signals and limitations

    Network access

    medium · line 49

    The documentation includes network, browsing, or remote request actions.

    https://graph.microsoft.com/v1.0/

    Network access

    medium · line 54

    The documentation includes network, browsing, or remote request actions.

    https://graph.microsoft.com/beta/

    Evidence record

    Why each signal appears

    EvidenceSourceComputedTestedEditorial
    SignalValueEvidence typeMeaning
    Quality score94/100ComputedDocumentation, specificity, maintenance, and trust rules
    Repository stars42SourceRepository attention, not individual Skill quality
    Compatibility0 platformsSourceDeclared in the catalog source record
    Usage guideautomated source guideEditorialGenerated or reviewed according to the visible evidence level

    Pinned source

    Provenance and original SKILL.md

    Repository
    WYRE-AI/msp-claude-plugins
    Skill path
    msp-claude-plugins/m365/m365/skills/api-patterns/SKILL.md
    Commit
    5005f73ba2f52cd299f58aa6bb79f4e70ae87103
    License
    Apache-2.0
    Collected
    2026-08-28
    Default branch
    main
    View the original SKILL.md

    Microsoft Graph API Patterns

    Overview

    Microsoft Graph is the unified REST API surface for all M365 services (users, mail, calendar, Teams, OneDrive, security). All M365 MCP tools ultimately make Graph calls. Understanding Graph's OData query syntax, pagination model, throttling behavior, and auth patterns is essential for building reliable M365 workflows.

    Anti-triggers

    This skill teaches you to compose Graph calls by hand. Two neighbouring plugins cover the same tenant with almost identical vocabulary, and choosing the wrong one is the most common routing mistake in the Microsoft estate:

    • A read-only question about one tenant — "how many users", "who has no MFA registered", "which licences are unassigned". The Graph Enterprise MCP answers these from a vetted query catalogue, so nobody hand-writes a $filter; use the microsoft-graph plugin's microsoft-graph-querying skill. Hand-writing a Graph URL when that server is connected is the exact error pattern it exists to prevent.
    • Anything spanning more than one customer tenant — fleet-wide standards, BPA drift, GDAP, or a packaged action such as offboard / reset MFA / revoke sessions. Use the cipp plugin, which carries the multi-tenant scope and per-tenant audit trail this plugin does not.
    • A tenant that authenticates but returns nothing — that is an app registration and admin-consent problem, not a query-syntax problem; use microsoft-graph-connection.

    The short rule: ask one tenant → microsoft-graph; change one tenant → this plugin; do either across the fleet → cipp.

    Authentication

    Token Scope for MSP Operations

    The Softeria MS-365 MCP server (--org-mode) accepts a Bearer token per request via the Authorization header. The token must be obtained from Microsoft Entra using the common endpoint (multi-tenant) with the following scopes:

    ScopePurpose
    https://graph.microsoft.com/.defaultAll Graph permissions granted to app
    openidID token for tenant ID extraction
    profileUser profile claims
    offline_accessRefresh token for session persistence

    Base URL

    All Graph API calls use:

    https://graph.microsoft.com/v1.0/
    

    Beta features (preview, subject to change):

    https://graph.microsoft.com/beta/
    

    OData Query Parameters

    ParameterPurposeExample
    $selectReturn only specified fields$select=id,displayName,email
    $filterFilter results$filter=accountEnabled eq true
    $searchFull-text search (mailboxes, users)$search="displayName:Smith"
    $orderbySort results$orderby=displayName asc
    $topLimit results per page$top=100
    $skipSkip N results$skip=100
    $countInclude total count$count=true
    $expandInclude related entities$expand=manager

    Filter Syntax

    eq        equal             $filter=accountEnabled eq true
    ne        not equal         $filter=jobTitle ne 'Manager'
    gt/lt     greater/less      $filter=createdDateTime gt 2024-01-01T00:00:00Z
    ge/le     >=, <=            same but inclusive
    and/or    logical           $filter=dept eq 'IT' and accountEnabled eq true
    not       negation          $filter=not startsWith(mail,'test')
    startsWith prefix match     $filter=startsWith(displayName,'J')
    endsWith  suffix match      $filter=endsWith(mail,'@contoso.com')
    contains  substring         $filter=contains(jobTitle,'Manager')
    any/all   collection ops    $filter=assignedLicenses/any(x:x/skuId eq '<guid>')
    

    Advanced Queries (Require ConsistencyLevel: eventual)

    Some filters require the ConsistencyLevel: eventual header and $count=true:

    GET /v1.0/users?$filter=assignedLicenses/$count eq 0&$count=true&ConsistencyLevel: eventual
    

    Pagination

    Graph uses server-side pagination. Always check for @odata.nextLink in responses.

    Standard Pagination Loop

    1. Make initial request with $top=100
    2. If response contains @odata.nextLink → follow it
    3. Repeat until no @odata.nextLink
    

    Response with more pages:

    {
      "@odata.context": "...",
      "@odata.nextLink": "https://graph.microsoft.com/v1.0/users?$skiptoken=abc123",
      "value": [...]
    }
    

    Response — last page:

    {
      "@odata.context": "...",
      "value": [...]
    }
    

    The Softeria MCP server handles pagination automatically for supported operations.

    Delta Queries (Incremental Sync)

    Delta queries return only changed items since the last sync — ideal for regular polling.

    Initial Delta Request

    GET /v1.0/users/delta?$select=id,displayName,userPrincipalName,accountEnabled
    

    Response includes a @odata.deltaLink after the last page — store this.

    Subsequent Delta Requests

    GET {deltaLink}
    

    Returns only users added, modified, or deleted since the delta token was issued. Deleted users have "@removed": { "reason": "deleted" } in the response.

    Throttling and Retry

    Graph throttles requests at both per-app and per-tenant levels. Throttled responses return 429 Too Many Requests.

    Retry-After Header

    Always check the Retry-After header on 429:

    HTTP/1.1 429 Too Many Requests
    Retry-After: 15
    

    Wait the specified seconds before retrying.

    Graph Throttle Limits (Approximate)

    ResourceLimit
    Per app per tenant10,000 req/10 min
    Per user3,000 req/10 min
    Mail search10 concurrent
    Reports1 req/15 min per report

    Best Practices

    1. Use $select to request only needed fields (reduces payload + throttle pressure)
    2. Use $filter server-side rather than fetching all and filtering in code
    3. Use delta queries for sync operations instead of polling all items
    4. Batch unrelated requests (see below) to reduce round-trips

    Batch Requests

    Combine up to 20 independent Graph calls into one HTTP request:

    POST /v1.0/$batch
    Content-Type: application/json
    
    {
      "requests": [
        {
          "id": "1",
          "method": "GET",
          "url": "/users/[email protected]?$select=displayName,accountEnabled"
        },
        {
          "id": "2",
          "method": "GET",
          "url": "/users/[email protected]?$select=displayName,accountEnabled"
        }
      ]
    }
    

    Response:

    {
      "responses": [
        { "id": "1", "status": 200, "body": { "displayName": "Alice", "accountEnabled": true } },
        { "id": "2", "status": 200, "body": { "displayName": "Bob", "accountEnabled": false } }
      ]
    }
    

    Use for fetching details on multiple known user IDs simultaneously.

    Common Error Codes

    HTTPCodeMeaningFix
    400Request_BadRequestMalformed OData filterCheck filter syntax
    401InvalidAuthenticationTokenToken expired or malformedRe-authenticate
    403Authorization_RequestDeniedMissing Graph permissionAdd scope, re-consent
    404Request_ResourceNotFoundObject doesn't existCheck GUID/UPN
    429ActivityLimitReachedThrottledWait Retry-After seconds
    500ServiceInternalServerErrorGraph outageRetry with backoff
    503ServiceUnavailableTransientRetry with backoff

    Useful Graph Explorer

    For testing queries interactively: https://developer.microsoft.com/graph/graph-explorer

    Log in with a test M365 account to explore API responses before writing code.

    Related Skills

    Frequently asked questions

    What to verify before installation and use

    What does the Microsoft 365 API Patterns source document cover?

    Microsoft Graph fundamentals shared by every M365 skill: Entra token scopes and the per-request Bearer model, OData query operators and filter syntax, @odata. nextLink pagination, delta queries for incremental sync, 429 throttling and retry behavior, JSON batching, and the common Graph error codes.

    How do I install Microsoft 365 API Patterns?

    The source record exposes this install command: npx skills add https://github.com/WYRE-AI/msp-claude-plugins --skill "msp-claude-plugins/m365/m365/skills/api-patterns". Inspect the command and pinned source before running it.

    Which permission-related actions were detected?

    Static rules flagged network in the source; the page lists the matching lines and excerpts.

    Alternatives

    Compare before choosing

    Computed 10029,236

    garrytan/gbrain

    bulk-ingestion

    End-to-end discipline for turning any large data source (audio libraries, email takeouts, document corpora, chat exports, API dumps) into brain pages at scale. The lifecycle spine: SCHEMA → ACCESS → TRIAL → EVALUATE → IMPROVE → CODIFY → TEST → SKILLIFY → BULK → MONITOR. State is tracked in a durable JSON manifest (see MANIFEST-PATTERN.md) so any crash, session boundary, or subagent fan-out resumes from ground truth instead of memory.

    Computed 10025,136

    alirezarezvani/claude-skills

    app-store-optimization

    App Store Optimization (ASO) toolkit for researching keywords, analyzing competitor rankings, generating metadata suggestions, and improving app visibility on Apple App Store and Google Play Store. Use when the user asks about ASO, app store rankings, app metadata, app titles and descriptions, app store listings, app visibility, or mobile app marketing on iOS or Android. Supports keyword research and scoring, competitor keyword analysis, metadata optimization, A/B test planning, launch checklist

    Computed 1005,277

    dotnet/skills

    migrate-vstest-to-mtp

    Migrates .NET test projects from VSTest to Microsoft.Testing.Platform (MTP). Use when user asks to "migrate to MTP", "switch from VSTest", "enable Microsoft.Testing.Platform", "use MTP runner", set OutputType=Exe only for test projects in Directory.Build.props, or mentions EnableMSTestRunner, EnableNUnitRunner, or UseMicrosoftTestingPlatformRunner. USE FOR: MTP behavioral differences vs VSTest (exit code 8, zero tests discovered, --ignore-exit-code, TESTINGPLATFORM_EXITCODE_IGNORE); centralizing

    Computed 100147

    oaustegard/claude-skills

    featuring

    Generate hierarchical _FEATURES.md files that describe what a codebase DOES from a user/consumer perspective, anchored to source symbols via tree-sitting. Supports large complex codebases through feature-driven decomposition into sub-feature files. Uses a multi-pass synthesis: orientation → detail → overview rewrite. Use when someone says "what does this do", "document features", "feature inventory", "_FEATURES.md", or needs to understand a codebase's purpose before modifying it. Complements tre