---
title: "Aggregate Certificates"
method: POST
path: "/v1/certificate/aggregate"
tags: ["Certificates"]
---

# Aggregate Certificates

`POST /v1/certificate/aggregate`

Aggregate certificates with GROUP BY operations.

Allows grouping by status, type, 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

- CertificateAggregationModel — Request model for certificate aggregation queries. Note: Certificates use 'archived' parameter (not 'is_archived') to match the search_certificates endpoint for consistency.
  - `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` AggregationFieldLiteralIdUserId[], required — Aggregation functions to apply
    - `column` 'id' | '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' — Column to apply date_start/date_cut_off filters on (created_at or updated_at)
  - `is_archived` boolean, nullable — Not used for certificates. Use 'archived' parameter instead.
  - `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.
  - `archived` boolean, nullable — Filter by archived status. Defaults to False (only active certificates). Use None to include all.
  - `expired` boolean, nullable — Filter by expiry status before aggregating. True = only expired, False = only not-expired, None = include all.
  - `expiry_date_from` string, date-time, nullable — Filter certificates with expiry_date on or after this date (inclusive) before aggregating.
  - `expiry_date_to` string, date-time, nullable — Filter certificates with expiry_date strictly before this date (exclusive) before aggregating.
  - `user_id` integer, nullable — Filter to certificates for a specific user.
  - `company_certification_type_id` integer, nullable — Filter to certificates with a specific company certification type ID.

## Response `200`

Successful Response

- ApiGenericResponseCertificateAggregationResponse
  - `error` boolean — A boolean error indicator.
  - `message` string, nullable — Optional message.
  - `data` CertificateAggregationResponse — Response model for certificate 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` AggregationMetadataLiteralCompanyCertificationTypeIdApprovedOfflineUserIdArchivedExpiredCreatedDateCreatedWeekCreatedMonthCreatedYearUpdatedDateUpdatedWeekUpdatedMonthUpdatedYearLiteralIdUserId, required
      - `group_by_columns` string[], required — List of column names used for grouping the results
      - `aggregations` AggregationFieldLiteralIdUserId[], required — List of aggregation functions that were applied to produce the results
        - `column` 'id' | '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)
