---
title: "Aggregate attack surface assets"
method: POST
path: "/v1/attacksurfaces/{attack_surface_id}/aggregate"
tags: ["Exposure Management"]
---

# Aggregate attack surface assets

`POST /v1/attacksurfaces/{attack_surface_id}/aggregate`

## Request

- Base URL: `https://api.platform.censys.io`
- URL: `https://api.platform.censys.io/v1/attacksurfaces/{attack_surface_id}/aggregate`
- Auth: HTTP bearer

Aggregate the assets of your attack surface by a given field.<br><br>This functionality is equivalent to the [Report Builder](https://docs.censys.com/docs/platform-report-builder/) in the Platform UI.

## Path parameters

- `attack_surface_id` string, required: The ID of the attack surface, or the literal 'default' for your organization's attack surface. Obtain the attack surface ID using the list attack surfaces endpoint.

## Query parameters

- `organization_id` string, uuid, required: The ID of a Censys organization to associate the request with. See the [Getting Started docs](https://docs.censys.com/reference/get-started#step-3-find-and-use-your-organization-id-optional) for more information.

## Headers

- `X-Organization-ID` string, uuid: The ID of a Censys organization to associate the request with. See the [Getting Started docs](https://docs.censys.com/reference/get-started#step-3-find-and-use-your-organization-id-optional) for more information. Note: The header parameter is supported for atypical use cases; we recommend always providing this field via the query parameter.

## Request body

- SearchAggregateInputBody
  - `count_by_level` string: Specifies which document level's count is returned per term bucket, primarily for nested fields. This is the same functionality available in the Count By dropdown in the Report Builder UI. When aggregating on nested fields like 'host.services.port': empty string (default) counts documents at the deepest level containing the field; '.' counts root documents (e.g. counts matching 'host'); 'host.services' counts documents at the specified nested level.
  - `field` string, required: field to aggregate by
  - `filter_by_query` boolean: Controls whether aggregation results are limited to values that match the query. When true, only field values that satisfy the query constraints are included in aggregation counts. When false, aggregation includes all field values from records that match the query, even if those specific field values don't match the query constraints. For example, if the query is 'host.services.protocol=SSH' and you are aggregating by 'host.services.port' - when true, only shows SSH ports; when false, shows all ports on hosts that have SSH services.
  - `number_of_buckets` integer, required: number of buckets to split results into
  - `query` string, required: CenQL query string to search upon

## Response `200`

Assets aggregated successfully

- ResponseEnvelopeAttackSurfaceAggregateResponse
  - `result` AttackSurfaceAggregateResponse
    - `buckets` AttackSurfaceAggregateBucket[], required: The aggregated buckets, one per distinct field value.
      - `count` integer, required: The number of matching documents with this field value, counted at the level set by count_by_level. By default that is the nested level of the field, so aggregating host.services.port counts services rather than hosts; set count_by_level to '.' to count hosts, web properties or certificates.
      - `key` string, required: The value of the aggregated field for this bucket.
    - `is_more_than_total_hits` boolean, required: Whether the number of matching assets exceeds the accurately tracked hit count, meaning total_count is a lower bound rather than an exact value.
    - `other_count` integer, required: The number of documents in buckets that were not returned, counted at the nested level of the field. This is a document count, not a number of distinct assets. It is always 0 when count_by_level counts at a different level than the field, so a 0 does not mean every bucket was returned.
    - `query_duration_millis` integer, required: The time, in milliseconds, the query took to execute.
    - `total_count` integer, required: The total number of assets matching the query.

## Other responses

- `400`: Invalid arguments
- `401`: Request does not contain a valid Authorization token
- `403`: User does not have permission to access this data
- `404`: Attack surface not found
- `409`: The Exposure Management API is not enabled, or the operation conflicts with the attack surface's current state.
- `422`: Invalid query or inputs
- `500`: Internal server error

## Changes

- **2026-11-03** `ec1686b0a36a`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/censys/apis/censys-platform-api/changes/v1/attacksurfaces/:attack_surface_id/aggregate/post.md)

---

[API](https://skmtc.dev/censys/apis/censys-platform-api.md) - [All operations](https://skmtc.dev/censys/apis/censys-platform-api/llms.txt) - [OpenAPI document](https://skmtc.dev/censys/apis/censys-platform-api/revisions/ec1686b0a36a?raw)
