How to Handle Pagination and Access Cursors in Asynchronous Requests with SDK v2 Migration?

This topic was automatically generated from Slack. You can find the original thread here.

I’m migrating to SDK v2 and running into an issue with pagination.

In the previous version, I fetched a paginated list of Pipedream apps using pipedream.listApps, stored the endCursor, and reused it when users requested the next page.

In the new TypeScript SDK, the pipedream.apps.list method returns a Page<App> object. This includes a getNextPage method, but no longer provides the cursor value directly in the response. This is problematic for my use case since I need to handle multiple asynchronous requests and rely on passing explicit cursors.

What’s confusing is that the method still accepts a cursor (after) parameter—but the response itself doesn’t expose the cursor anymore.

export interface AppsListRequest {
    /**** The cursor to start from for pagination */
    after?: string;

Could you clarify how I should handle this situation in SDK v2? Is there a recommended way to access or persist cursors when managing pagination across asynchronous requests?

I tried getting it from the rawResponse object included in the response object, but it does not contain the actual response body for some reason, only headers and useless data:

{
  headers: Headers {
    date: 'Thu, 18 Sep 2025 08:25:52 GMT',
    'content-type': 'application/json; charset=utf-8',
    'transfer-encoding': 'chunked',
    connection: 'keep-alive',
    'x-frame-options': 'SAMEORIGIN',
    'x-xss-protection': '1; mode=block',
    'x-content-type-options': 'nosniff',
    'x-download-options': 'noopen',
    'x-permitted-cross-domain-policies': 'none',
    'referrer-policy': 'strict-origin-when-cross-origin',
    vary: 'Accept, Accept-Encoding, Origin',
    'content-encoding': 'gzip',
    etag: 'W/"..."',
    'cache-control': 'max-age=0, private, must-revalidate',
    'x-request-id': '---',
    'x-runtime': '0.108006'
  },
  redirected: false,
  status: 200,
  statusText: 'OK',
  type: 'basic',
  url: 'https://api.pipedream.com/v1/connect/apps?limit=64'
}

Hey , thank you for raising this. I’ve created a ticket here and added to Pipedream internal backlog: [BUG] SDKv2 Pagination: endCursor is not exposed for stateless requests · Issue #18401 · PipedreamHQ/pipedream

Kindly subscribe to it to be notified for latest updates

Hey , thanks!

Just so you know, since the pageInfo attribute is not public (although the PageInfo type is exposed), and also the PageT type is not exposed, I had to do this to both infer the PageT type and obtain the pageInfo attribute:

import type { PageInfo } from '@pipedream/sdk'

// the Page type is returned from several methods in the SDK but its type is not exposed for some reason, so I have to define it myself
export type PageT = {
  data: T[]
  getNextPage: () => PromisePage<T>
  hasNextPage: () => boolean
  [Symbol.asyncIterator]: () => AsyncIteratorT, void, any
}

export function getPageInfoT(page: PageT): PageInfo {
  // @ts-expect-error - the pageInfo is included in the response but not public for some reason
  return page.response.pageInfo
}