/api/v1/facts/aggregateAggregate XBRL facts across companies.
Aggregate XBRL facts across companies. Reduces a concept across a filter set (sector, ticker list, period) and returns sum / avg / median / count statistics.
10 tokensSince v3.4.0
Why use this
Cross-company aggregation of one XBRL concept across a filter set — pass `concept` + `period` + optional sector / ticker-list filters and receive `sum`, `avg`, `median`, `count`, `min`, `max` in one shot. The right endpoint for sector-wide research workflows like 'median capex / revenue across S&P 500 Industrials in 2025', 'total reported revenue across all reporting companies in Q4 2025', or 'distribution of book-value-per-share across Healthcare names'. Pair with `/facts/by-concept` when you need the underlying row-level data; pair with `/financials/screen` when you want filter-then-rank workflows on standardized ratios. The 10-token cost reflects the heavy multi-row reduction.
Cross-company aggregation of XBRL facts — pass a concept + filter set (sector, ticker list, period) and receive sum / avg / median / count statistics. Useful for sector-wide research like "median capex / revenue across S&P 500 Industrials in 2025".
Parameters
| Name | In | Required | Default | Allowed | Description | Example |
|---|---|---|---|---|---|---|
| concept | body | required | — | — | XBRL concept name in `prefix:LocalName` format (e.g. `us-gaap:Revenues`, `us-gaap:NetIncomeLoss`). Same concept syntax as `/facts/by-concept`. Returns 400 for unknown concepts. | us-gaap:Revenues |
| period | body | required | — | — | Period filter — accepts (a) exact ISO `YYYY-MM-DD` for a specific period-end date, or (b) `YYYY-Q1`/`YYYY-Q2`/`YYYY-Q3`/`YYYY-Q4` for fiscal-quarter rollup, or (c) `YYYY` for full-year (annual filings only). Calendar-year scope; for fiscal-year offsets (companies with non-calendar fiscal years) use `/facts/by-concept` and aggregate client-side. | 2025-12-31 |
| sector | body | optional | — | — | Sharadar sector filter (e.g. `Technology`, `Healthcare`, `Industrials`). Default: aggregate across all sectors. Excludes companies unmapped in Sharadar (~5% of universe). | Technology |
| tickers | body | optional | — | — | Array of ticker strings to restrict the aggregation to (max 500 entries). Useful for index-defined cohort aggregations (e.g. 'aggregate over the S&P 500'). Mutually exclusive with `sector` — pass one or the other, not both. | ["AAPL","MSFT","GOOGL"] |
Response schema
| Field | Type | Nullable | Description |
|---|---|---|---|
| concept | string | no | Concept name echoed back. Useful for asserting your client passed the concept correctly. |
| period | string | no | Period filter echoed back as ISO date / quarter-string / year-string (whichever form was passed). Useful for chart annotations. |
| aggregates | object | no | Computed aggregate statistics across all facts matching the filter set. All fields use the most-common unit across contributing facts (e.g. `USD` is preferred over `USD-thousands`); units are NOT auto-converted — when the contributing facts have mixed units, the aggregation falls back to filtering by majority-unit and excluding the minority. Use `count` to detect when this happened. |
| aggregates.sum | number | yes | Sum across all matching fact values (in the dominant unit). Useful for total-revenue-style aggregates. Null when no facts match the filter set OR when all values are null. |
| aggregates.avg | number | yes | Arithmetic mean across matching facts. Useful for sector-average analysis. Null when count=0. Note: not weighted — for revenue-weighted averages, run two queries (numerator-aggregated + denominator-aggregated) and divide. |
| aggregates.median | number | yes | Median (50th percentile) across matching facts. Useful for distribution-center analysis on heavy-tailed concepts where mean is skewed by outliers (e.g. revenue distributions are typically log-normal — median is the better center metric than mean). Null when count=0. |
| aggregates.count | integer | no | Number of facts contributing to the aggregation. Always non-negative. Use to detect filter-too-narrow cases (count=0 means no matches; count<10 means small sample warrants caution). |
| aggregates.min | number | yes | Minimum value across matching facts. Useful for identifying outlier candidates (lowest reported revenue in sector, smallest cap-ex spend). Null when count=0. |
| aggregates.max | number | yes | Maximum value across matching facts. Useful for identifying top-of-distribution outliers. Null when count=0. |
| meta | object | no | Filter echo block: `{ sector: string, tickers: array, period: string, dominant_unit: string, excluded_count: integer }`. `excluded_count` flags facts that were skipped due to unit mismatch — when non-zero, suggests you should filter your input cohort to a single-unit subset for cleaner aggregation. |
Sample response
·
- "concept": "us-gaap:Revenues"
- "period": "2025-12-31"
- "aggregates":
- "sum": 12400000000000
- "avg": 24800000000
- "median": 1820000000
- "count": 500
- "min": 50000000
- "max": 391035000000
- "meta":
- "sector": "all"
- "period": "2025-12-31"
Errors
| Status | Label | Description |
|---|---|---|
| 200 | OK | Request succeeded. |
| 400 | Bad Request | Invalid query, body, or path parameter. |
| 401 | Unauthorized | Missing or invalid Authorization header / api_Token. |
| 402 | Payment Required | Insufficient token balance for this call. Top up |
| 429 | Too Many Requests | Rate limit exceeded for your tier (see /pricing for tier limits). Tier limits |
| 500 | Server Error | Unexpected server-side failure. Retry with backoff; report if persistent. |
Code samples
curl -X POST "https://api.finradar.ai/api/v1/facts/aggregate?api_Token=YOUR_API_KEY" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"Generate an API key in /account/credentials to run live queries (literal YOUR_API_KEY placeholder shown until then).