> For the complete documentation index, see [llms.txt](https://api-docs.intratool.help/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://api-docs.intratool.help/introduction/query-manipulation/result-control.md).

# Result Control

Result Control query parameters determine which public fields and relations the intratool API returns and how it orders, limits, or paginates the result. These controls do not bypass resource authorization, visibility, or Restricted Scope rules.

Each endpoint defines the fields, relations, computed properties, and pagination behavior it supports. Resource-specific query extensions are not part of the shared Result Control contract unless the affected API reference documents them explicitly.

## Query Parameters

| Key                 | Type      | Default             | Description                                                                                                                                     |
| ------------------- | --------- | ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| `select`            | `string`  | Endpoint fields     | Comma-separated fields to return.                                                                                                               |
| `with_count`        | `string`  | No counts           | Pipe-separated relations whose counts are returned.                                                                                             |
| `include`           | `string`  | Endpoint relations  | Pipe-separated relations to return.                                                                                                             |
| `filter`            | `object`  | `{}`                | Standard [Value Filters](/introduction/query-manipulation/value-filters.md) and [Constraints](/introduction/query-manipulation/constraints.md). |
| `filter_relation`   | `object`  | `{}`                | [Grouped Relation Filters](#grouped-relation-filters) on query-backed endpoints.                                                                |
| `filter_with_count` | `object`  | `{}`                | [Filtered Relation Counts](#filtered-relation-counts) and count comparisons on query-backed endpoints.                                          |
| `sort`              | `string`  | Endpoint order      | Comma-separated fields used for ordering.                                                                                                       |
| `limit`             | `integer` | No additional limit | Maximum number of records.                                                                                                                      |
| `page`              | `integer` | `1`                 | Page number for pagination-enabled endpoints.                                                                                                   |
| `per_page`          | `integer` | `25`                | Page size for pagination-enabled endpoints.                                                                                                     |
| `appends`           | `string`  | Endpoint appends    | Comma-separated computed fields to add.                                                                                                         |

## Includes

Use `include` to return related resources without additional API requests. The relation must be listed as public in the affected resource's Model Definition.

**Syntax**

* `{route}` - Endpoint from which records are retrieved.
* `?include` - Query parameter containing the relations.
* `{relations}` - Relation identifiers separated by `|`; use `.` for nested relations.

<mark style="color:green;">`GET`</mark> `/api/{route}?include={relations}`

### Relation Fields

Append `:` and comma-separated field keys to select fields on an included relation.

`?include={relation}:{field1},{field2}`

{% hint style="warning" %}
Include every key needed to resolve the relation. For example, a selected child record may need its primary and foreign keys for the relation to be returned correctly.
{% endhint %}

### Relation Options

Append relation options after the selected fields. Options use square brackets, are separated by commas, and are case-sensitive. A relation without field selection places the first option directly after `:`.

`?include={relation}:{field1},[{option}={value}]`

| Option       | Type      | Description                                                                                                             |
| ------------ | --------- | ----------------------------------------------------------------------------------------------------------------------- |
| `withCounts` | `string`  | Add counts for one or more related relations. Separate multiple relation names with `+`.                                |
| `order`      | `string`  | Order related records by one or more fields. Separate fields with `+` and prefix a field with `-` for descending order. |
| `limit`      | `integer` | Limit the number of related records.                                                                                    |
| `appends`    | `string`  | Add one or more computed fields to related records. Separate field names with `+`.                                      |
| `nestLevels` | `integer` | Repeat a self-referential relation for the specified number of additional nesting levels.                               |

**Combined example**

<mark style="color:green;">`GET`</mark> `/api/{route}?include=manualEntries:id,title,manual_chapter_id,[withCounts=seenUsers+readUsers],[order=-id],[limit=2],[appends=hash]`

**Self-referential example**

<mark style="color:green;">`GET`</mark> `/api/{route}?include=children:id,title,parent_id,[nestLevels=2]`

Relation options affect only supported, authorized relations. Invalid or unavailable relations are not made accessible by including them.

## Selects

Use `select` to restrict the response to specified public fields.

**Syntax**

* `{route}` - Endpoint from which records are retrieved.
* `?select` - Query parameter containing the fields.
* `{fields}` - Field keys separated by `,`.

<mark style="color:green;">`GET`</mark> `/api/{route}?select={fields}`

{% hint style="warning" %}
When combining `select` with `include`, include the field required to resolve each requested relation.
{% endhint %}

## Limiting

Use `limit` to control the maximum number of returned records.

**Syntax**

* `{route}` - Endpoint from which records are retrieved.
* `?limit` - Query parameter containing the maximum result count.
* `{value}` - Maximum number of records to return.

<mark style="color:green;">`GET`</mark> `/api/{route}?limit={value}`

For paginated endpoints with an exact count, `limit` also caps the reported total and can therefore reduce the last available page. Count-less endpoints still stop returning records after the limit is reached.

## Pagination

Pagination-enabled endpoints accept `page` and `per_page`. They default to page `1` with `25` records per page.

**Syntax**

* `{route}` - Pagination-enabled endpoint from which records are retrieved.
* `?page` - Query parameter containing the page number.
* `?per_page` - Query parameter containing the page size.

<mark style="color:green;">`GET`</mark> `/api/{route}?page=2&per_page=25`

Paginated responses contain `current_page`, `last_page`, `per_page`, `total`, `from`, `to`, and `data`. Endpoints that do not enable pagination ignore these shared pagination controls or document different behavior.

### Count-less Pagination

Some entity-selection and preview endpoints avoid an exact count. Their response keeps the standard pagination fields but returns `total` as `null`. While another page may exist, `last_page` is the next page number; otherwise it equals `current_page`. Clients can therefore test whether `last_page` is greater than `current_page` without treating it as an exact total page count.

## Sorting

Use `sort` to define the order of returned records.

**Syntax**

* `{route}` - Endpoint from which records are retrieved.
* `?sort` - Query parameter containing the sort fields.
* `{fields}` - Field keys separated by `,`; prefix a field with `-` for descending order.

<mark style="color:green;">`GET`</mark> `/api/{route}?sort={fields}`

For example, `?sort=-updated_at,title` sorts by `updated_at` descending and then by `title` ascending.

## Relation Counts

Use `with_count` to return the number of related records without returning those resource objects.

**Syntax**

* `{route}` - Endpoint from which records are retrieved.
* `?with_count` - Query parameter containing the relations.
* `{relations}` - Relation identifiers separated by `|`.

<mark style="color:green;">`GET`</mark> `/api/{route}?with_count={relations}`

Each count uses the snake-case relation name followed by `_count`. For example, `with_count=seenUsers|readUsers` adds `seen_users_count` and `read_users_count`.

### Filtered Relation Counts

On query-backed endpoints, `filter_with_count` computes a count with optional related-field filters. The relation must be public for the endpoint, and its access restrictions still apply. This filter adds the count to the response without requiring a separate `with_count` parameter.

**Filtered count example**

<mark style="color:green;">`GET`</mark> `/api/infoboard/posts?filter_with_count[comments][user_id][is]=3`

This request adds `comments_count` for comments authored by user `3`. Other fields inside the relation's filter object use the standard [Value Filters](/introduction/query-manipulation/value-filters.md).

Place comparisons on the resulting count under `count`. A scalar `count` means exact equality; an object accepts the supported [count comparisons](#count-comparisons).

**Count comparison example**

<mark style="color:green;">`GET`</mark> `/api/infoboard/posts?filter_with_count[comments][user_id][is]=3&filter_with_count[comments][count][gte]=2`

This request returns posts with at least two accessible comments authored by user `3`. Use `relation as alias` as the relation key to name the count explicitly, for example `filter_with_count[comments as authored_comments][count][gte]=2`; the response field is then `authored_comments`. Encode spaces when sending the URL. Relation and alias identifiers must start with a letter or underscore and contain only letters, digits, and underscores.

**Count comparisons**

* `is` - Count equals the supplied value.
* `not` - Count differs from the supplied value.
* `gt` - Count exceeds the supplied value.
* `gte` - Count is at least the supplied value.
* `lt` - Count is below the supplied value.
* `lte` - Count is at most the supplied value.
* `in` - Count matches one of the supplied comma-separated values or array items.
* `nin` - Count matches none of the supplied comma-separated values or array items.
* `is_null` - Tests whether the aggregate is null with `1`, or non-null with `0`; relation counts normally return a number, including `0`.

These filters require a database-backed query. Endpoints that calculate a collection of results in memory do not support this aggregate-filter syntax.

## Appends

Use `appends` to add supported computed fields to API responses.

**Syntax**

* `{route}` - Endpoint from which records are retrieved.
* `?appends` - Query parameter containing the computed fields.
* `{fields}` - Computed field keys separated by `,`.

<mark style="color:green;">`GET`</mark> `/api/{route}?appends={fields}`

**Top-level example**

<mark style="color:green;">`GET`</mark> `/api/manual/entries/1?appends=hash`

Use the `appends` relation option for included relations. Top-level fields are separated by `,`, while relation-option fields are separated by `+`.

<mark style="color:green;">`GET`</mark> `/api/forms/1?include=formFields:[appends=field_validation_string]`

{% hint style="warning" %}
If an appended field depends on an attribute excluded by `select`, the appended output can be incomplete.
{% endhint %}

## Filters

The shared `filter` object accepts the field comparisons documented under [Value Filters](/introduction/query-manipulation/value-filters.md) and the relation conditions documented under [Constraints](/introduction/query-manipulation/constraints.md).

### Grouped Relation Filters

On query-backed endpoints, `filter_relation[{relation}]` groups comparisons that must match the same related record. Multiple comparisons use `AND` semantics within that record. The relation must be public for the endpoint, and its access restrictions still apply.

**Grouped relation example**

<mark style="color:green;">`GET`</mark> `/api/infoboard/posts?filter_relation[comments][user_id][is]=3&filter_relation[comments][text][value]=approved`

This request returns posts with an accessible comment authored by user `3` whose text contains `approved`. Separate dot-notation filters can match different related records; grouping them requires one comment to satisfy both conditions. Filtering does not include comments in the response; add `include=comments` when needed.

Resource-specific shortcut filters added on top of those shared operators are intentionally not part of the public API documentation yet.
