# Computed Fields Computed fields let you define **dynamic, on-the-fly numeric fields** that are calculated during a request. They are created using the `computed_fields[]` query parameter and can be used immediately in **filters** and **sorting**. Computed fields work together with the standard filtering rules described in the ➡️ **[Filtering Documentation](/filtering)** ## What Are Computed Fields? A computed field: * Is defined per request * Performs an **aggregate** on a relation * Becomes available as a **numeric field** for filtering and sorting * Exists only for the current request Supported aggregates: * `count()` * `sum()` * `avg()` * `min()` * `max()` You declare them using query parameters: ``` computed_fields[alias]= ``` # Syntax ### Count ``` relation.count() relation.count() ``` ### Aggregates (sum, avg, min, max) ``` relation.sum() relation.sum(, ) relation.avg() relation.min() relation.max() ``` ### Where clause (``) * Uses the same **DSL filter syntax** as the main `filter` parameter * Is evaluated in the context of the **related model** # Examples ## Count related tasks with status `"Completed"` ``` computed_fields[tasks_done]=tasks.count(status eq "Completed") filter=tasks_done gt 0 ``` ## Sum of billable minutes on `timeUnits` ``` computed_fields[billable_minutes]=timeUnits.sum(minutes, status eq "billable") filter=billable_minutes gte 120 ``` ## Average estimate across tasks ``` computed_fields[avg_estimate]=tasks.avg(estimated_hours) filter=avg_estimate lt 6 ``` ## URL-encoded example ``` ?computed_fields[tasks_done]=tasks.count(status%20eq%20%22Completed%22)&filter=tasks_done%20gt%200 ``` # Using Computed Fields in Filters Computed fields are treated as **numeric fields**. Allowed operators: * `eq`, `ne` / `neq` * `gt`, `gte` * `lt`, `lte` Examples: ``` filter=tasks_done gt 0 filter=billable_minutes gte 120 filter=avg_estimate lt 6 ``` ### Types * `count()` → integer * `sum()`, `avg()`, `min()`, `max()` → number # Sorting With Computed Fields You can sort by any computed field as long as it is declared: ``` ?computed_fields[tasks_done]=tasks.count()&sort=-tasks_done ``` Works regardless of whether the computed field is used in a filter. # Validation Rules The API validates computed field expressions. Errors occur when: * The relation name is unknown * The column does not exist * The where clause uses invalid fields or operators * The syntax is invalid A 400 Bad Request is returned with details. Example error response: ```json { "message": "Invalid computed field expression", "errors": [ {"alias": "billable_minutes", "issue": "Unknown column 'minutesx'"} ] } ``` # Best Practices * Use **short, descriptive aliases** (e.g., `tasks_done`, `avg_estimate`) * Combine multiple computed fields for powerful analytics-style queries * When passing DSL expressions, remember to URL-encode them * Use computed fields when: * You need aggregated information * You need to filter or sort based on aggregated values * You want analytics without building a custom endpoint # Related Documentation See the **Filtering page** for: * DSL filter syntax * Operators * Relation filters (`any`, `all`, `none`) * Data types and validation ➡️ **[Filtering Documentation](/filtering)**