Building, integrating, or customizing apps and workflows within Microsoft Teams using developer tools and APIs
Pagination for Teams channel messages and replies in Microsoft Graph must follow the standard @odata.nextLink pattern and the current Teams-specific behaviors.
Key points from the documented behavior:
-
@odata.nextLinkmust be used as-is- For paged results, Microsoft Graph returns an
@odata.nextLinkproperty that contains the full URL for the next page. - The guidance is to send a GET request to that URL exactly as returned. Do not try to extract or manipulate
$skipTokenor$skipand reuse it in a different or modified request. - Any other query parameters from the original request are already encoded in that URL.
- For paged results, Microsoft Graph returns an
-
skipTokenandskipsemantics- Many Graph APIs, including Teams/Export APIs, use
skipTokenfor paging. The token is opaque and only meaningful in the context of the returnednextLink. - Some APIs (for example, Outlook events/messages) use
$skipinstead, but directory objects do not support$skip. - For Teams Export APIs, the pattern is:
- Initial request without
skipToken→ response includes@odata.nextLinkwith?skipToken=ABC. - Next request uses that full
nextLink→ response may again include a newskipToken. - When a response page has no
skipTokenin@odata.nextLink, there are no more results.
- Initial request without
- Many Graph APIs, including Teams/Export APIs, use
- Teams APIs and
@odata.nextLink- Teams channel-related APIs (for example, list channels, incomingChannels, allChannels) explicitly support
@odata.nextLinkpagination to handle large result sets. - The same paging model applies: when the result set spans multiple pages, the response includes
@odata.nextLinkwith the URL for the next page.
- Teams channel-related APIs (for example, list channels, incomingChannels, allChannels) explicitly support
- Client-side paging requirements
- A page of results can contain zero or more items; an empty result set on a subsequent page is allowed by design.
- Different APIs have different default and maximum page sizes; a requested
$topmay be ignored or capped. - For directory resources, custom headers like
ConsistencyLevelmust be re-sent on subsequent page requests; for Teams messages/replies, ensure any required headers are preserved if applicable.
Given the documented behavior:
- The correct way to paginate replies is:
- Call
GET /teams/{team-id}/channels/{channel-id}/messages/{message-id}/replies?$top=50. - If the response includes
@odata.nextLink, issue a GET to that URL exactly. - Repeat until a page is returned with no
@odata.nextLink.
- Call
- The same pattern applies when using
?$expand=repliesonmessages; eachrepliescollection can expose its own[email protected], which must be followed as returned.
If @odata.nextLink is followed exactly and consistently returns an empty array while more replies are known to exist, that behavior is not aligned with the documented paging model and should be treated as a service issue. In that case, capture:
- The initial request URL and response (including
@odata.nextLink). - The exact
nextLinkURL and its response body. - Any relevant headers.
and provide them to Microsoft support so the backend paging implementation for Teams replies can be investigated.
References: