# Pagination and filtering

Most MK.IO `list` endpoints accept query parameters that page, sort, and filter the results on the server. Using them keeps responses small, removes client-side filtering work, and reduces the number of follow-up requests your integration makes.

## The shape of a list response

A list endpoint returns two top-level fields:

- `value`: the array of resources on the current page.
- `supplemental`: metadata about the result set, including pagination counts.

A trimmed response looks like this:

```json
{
  "value": [
    { "name": "asset-001" },
    { "name": "asset-002" }
  ],
  "supplemental": {
    "count": 2,
    "kind": "Asset",
    "operation": "list",
    "pagination": {
      "start": 0,
      "end": 2,
      "records": 2,
      "total": 145
    }
  }
}
```

The `pagination` block tells you where you are in the collection: `records` is how many items this page returned, and `total` is how many exist across the whole project. Comparing them tells you whether more pages remain.

## Limit a page with $top

`$top` caps how many items a single page returns. The service returns up to that many, and never more than exist.

```bash
curl -X GET "https://app.mk.io/api/v1/projects/<PROJECT_NAME>/media/assets?\$top=10" \
  -H "Authorization: Bearer <YOUR_TOKEN>"
```

The `$` is escaped as `\$` in these examples so that your shell does not treat the parameter as a variable.

## Page through results with $skiptoken

`$skiptoken` sets the start offset for the next page. Use it to walk a collection one page at a time.

```bash
curl -X GET "https://app.mk.io/api/v1/projects/<PROJECT_NAME>/media/assets?\$top=10&\$skiptoken=<SKIPTOKEN>" \
  -H "Authorization: Bearer <YOUR_TOKEN>"
```

Do not construct `$skiptoken` values by hand. Take the value from the previous response.

To page until the end, request pages until `supplemental.pagination.records` is smaller than your `$top`, or until the running total of returned records reaches `supplemental.pagination.total`.

## Sort with $orderby

`$orderby` orders the result collection by a field. The valid fields depend on the endpoint.

```bash
curl -X GET "https://app.mk.io/api/v1/projects/<PROJECT_NAME>/media/assets?\$orderby=properties/created%20desc" \
  -H "Authorization: Bearer <YOUR_TOKEN>"
```

For the Media API asset list, sortable fields include `name`, `properties/created`, `properties/lastModified`, and `properties/storageAccountName`. Other APIs expose their own sort keys. Check the [API reference](/api-reference/media-api) for the fields a given endpoint supports.

## Filter with $filter

`$filter` restricts the result set to items that match an expression.

```bash
curl -X GET "https://app.mk.io/api/v1/projects/<PROJECT_NAME>/media/assets?\$filter=name%20eq%20'my-asset'" \
  -H "Authorization: Bearer <YOUR_TOKEN>"
```

The fields available to filter on vary by resource. Common examples are assets by `name` or `properties/created`, live events by `properties/resourceState`, devices by `spec/siteName`, and sites by `status/locationName`.

## Filter by label

Several list endpoints also support label queries, which are separate from `$filter`.

Return items that carry a given label key with `$label_key`:

```bash
curl -X GET "https://app.mk.io/api/v1/projects/<PROJECT_NAME>/media/assets?\$label_key=studio" \
  -H "Authorization: Bearer <YOUR_TOKEN>"
```

When you pass more than one `$label_key`, an item must carry all of those keys to match.

Match a key and value with `$label`. Use `=` for an exact match and `~` for a partial match:

```bash
curl -X GET "https://app.mk.io/api/v1/projects/<PROJECT_NAME>/media/assets?\$label=studio=paravalley" \
  -H "Authorization: Bearer <YOUR_TOKEN>"
```

Label queries are supported on the asset, live event, device, network, and site list endpoints.

## Combine parameters to do less work

The parameters compose. A single request can limit, sort, and filter at once:

```bash
curl -X GET "https://app.mk.io/api/v1/projects/<PROJECT_NAME>/media/assets?\$top=10&\$orderby=properties/created%20desc&\$label=studio=paravalley" \
  -H "Authorization: Bearer <YOUR_TOKEN>"
```

That one call returns the ten most recent assets for one studio, which would otherwise take a full list plus client-side sorting and filtering.

## A pattern for scanning large collections

When you need to process an entire collection, work from narrow to broad:

1. Apply the narrowest `$filter` or label query the task allows.
2. Add `$orderby` if processing order matters.
3. Set a bounded `$top`.
4. Page with `$skiptoken` until no further records remain.

Filtering and sorting on the server is almost always better than listing everything and filtering locally. It returns less data, needs fewer follow-up requests, and keeps you clear of the [rate limits](/api-guides/understanding/rate-limits).
