Business Central API Pagination & Performance: Complete Guide

When a Business Central integration grows from a few records to thousands or millions, simply calling an API endpoint repeatedly is not enough. You need efficient filtering, controlled result sizes, pagination, retry handling and a performance-focused API design. This guide explains practical patterns for building reliable Business Central integrations.

1. What Is API Pagination?

Pagination means retrieving a large dataset in smaller pages instead of trying to download every record in a single response.

For example, an integration may need to read 50,000 customers. Instead of treating the entire dataset as one response, the client processes the available pages one after another.

Key idea: pagination protects both the Business Central service and the consuming application from unnecessarily large responses, slow processing and memory pressure.

2. Why Pagination Matters in Business Central

Microsoft recommends performance-oriented API and OData patterns such as limiting data, using filters, selecting only required columns and using server-driven paging where appropriate.

3. Business Central API Endpoint Example

A standard Business Central API endpoint can look like this:

https://api.businesscentral.dynamics.com/v2.0/PRODUCTION/api/v2.0/companies({companyId})/customers

You can then apply query options when supported by the endpoint. For example:

https://api.businesscentral.dynamics.com/v2.0/PRODUCTION/api/v2.0/companies({companyId})/customers?$select=id,number,displayName

Reducing the number of fields returned is one of the simplest ways to reduce payload size.

4. Use $top Carefully

The $top query option can limit the number of records returned by a request.

GET .../customers?$top=100

This is useful when you only need a limited number of records, such as a dashboard or a preview. It should not be treated as a complete pagination strategy for large integrations.

Important: do not build a large Business Central OData integration around repeated $skip + $top calls. Microsoft recommends server-driven paging rather than client-driven paging with $top and $skip for OData performance scenarios.

5. Server-Driven Paging and @odata.nextLink

With server-driven paging, Business Central determines how much data is returned in a page. When more data remains, the response can contain an @odata.nextLink value.

The client should follow that link to retrieve the next page rather than trying to construct its own paging token.

{ "@odata.context": "...", "value": [ { "id": "...", "number": "C00010" }, { "id": "...", "number": "C00011" } ], "@odata.nextLink": "https://api.businesscentral.dynamics.com/..." }

The exact response shape depends on the endpoint, but the important pattern is the same: process the current page, check for the next link, call it, and continue until there is no next link.

6. Pagination Flow

  1. Send the initial GET request.
  2. Process the records returned in the current page.
  3. Check whether a next-page link is present.
  4. If it exists, call the supplied next link.
  5. Process the next page.
  6. Repeat until there is no next link.

A simplified client-side algorithm looks like this:

nextUrl = initialUrl while nextUrl is not empty: response = GET(nextUrl) process(response.value) nextUrl = response.@odata.nextLink
Best practice: treat a server-provided next link as opaque. Do not manually modify its paging token or assume that page sizes will always be identical.

7. Use $filter Before Pagination

Pagination is useful, but filtering is often even more important. If the integration only needs recently changed records, do not download the entire table.

For example, a suitable API filter can reduce the dataset before pagination begins:

?$filter=lastModifiedDateTime ge 2026-09-01T00:00:00Z

In real integrations, combine business requirements with the fields and filter capabilities exposed by the endpoint.

8. Use $select to Reduce Payload Size

If an integration only needs five fields, there is little value in transferring dozens of fields.

?$select=id,number,displayName,email,phoneNumber

Smaller responses generally mean less network traffic, less JSON parsing and less memory usage in the consuming application.

9. Be Careful with $expand

$expand is useful when related data is required, but expanding large related datasets can make an API call expensive.

A safer pattern is to combine an expansion with a restrictive filter or limit the data you actually need.

?$select=id,number,displayName&$expand=contacts($select=id,displayName)

Always test the actual response size and execution time instead of assuming that an apparently small query will be fast.

10. API Pagination vs OData Paging

ApproachTypical useImportant point
Business Central REST APIsApplication integrationsUse the API stack and efficient query options; handle paged list responses correctly.
OData web servicesData access, reporting and compatible clientsPrefer server-driven paging for large result sets.
$topSmall result limitsUseful for limiting a request, not a substitute for robust server-driven paging.
$skip + $topCommon generic REST patternDo not use it as the main client-driven paging approach for Business Central OData.

11. Performance Best Practices

12. Handling 429, 503 and 504 Responses

Large integrations can encounter service throttling or temporary service conditions. Your client should be prepared for HTTP status codes such as 429 Too Many Requests, 503 Service Temporarily Unavailable and 504 Gateway Timeout.

A robust retry strategy can use a cool-off period and exponential backoff rather than immediately repeating the same request.

Attempt 1 → wait briefly Attempt 2 → wait longer Attempt 3 → wait longer again If still failing → log the failure and move the item to a retry/dead-letter process

The exact retry policy should be based on the integration's business requirements and operational limits.

13. Example: Sync Customers Efficiently

Imagine an external e-commerce application needs to synchronize customers from Business Central.

A poor design might download every customer and every available field on every run.

A better design is:

  1. Use the Business Central API.
  2. Request only required fields with $select.
  3. Filter for records that need synchronization.
  4. Process the response page by page.
  5. Follow the server-provided next link when present.
  6. Save a synchronization checkpoint.
  7. Retry transient failures with backoff.
  8. Log failures that cannot be recovered automatically.

14. Pagination in an AL Integration

When AL uses HttpClient to call an external service, the same design principles apply. Keep the HTTP request, JSON parsing and pagination logic separate where practical.

HttpClient.Get(RequestUrl, Response); if Response.IsSuccessStatusCode() then begin Response.Content().ReadAs(ResponseText); // Parse JSON // Process current page // Read next link end else begin // Handle HTTP error end;

For calls from interactive AL sessions, remember that an outgoing HTTP call blocks AL execution until the call completes. Long-running integrations are usually better designed around background processing rather than making a user wait for a large synchronization job.

15. Common Pagination Mistakes

Mistake 1: Downloading everything in one request

This increases response size, memory usage and timeout risk.

Mistake 2: Ignoring the next link

If the service provides another page, processing only the first response means your integration silently misses records.

Mistake 3: Manually modifying a paging URL

Server-generated paging links should be treated as opaque. Follow the supplied link instead of guessing its token format.

Mistake 4: Requesting every field

Use $select when the endpoint supports it and only return data the consumer needs.

Mistake 5: Retrying immediately

Repeated immediate retries can make throttling worse. Use controlled backoff and logging.

16. How to Test API Performance

Use Postman, browser developer tools or another HTTP client to compare different versions of a query.

Measure:

Do not optimize blindly. Establish a baseline, make one meaningful change, and measure the result again.

17. Pagination Checklist

FAQ

Does pagination improve Business Central API performance?

It can improve reliability and resource usage by keeping individual responses manageable. It should be combined with filtering, selecting required fields and sensible endpoint design.

Should I always use $top?

No. Use $top when you intentionally need to limit a result set. For large OData datasets, use the server-driven paging pattern rather than building a large paging system around $skip and $top.

What should I do when @odata.nextLink is returned?

Process the current page, then request the supplied next link and continue until no next link is returned.

What is the best way to make a Business Central API integration fast?

Start with the right endpoint, reduce the dataset with filters, select only required fields, avoid unnecessary expansions, use efficient paging and measure actual performance.

Related Dynexal Tutorials