Skip to main content
Many APIs return data in pages. Workflow service steps handle pagination automatically — you configure the strategy and the engine fetches all pages, appending results to the output table.

Pagination types

Cursor-based

Used by GraphQL APIs, Shopify, Slack, and similar services that return a cursor pointing to the next page:
{
  service: "shopify",
  operation: "listProducts",
  params: { status: "active" },
  outputTable: "raw_products",
  outputSchema: {
    id: "VARCHAR",
    title: "VARCHAR",
    vendor: "VARCHAR",
  },
  paginate: {
    type: "cursor",
    cursorField: "pageInfo.endCursor",
    cursorParam: "after",
    hasMoreField: "pageInfo.hasNextPage",
  },
}
FieldDescription
cursorFieldPath to the cursor value in the response (supports dot notation)
cursorParamParameter name to pass the cursor on the next request
hasMoreFieldPath to a boolean indicating more results exist

Page number

Used by GitHub REST, Rails, Django, and APIs that accept a page number parameter:
{
  service: "github",
  operation: "listRepos",
  params: {},
  outputTable: "raw_repos",
  outputSchema: {
    id: "VARCHAR",
    name: "VARCHAR",
    full_name: "VARCHAR",
  },
  paginate: {
    type: "pageNumber",
    pageParam: "page",
    startPage: 1,
  },
}
FieldDescription
pageParamParameter name for the page number
startPageFirst page number (typically 1)

Offset

Used by Elasticsearch, SQL-style APIs, and services that accept offset and limit parameters:
{
  service: "elasticsearch",
  operation: "search",
  params: { query: "*" },
  outputTable: "raw_results",
  outputSchema: {
    id: "VARCHAR",
    title: "VARCHAR",
    score: "DOUBLE",
  },
  paginate: {
    type: "offset",
    offsetParam: "from",
    limitParam: "size",
    limitValue: 100,
    startOffset: 0,
  },
}
FieldDescription
offsetParamParameter name for the starting offset
limitParamParameter name for the page size
limitValueNumber of records per page
startOffsetInitial offset value (typically 0)

Stop conditions

Pagination stops automatically when there are no more results:
  • Cursor: hasMoreField returns false, or the cursor is null/undefined
  • Page number / Offset: The response returns an empty result set

Retry configuration

In addition to step-level retries (when the entire step fails), you can configure retries per page when a single page request fails:
paginate: {
  type: "cursor",
  cursorField: "nextCursor",
  cursorParam: "cursor",
  maxRetries: 5,
  retryDelayMs: 2000,
}
FieldDefaultDescription
maxRetries3Retry attempts per page
retryDelayMs1000Base delay in milliseconds (exponential backoff applied)