> ## Documentation Index
> Fetch the complete documentation index at: https://docs.moonbase.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Pagination

> Learn how to work with paginated responses.

The Moonbase API uses cursor-based pagination for list endpoints that return multiple items. These endpoints return one page of results per API call. Each page contains up to 20 results by default.

## Response structure

The API returns items in the `data` property of the response. Refer to the individual endpoints for the ordering of items since they vary based on the endpoint.

**Example: First page (with more results)**

```json theme={null}
{
  "type": "list",
  "data": [
    {
      "id": "1CLJt2ub4MavjpDF6NV14F",
      "type": "item",
      "values": {
        "name": {"type": "value/text/single_line", "data": "OrbGrid"},
        "updated_at": {"type": "value/datetime", "data": "2025-02-17T16:00:00.000Z"}
      }
    },
    {
      "id": "1CLJt2ub4MavjpDF6NV14G",
      "type": "item",
      "values": {
        "name": {"type": "value/text/single_line", "data": "TechStart Inc"},
        "updated_at": {"type": "value/datetime", "data": "2025-02-17T16:00:00.000Z"}
      }
    },
    {
      "id": "1CLJt2ub4MavjpDF6NV14H",
      "type": "item",
      "values": {
        "name": {"type": "value/text/single_line", "data": "Global Systems"},
        "updated_at": {"type": "value/datetime", "data": "2025-02-17T16:00:00.000Z"}
      }
    }
    ...
  ],
  "meta": {
    "cursors": {
      "next": "eyJpZCI6IjFDUDY0dkc2SkhuSkhLUEpLTDVpblcifQ"
    }
  }
}
```

**Example: Middle page (both prev and next)**

```json theme={null}
{
  "type": "list",
  "data": [ /* items omitted for brevity */ ]
  "meta": {
    "cursors": {
      "prev": "eyJpZCI6IjFDUzY4Ykp0Z3k5ZGFzOGFzYTg3bmV3OTJuMHE4a2w4MWpBIn0",
      "next": "eyJpZCI6IjFDUDY0dkc2SkhuSkhLUEpLTDVpblcifQ"
    }
  }
}
```

The `next` cursor will not be present if there are no more pages to fetch. `prev` cursor appears when previous pages exist. Enables bidirectional navigation.

<Note>
  Do not pass both before and after in the same request. Cursors are opaque strings—do not parse or modify them—and should be URL-encoded when used in query parameters.
</Note>

## Pagination parameters

Control pagination using these query parameters:

* `limit`: *(Integer)* — Maximum number of items to return per page. Must be between 1 and 100. Defaults to 20 if not specified.
* `after`: *(String)* — Returns results starting immediately after the item identified by this cursor. Use the `next` cursor from a previous response to fetch the next page.
* `before`: *(String)* — Returns results starting immediately before the item identified by this cursor. Use the `prev` cursor from a previous response to fetch the previous page.

<Note>
  Cursors do not expire and remain valid indefinitely. Using an invalid cursor will return a 400 Bad Request error.
</Note>

## Navigating pages

### Auto-pagination (recommended)

Moonbase SDKs provide methods to automatically iterate through all items across all pages:

