Note: This is a part of our series on API Pagination where we solve common developer queries in detail with common examples and code snippets. Please read the full guide here where we discuss page size, error handling, pagination stability, caching strategies and more.
It is important to account for edge cases such as reaching the end of the dataset, handling invalid or out-of-range page requests, and to handle this errors gracefully.
Always provide informative error messages and proper HTTP status codes to guide API consumers in handling pagination-related issues.
Here are some key considerations for handling edge cases and error conditions in a paginated API:
How to handle common errors and invalid requests in API pagination
Here are some key considerations for handling edge cases and error conditions in a paginated API:
1. Out-of-range page requests
When an API consumer requests a page that is beyond the available range, it is important to handle this gracefully.
Return an informative error message indicating that the requested page is out of range and provide relevant metadata in the response to indicate the maximum available page number.
2. Invalid pagination parameters
Validate the pagination parameters provided by the API consumer. Check that the values are within acceptable ranges and meet any specific criteria you have defined. If the parameters are invalid, return an appropriate error message with details on the issue.
3. Handling empty result sets
If a paginated request results in an empty result set, indicate this clearly in the API response. Include metadata that indicates the total number of records and the fact that no records were found for the given pagination parameters.
This helps API consumers understand that there are no more pages or data available.
4. Server errors and exception handling
Handle server errors and exceptions gracefully. Implement error handling mechanisms to catch and handle unexpected errors, ensuring that appropriate error messages and status codes are returned to the API consumer. Log any relevant error details for debugging purposes.
5. Rate limiting and throttling
Consider implementing rate limiting and throttling mechanisms to prevent abuse or excessive API requests.
Enforce sensible limits to protect the API server's resources and ensure fair access for all API consumers. Return specific error responses (e.g., HTTP 429 Too Many Requests) when rate limits are exceeded.
6. Clear and informative error messages
Provide clear and informative error messages in the API responses to guide API consumers when errors occur.
Include details about the error type, possible causes, and suggestions for resolution if applicable. This helps developers troubleshoot and address issues effectively.
7. Consistent error handling approach
Establish a consistent approach for error handling throughout your API. Follow standard HTTP status codes and error response formats to ensure uniformity and ease of understanding for API consumers.
For example, consider the following API in Django
8. Consider an alternative
If you work with a large number of APIs but do not want to deal with pagination or errors as such, consider working with a unified API solution like Knit where you only need to connect with the unified API only once, all the authorization, authentication, rate limiting, pagination — everything will be taken care of the unified API while you enjoy the seamless access to data from more than 50 integrations.
Sign up for Knit today to try it out yourself in our sandbox environment (getting started with us is completely free)
Frequently Asked Questions
What are common API pagination errors?
The most common API pagination errors are: invalid or expired cursor tokens (the client retries a cursor that has timed out), missing records due to offset drift (inserts between pages shift results, silently skipping records), duplicate records on consecutive pages (a record updated between requests appears twice), out-of-range page requests returning 400 or empty responses, and inconsistent total counts when the dataset is modified mid-pagination. The root cause of most pagination bugs is using offset on mutable data — switching to cursor-based or keyset pagination eliminates the majority of these issues. Knit handles these edge cases internally when syncing from enterprise HRIS and ATS platforms, retrying expired cursors and surfacing sync errors clearly rather than silently dropping records.
Why are records missing from paginated API responses?
Missing records in paginated API responses are almost always caused by offset pagination on a dataset that was modified between page requests. When a record is deleted from page 1 after you've fetched it, every subsequent record shifts one position forward - the first record of page 2 is now the last record of page 1, and your client skips it entirely. The fix is to switch to cursor-based or keyset pagination, which uses a stable pointer that doesn't shift when records are inserted or deleted. If you must use offset, fetch records in reverse chronological order so insertions push records toward earlier already-fetched pages rather than creating gaps later.
How do you handle an invalid or expired pagination cursor?
When a pagination cursor expires or becomes invalid, the API should return a clear error — typically HTTP 400 with a descriptive code like cursor_expired or invalid_cursor — rather than silently returning wrong results. On the client side, handle this by restarting pagination from the beginning or from the last known good checkpoint, depending on whether your use case tolerates re-fetching records. Set cursor TTLs based on realistic client behaviour — cursors that expire in minutes will frustrate developers paginating large datasets. Knit implements automatic cursor retry and pagination checkpointing when syncing from enterprise APIs, so a single expired cursor doesn't trigger a full resync.
What HTTP status codes should a paginated API return for errors?
Paginated APIs should use standard HTTP status codes: 400 for invalid pagination parameters (bad page number, malformed cursor, page size exceeding maximum), 404 if the resource being paginated no longer exists, 422 for semantically invalid parameters (negative offset, zero page size), and 429 for rate limit exceeded on rapid page-through requests. Avoid returning 200 with an empty results array for genuinely invalid requests — it masks errors from clients. Always include a machine-readable error code in the response body alongside the human-readable message, so clients can programmatically distinguish cursor_expired from invalid_page_size without parsing strings.
How do you handle duplicate records in paginated API responses?
Duplicate records across paginated responses occur when offset pagination is used on a dataset where records can move between pages due to concurrent writes. The reliable fix is cursor-based or keyset pagination, where each page starts from a stable pointer that doesn't shift. If you cannot change the pagination method, track seen record IDs on the client and deduplicate before processing — but this is a workaround, not a fix. Knit uses cursor-based pagination internally to prevent duplicates when syncing employee records from platforms like Workday and BambooHR, where the underlying dataset changes continuously. If sort order can change mid-pagination, document this explicitly so integrators know to expect and handle duplicates.
Why does my paginated API return a 400 error for large page numbers?
APIs that return 400 errors for large page numbers are enforcing a maximum offset or page depth limit. Deep pagination with offset (e.g. OFFSET 10,000,000) is expensive on the database — it requires scanning and discarding millions of rows before returning results, and many APIs cap this to protect performance. If you need to access deep into a large dataset, the correct approach is cursor-based pagination, which fetches records from a stable pointer rather than skipping rows. If you're building an API and need to support deep access, implement cursor or keyset pagination and document the maximum supported offset clearly in your API reference.



.webp)

