Skip to main content
Conductor’s QuickBooks Desktop API v2 uses cursor-based pagination to handle large datasets efficiently, allowing you to retrieve results in manageable chunks. This guide explains how to implement pagination and its key limitations.

How pagination works

For list endpoints that support pagination (indicated by the presence of a cursor query parameter in the API specification), the process works as follows:
  1. Make your initial request to the list endpoint without a cursor.
    • Use the limit query parameter to control how many items are returned per page.
      • The default and maximum value is 150 items per page. We enforce this limit to prevent overloading QuickBooks Desktop.
  2. The response will contain the following pagination fields:
    • nextCursor - The cursor value to use when requesting the next page of results. This field is null if there are no more pages.
    • hasMore - Indicates whether there are more pages of results available.
    • remainingCount - The number of remaining items that can be retrieved in subsequent pages.
  3. To fetch the next page, make another request with the cursor query parameter set to the nextCursor value from the previous response.
    You must make subsequent pagination requests within 10 seconds of receiving the previous response. If you exceed this time limit, you’ll receive an error. This is rarely a problem for code that fetches pages in a loop, but it can affect manual testing where you copy and paste cursor values between requests.
  4. Repeat until hasMore is false.
  5. Attempting to request another page when hasMore is false will result in an error.

Important limitations

Same cursor value used for all pages

The cursor value stays the same for every page in a sequence. Requests that send it are not idempotent: each one returns the next page. If a request fails, you cannot retry it with the cursor, because QuickBooks may already have moved past that page.

Cursors are short-lived

A cursor stops working 10 seconds after the previous response, when hasMore becomes false, or when QuickBooks Desktop or the Web Connector restarts. Requests with an expired cursor return an error. After an expired cursor or a failed request, start over without a cursor. To make a run resumable, see Paging by name.

No custom sorting available

QuickBooks Desktop determines the order of results, the order is not guaranteed, and the API does not support custom sorting. The exception is name order: when you set nameFrom or nameTo, most list endpoints return results sorted by name. See Paging by name.

Non-paginated endpoints

Some QuickBooks Desktop list endpoints do not support pagination because QuickBooks Desktop does not support it for those object types. You can recognize them by the absence of a cursor parameter. Most are object types that rarely have many records. You can page through some of them by name instead. See Paging by name.

Paging by name

You can also page through a list by name with nameFrom. It is the only way to page through list endpoints that have no cursor, and it works on every list endpoint whose nameFrom description says the results are sorted by name. Each page is a separate QuickBooks query, so paging by name is slower than a cursor, but requests are idempotent: to retry a failed one, send it again unchanged. When you set nameFrom or nameTo, QuickBooks returns the results sorted by full name, compared case-insensitively in its own sort order: punctuation first, then digits, then letters. Both bounds are inclusive.
Do not page by name through accounts or price levels. QuickBooks does not return them sorted by name, even with nameFrom or nameTo: accounts come back in QuickBooks’ internal order, and price levels come back grouped by type (fixed-percentage first, then per-item).
  1. On the first request, set limit to at least 2 and set nameFrom to ' (a single apostrophe), which sorts before every name. Do not omit nameFrom, because without a name bound the order is not guaranteed.
  2. On each later request, set nameFrom to the name of the last record you received, from the field named in that endpoint’s nameFrom description. Keep every other query parameter the same.
  3. Because nameFrom is inclusive, each later page starts with the last record of the previous page. Drop it by id.
  4. On paginated endpoints, stop when hasMore is false. On endpoints without a cursor, stop when a response returns fewer records than limit, including the repeated one.
On paginated endpoints, you can resume a cursor run by name only if the run started with nameFrom set to '. So start each run that way and continue it with cursor. If the cursor expires or a request fails, resume from step 2 without the cursor.

Pagination in Conductor SDKs

Our official client libraries handle pagination automatically, making it easier to work with paginated responses. Check out their documentation for implementation details:

Example

  1. Initial request:
    Example initial response
  2. Next page request with cursor query parameter:
    Example next page response
  3. Requesting another page after hasMore is false will result in an error:
    Example error response