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

# Pagination, sorting, and filtering

> The list envelope, paging rules, sort fields, and per-resource filters

Every list endpoint shares one response envelope and one set of paging parameters.

## The envelope

```json theme={null}
{
  "totalCount": 137,
  "page": 0,
  "limit": 50,
  "hasMore": true,
  "items": [ { "...": "..." } ]
}
```

## Paging

* `page` is **0-based**. Negative values are clamped to `0`.
* `limit` defaults to `50` and is **clamped to 1–200** — out-of-range values are adjusted, not rejected. If you ask for `limit=500` you get 200 items back; check `limit` in the response for the value that was actually applied.
* Iterate on `hasMore` rather than computing page counts from `totalCount` — data can change between calls.

```bash theme={null}
page=0
while : ; do
  resp=$(curl -s "https://api.prophia.com/rest/v2/accounts/{accountId}/properties?page=$page&limit=100" \
    -H "X-API-Key: <your-api-key>")
  echo "$resp" | jq -r '.items[].propertyName'
  [ "$(echo "$resp" | jq '.hasMore')" = "true" ] || break
  page=$((page + 1))
done
```

## Sorting

Pass `sortBy` and `sortDir` (`asc` — the default — or `desc`; anything else is treated as `asc`).

> [!WARNING]
>
> An unrecognized `sortBy` value **silently falls back to the endpoint's default sort** — it does not return an error. If your sort seems ignored, check the field name against the table below. (Contrast with [`include`](https://docs.prophia.com/api-reference/v2/concepts/includes), where unknown keys are rejected with `400`.)

| Resource | Sort fields | Default |
| - | - | - |
| Accounts | `accountName`, `apiName`, `accountStatus`, `accountManager`, `createdAt` | `accountName` |
| Properties | `propertyName`, `customId`, `createdAt` | `propertyName` |
| Buildings | `buildingName`, `address.city`, `address.state`, `activeStatus`, `customId`, `buildingType`, `implementationManager`, `createdAt` | `buildingName` |
| Building spaces | `floor`, `suiteNumber`, `type`, `squareFootage`, `createdAt`, `updatedAt` | `suiteNumber` |
| Leases | `dba`, `tenantLegalName`, `expirationDate`, `commenceDate`, `leaseStatus`, `leaseType`, `suiteNumber`, `squareFootage`, `customId` | `dba` |
| Recently changed leases | `dba` — the only accepted value | `dba` |
| Lease documents | `filename`, `createdAt`, `numberOfPages`, `docCategory` | `filename` |
| Document pages | `pageSequence` | `pageSequence` |
| Tags | `tagName`, `createdAt`, `updatedAt` | `tagName` |
| Custom terms | `tagName`, `definitionType`, `createdAt`, `updatedAt` | `tagName` |
| Custom fields | `fieldName`, `fieldType`, `active`, `createdAt`, `updatedAt` | `fieldName` |

## Filtering

List endpoints take resource-specific filter parameters as plain query params, combinable with paging and sorting. Multiple filters combine with AND. Filters that take a fixed set of values list the accepted values on each endpoint's page.

| Resource | Filter | Matching |
| - | - | - |
| **Accounts** | `accountName`, `apiName`, `accountManager` | Case-insensitive *contains* |
| | `accountStatus` | Case-insensitive exact; an unrecognized value returns no results |
| **Properties** | `propertyName` | Case-insensitive *contains* |
| | `customId` | Exact |
| **Buildings** | `name`, `implementationManager` | Case-insensitive *contains* |
| | `city`, `state` | Case-insensitive exact |
| | `activeStatus` | Case-insensitive exact; an unrecognized value returns no results |
| | `buildingType` | Case-insensitive exact; an unrecognized value returns `400` |
| | `customId` | Exact |
| **Building spaces** | `type`, `floor`, `suiteNumber` | Exact |
| | `rentable`, `occupied`, `archived` | Boolean; omit the param for both |
| **Leases** | `tenantName` | Case-insensitive *contains*, against both `dba` and `tenantLegalName` |
| | `suiteNumber` | Case-insensitive *contains*, against the lease's suite names |
| | `status`, `customId` | Exact |
| | `leaseType` | Case-insensitive; an unrecognized value returns no results |
| | `expirationBefore`, `expirationAfter`, `commenceBefore`, `commenceAfter` | Calendar date `yyyy-MM-dd`, inclusive |
| | `squareFootageMin`, `squareFootageMax` | Inclusive bounds |
| **Recently changed leases** | `start_date`, `end_date` | **Required.** Calendar date `yyyy-MM-dd`, inclusive; the window in which the leases' documents changed |
| **Lease documents** | `filename` | Case-insensitive *contains* |
| | `docCategory` | Case-insensitive exact |
| | `numberOfPagesMin`, `numberOfPagesMax` | Inclusive bounds |
| **Tags** | `tagName` | Case-insensitive *contains* |
| | `lifecycleStatus` | Exact — `ACTIVE`, `VOID`, `STRICKEN`, `EXERCISED` |
| | `isCustomTag` | Boolean; omit the param for both |
| | `createdAtAfter`, `createdAtBefore` | Timestamp, inclusive |
| **Custom terms** | `tagName` | Case-insensitive *contains* |
| | `definitionType` | Case-insensitive exact — `CURRENCY`, `TEXT`, `MULTI`, `DATE`; an unrecognized value returns no results |
| | `aiEnabled` | Boolean; omit the param for both |
| **Custom fields** | `fieldName` | Case-insensitive *contains* |
| | `fieldType` | Case-insensitive exact — `SINGLE`, `MULTI`; an unrecognized value returns no results |
| | `active` | Boolean; omit the param for both |

Two date conventions are in play: lease filters take **calendar dates** (`yyyy-MM-dd`), while the tag `createdAt` filters take **timestamps**. Each endpoint page states the exact type per parameter.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.