<CodeGroup>
  ```typescript TypeScript theme={null}
  async function fetchAllItems(params) {
    const allItems = [];
    // Automatically fetches more pages as needed.
    for await (const item of moonbase.collections.items.list('people', { limit: 5 })) {
      allItems.push(item);
    }
    return allItems;
  }
  ```

  ```go Go theme={null}
  iter := client.Collections.Items.ListAutoPaging(
  	context.TODO(),
  	"people",
  	moonbase.CollectionItemListParams{
  		Limit: moonbase.Int(5),
  	},
  )
  // Automatically fetches more pages as needed.
  for iter.Next() {
  	item := iter.Current()
  	fmt.Printf("%+v\n", item)
  }
  if err := iter.Err(); err != nil {
  	panic(err.Error())
  }
  ```

  ```ruby Ruby theme={null}
  page = moonbase.collections.items.list("people", limit: 5)

  # Fetch single item from page.
  item = page.data[0]
  puts(item.id)

  # Automatically fetches more pages as needed.
  page.auto_paging_each do |item|
    puts(item.id)
  end
  ```

  ```python Python theme={null}
  from moonbase import Moonbase

  moonbase = Moonbase()

  all_items = []
  # Automatically fetches more pages as needed.
  for item in moonbase.collections.items.list(
      collection_id="people",
      limit=5,
  ):
      # Do something with item here
      all_items.append(item)
  print(all_items)

  # Or, asynchronously:

  import asyncio
  from moonbase import AsyncMoonbase

  moonbase = AsyncMoonbase()

  async def main() -> None:
      all_items = []
      # Iterate through items across all pages, issuing requests as needed.
      async for item in moonbase.collections.items.list(
          collection_id="people",
          limit=5,
      ):
          all_items.append(item)
      print(all_items)


  asyncio.run(main())
  ```
</CodeGroup>

### Single page requests

Request one page at a time:

<CodeGroup>
  ```typescript TypeScript theme={null}
  let page = await moonbase.collections.items.list('people', { limit: 5 });
  for (const item of page.data) {
    console.log(item);
  }

  // Convenience methods are provided for manually paginating:
  while (page.hasNextPage()) {
    page = await page.getNextPage();
    // ...
  }
  ```

  ```go Go theme={null}
  people, err := client.Collections.Items.List(
  	context.TODO(),
  	"people",
  	moonbase.CollectionItemListParams{
  		Limit: moonbase.Int(5),
  	},
  )
  for page != nil {
  	for _, item := range page.Data {
  		fmt.Printf("%+v\n", item)
  	}
  	page, err = page.GetNextPage()
  }
  if err != nil {
  	panic(err.Error())
  }
  ```

  ```ruby Ruby theme={null}
  page = moonbase.collections.items.list("people", limit: 5)

  if page.next_page?
    new_page = page.next_page
    puts(new_page.data[0].id)
  end
  ```

  ```python Python theme={null}
  first_page = await moonbase.collections.items.list(
      collection_id="people",
      limit=5,
  )
  if first_page.has_next_page():
      print(f"will fetch next page using these details: {first_page.next_page_info()}")
      next_page = await first_page.get_next_page()
      print(f"number of items we just fetched: {len(next_page.data)}")

  # Remove `await` for non-async usage.
  ```
</CodeGroup>

### Manual pagination with cURL

<Steps>
  <Step title="Make an initial API call to list items">
    ```sh theme={null}
      curl https://api.moonbase.ai/v0/collections/organizations/items \
      --header 'Authorization: Bearer <token>'
    ```

    For authentication details, see the Moonbase [authentication guide](/api-reference/authentication).
  </Step>

  <Step title="Check for pagination cursors in the response">
    * If `meta.cursors.next` is missing, all items have been retrieved
    * If the `next` cursor is present, use it with the `after` parameter to fetch the next page
    * If the `prev` cursor is present, use it with the `before` parameter to fetch the previous page

    **Fetch next page:**

    ```sh theme={null}
      curl https://api.moonbase.ai/v0/collections/organizations/items?after=eyJpZCI6IjFDUDY0dkc2SkhuSkhLUEpLTDVpblcifQ \
      --header 'Authorization: Bearer <token>'
    ```

    **Fetch previous page:**

    ```sh theme={null}
      curl https://api.moonbase.ai/v0/collections/organizations/items?before=eyJpZCI6IjFDUDY0dkc2SkhuSkhLUEpLTDVpblcifQ \
      --header 'Authorization: Bearer <token>'
    ```
  </Step>

  <Step title="Repeat until all required data is processed">
    Continue using the cursors from each response to navigate forward or backward through  results.
  </Step>
</Steps>
