---
title: "Aggregate Form Instances"
method: POST
path: "/v1/form-instance/aggregate"
tags: ["Form Instances"]
---

# Aggregate Form Instances

`POST /v1/form-instance/aggregate`

Aggregate form instances with GROUP BY operations.

Allows grouping by status, form_id, type_id, site_id, and other fields with
aggregation functions like COUNT, SUM, AVG, MIN, MAX. Uses the same base filters
and company scoping as the search endpoint for consistent behavior.

## Request body

- FormInstanceAggregationModel — Request model for form instance aggregation queries.
  - `query` string, nullable — Keywords should be space separated and are `AND`ed together, so all keywords must be present but they can be present in any of the fields specified above.
  - `skip` integer, nullable — Number of records to skip before returning records
  - `limit` integer, nullable — Number of records to return
  - `sort_direction` 'asc' | 'desc' — Direction to sort the `sort_column` - ascending or descending.
  - `date_start` string, date-time, nullable — If sorting on `updated_at` or `created_at`, and `date_cut_off` is provided, return only records that were created or updated (whichever is being sorted on) between `date_start` and `date_cut_off`
  - `date_cut_off` string, date-time, nullable — If sorting on `updated_at` or `created_at`, return only records that were created or updated (whichever is being sorted on) between the initial value (determined by sort order) and the cutoff date. For example, sorting on `created_at` ascending with a `date_cut_off` will return all records from the oldest creation date to the cutoff date. By comparison, sorting on `created_at` descending with a `date_cut_off` will return all records from the most recent creation date to the cutoff date.
  - `sort_column` string, nullable — Column to sort aggregation results by (must be in group_by or an aggregation alias)
  - `group_by` string[], required — Column names to group by
  - `aggregations` AggregationFieldLiteralIdFormIdSiteIdSubmittedByUserId[], required — Aggregation functions to apply
    - `column` 'id' | 'form_id' | 'site_id' | 'submitted_by_user_id', required — Column name to aggregate
    - `operator` 'sum' | 'avg' | 'count' | 'min' | 'max' | 'count_distinct', required — Supported aggregation operators for SQL GROUP BY queries.
    - `alias` string, nullable — Optional alias for the result column
  - `date_filter_column` 'created_at' | 'updated_at' | 'submitted_on' — Column to apply date_start/date_cut_off filters on. One of 'created_at', 'updated_at', or 'submitted_on' (excludes drafts since they have no submitted_on).
  - `is_archived` boolean, nullable — Filter by entity archived status. Defaults to False (only active entities). Use True for archived only, None to include all.
  - `project_is_archived` boolean, nullable — Filter by parent project's archived status. Defaults to False (only active projects). Use True for archived projects only, None to include all.
  - `query_mode` 'own' | 'shared' — Specify the search mode for the form instances.
  - `form_instance_status` 'draft' | 'draft_pending_review' | 'pending_review' | 'completed' | 'disapproved' — The status of the form instances.
  - `form_id` integer, nullable — Filter to submissions of a specific form template.
  - `site_id` integer, nullable — Filter to submissions at a specific site.
  - `type_id` integer, nullable — Filter to submissions of a specific form type.
  - `submitted_by_user_id` integer, nullable — Filter to submissions by a specific user.
  - `asset_id` integer, nullable — Filter to submissions for a specific asset.

## Response `200`

Successful Response

- ApiGenericResponseFormInstanceAggregationResponse
  - `error` boolean — A boolean error indicator.
  - `message` string, nullable — Optional message.
  - `data` FormInstanceAggregationResponse — Response model for form instance aggregation queries.
    - `data` object[], required — List of aggregation result rows. Each row contains the group_by column values and computed aggregation values. Keys are the group_by column names and aggregation aliases (or default names like 'count_id' if no alias provided).
    - `total_groups` integer, required — Total number of distinct groups returned by the aggregation query
    - `metadata` AggregationMetadataLiteralStatusFormIdTypeIdSiteIdCompanyIdIsArchivedFormFormatDeviceTypeSubmittedByUserIdCreatedDateCreatedWeekCreatedMonthCreatedYearUpdatedDateUpdatedWeekUpdatedMonthUpdatedYearSubmittedDateSubmittedWeekSubmittedMonthSubmittedYearLiteralIdFormIdSiteIdSubmittedByUserId, required
      - `group_by_columns` string[], required — List of column names used for grouping the results
      - `aggregations` AggregationFieldLiteralIdFormIdSiteIdSubmittedByUserId[], required — List of aggregation functions that were applied to produce the results
        - `column` 'id' | 'form_id' | 'site_id' | 'submitted_by_user_id', required — Column name to aggregate
        - `operator` 'sum' | 'avg' | 'count' | 'min' | 'max' | 'count_distinct', required — Supported aggregation operators for SQL GROUP BY queries.
        - `alias` string, nullable — Optional alias for the result column
      - `time_series` TimeSeriesMetadata — Metadata for time-series aggregation results.
        - `time_field` string, required — The time-based column used for grouping (e.g., 'created_month')
        - `granularity` 'date' | 'week' | 'month' | 'year', required — The time granularity of the grouping
        - `category_fields` string[] — Non-time columns used for grouping (e.g., ['status'])

## Other responses

- `400` — Invalid aggregation request
- `403` — Permission denied
- `409` — Integrity Error or Data Conflict
- `422` — Validation Error

---

[API](https://skmtc.dev/salussafety/apis/salus-developer-api.md) · [All operations](https://skmtc.dev/salussafety/apis/salus-developer-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/salussafety/salus-developer-api/revisions/ef065f44da25/schema)
