# Pagination in the Nebula API

## Overview

All core API resources have support for bulk fetches via "list" API methods.
For example, you can list access points, access rights or users.

The Salto Nebula API uses cursor-based pagination, i.e.: it returns a "cursor", or opaque token, with the list of results.
This token is called the `next_page_token` and can be passed with the next API request to request the next page.

The field name should match the noun in the method name in the request.
For example, there will be a maximum number of items returned based on the `page_size` field in the request.

## Parameters

| Common parameters | Type | Description |
|---|---|---|
| `parent` | String | The parent resource name |
| [`filter`](/nebula/api/filter) | String | A filter that chooses which resource to return. The maximum length of the filter is 20000 characters |
| [`order_by`](/nebula/api/pagination#order-by) | String | How the results should be sorted |
| `page_size` | Integer | The maximum number of items to return |
| `next_page_token` | String | A value returned from a previous `List` request, if any |

## Order by

You can optionally use the `order_by` parameter to sort results in a specific way.

The string value should follow SQL syntax, that's to say it should be a comma-separated list of the field names.
The default sorting order is ascending.

Here's an example:

- `display_name DESC`

This example sorts by `display_name` in descending order.

Not all of the fields in an entity are orderable.
The service will return an `UNKNOWN: field {entity} is not orderable` error for non-orderable fields.

## Example request

{{% info-panel %}}
Placeholders such as `INSTALLATION_ID` or `USER_ID` are used to represent the [IDs of entities in the API](/nebula/guides/names-custom-ids).
These replace the real alphanumeric values like for example, `01GMW9G7PMV3VRMM6PMBC3SHQV`.
{{% / info-panel %}}

[Lists users](https://developer.saltosystems.com/nebula/api/salto/nebula/user/v1/#list-users) within an installation (using Go):

```go
resp, err := client.Users(context.Background(), &ListUsersRequest{
    Parent:   "installations/INSTALLATION_ID",
    PageSize:  2,
})
```

## Example response

```json
{
  "users": [
    {
      "name": "installations/INSTALLATION_ID/users/USER_ID",
      "given_name": "Sherlock",
      "family_name": "Holmes",
      "display_name": "Sherlock Holmes",
      "email": "sherlock@surelock.com",
      "activate_time": "2025-01-29T08:45:32.154830Z",
      "card_key": {
        "name": "installations/INSTALLATION_ID/users/USER_ID/card-key",
        "uid": "04635dfdfd14f0",
        "state": "ACTIVE"
      },
      "app_key": {
        "name": "installations/INSTALLATION_ID/users/USER_ID/app-key",
        "state": "ACTIVE"
      },
      "wallet_key": {
        "name": "installations/INSTALLATION_ID/users/USER_ID/wallet-key",
        "state": "NOT_ASSIGNED"
      },
      "passcode": {
        "name": "installations/INSTALLATION_ID/users/USER_ID/passcode",
        "state": "NOT_ASSIGNED"
      }
    },
    {
      "name": "installations/INSTALLATION_ID/users/USER_ID",
      "given_name": "Dr John",
      "family_name": "Watson",
      "display_name": "Dr John Watson",
      "email": "watson@surelock.com",
      "activate_time": "2025-01-29T08:45:40Z",
      "card_key": {
        "name": "installations/INSTALLATION_ID/users/USER_ID/card-key",
        "state": "NOT_ASSIGNED"
      },
      "app_key": {
        "name": "installations/INSTALLATION_ID/users/USER_ID/app-key",
        "state": "ACTIVE"
      },
      "wallet_key": {
        "name": "installations/INSTALLATION_ID/users/USER_ID/wallet-key",
        "state": "NOT_ASSIGNED"
      },
      "passcode": {
        "name": "installations/INSTALLATION_ID/users/USER_ID/passcode",
        "state": "NOT_ASSIGNED"
      }
    }
  ],
  "next_page_token": "4VoaKt6Jv85cTe0X6xtS_oi2FMh65RqDaMwYs5kN0-nXk-QLBQiaihVDdHljzMSSSgLU0I-MfNOopm5WWo9XAm9b1GqBDIpPI0aiYw=="
}
```

