---
title: "Get Category Analytics"
method: POST
path: "/api/portfolio/category-analytics"
tags: ["Portfolio Analytics"]
---

# Get Category Analytics

`POST /api/portfolio/category-analytics`

## Request

- Base URL: `https://api.harmoney.in`
- URL: `https://api.harmoney.in/api/portfolio/category-analytics`
- Auth: API key in header `x-api-key`

One fund against its AMFI category cohort — percentile band and ranks.

## Request body

- CategoryAnalyticsRequest: Request body for POST /api/portfolio/category-analytics. * **Mode A** — ``as_of`` + ``horizon``. * **Mode B** — ``start_date`` + ``end_date``.
  - `instrument_id` string, required: ``unique_id`` of the fund being compared to its category.
  - `metrics` string[]: Scalar metrics to rank the fund on. Defaults to all.
  - `trailing_horizons` string[]: Trailing horizons to rank the cohort over, anchored on the window end. Opt-in: empty (the default) skips the work and the extra NAV history it needs.
  - `discrete_frequencies` string[]: Calendar cadences to rank the cohort over, one stat per bucket. Opt-in, and a list so a caller offering the cadence as a UI toggle can switch without a second request.
  - `include_aum` boolean: Add ``aum_series`` — daily AUM for each reference fund plus the category total. Opt-in: it is a second timeseries fetch over the whole cohort, which a caller not drawing that chart should not pay.
  - `benchmark_id` string: unique_id of the instrument beta / treynor / up_capture / down_capture are measured against, for every cohort member. There is no default: without it those four metrics are null rather than silently measured against an index the caller never chose.
  - `as_of` string, date: Mode A: window end
  - `horizon` '1M' | '3M' | '6M' | 'YTD' | '1Y' | '3Y' | '5Y' | '10Y' | 'MAX': Mode A: window size back from ``as_of``
  - `start_date` string, date: Mode B: window start
  - `end_date` string, date: Mode B: window end

## Response `200`

Successful Response

- CategoryAnalyticsResponse
  - `instrument_id` string, required
  - `instrument_name` string, required
  - `category` string, required
  - `category_code` string, required
  - `plan_type` string, required
  - `requested_start` string, date, required
  - `requested_end` string, date, required
  - `effective_start` string, date, required
  - `effective_end` string, date, required
  - `cohort_size` integer, required: Cohort members with usable NAV history.
  - `benchmark_name` string
  - `dates` string[]
  - `series` CohortSeries[]
    - `key` 'selected' | 'max_aum' | 'top_performer' | 'median_performer' | 'bottom_performer', required
    - `label` string, required
    - `instrument_id` string: ``None`` when the cohort had nobody to resolve.
    - `instrument_name` string
    - `aum_crores` number
    - `window_return` number: The series' return over the effective window, annualized when that window is a year or longer (same rule as ``annualised_return``). The `points` remain cumulative.
    - `points` number[], required
  - `aum_series` AumSeries[]: Empty unless ``include_aum``. Aligned to ``dates``.
    - `key` 'selected' | 'max_aum' | 'top_performer' | 'median_performer' | 'bottom_performer' | 'category_total', required
    - `label` string, required
    - `instrument_id` string: ``None`` for ``category_total``.
    - `instrument_name` string
    - `funds` integer: Distinct funds behind ``category_total``; ``None`` otherwise.
    - `points` number[], required
  - `metric_stats` MetricStat[]
    - `metric` 'annualised_return' | 'volatility' | 'sharpe' | 'sortino' | 'max_drawdown' | 'beta' | 'treynor' | 'up_capture' | 'down_capture', required
    - `label` string, required
    - `unit` 'pct' | 'ratio', required
    - `selected` number, required
    - `rank` integer: Dense rank of the selected fund within the cohort — 1 is best, which is the lowest value for volatility / downside capture and the highest value for everything else.
    - `out_of` integer, required: Cohort members with a value for this metric.
    - `by_series` object: The same metric for each reference series, keyed by series key.
    - `rank_by_series` object: Where each reference series' value stands in the cohort, on the same dense-rank scale and out of the same ``out_of``.
  - `trailing_rank_stats` TrailingRankStat[]
    - `horizon` '1M' | '3M' | '6M' | 'YTD' | '1Y' | '3Y' | '5Y' | '10Y', required
    - `out_of` integer, required: Cohort members with a return over this horizon.
    - `rank` integer: Dense rank of the selected fund over this horizon, 1 = best.
    - `by_series` object: Each fund series' trailing return over this horizon, on the same annualisation rule as ``trailing_return``.
    - `rank_by_series` object: Each fund series' rank over this horizon, out of ``out_of``. ``None`` where the fund has no return for the horizon — no rank, never a last place.
  - `discrete_rank_stats` DiscreteRankStat[]
    - `frequency` 'monthly' | 'quarterly' | 'annual', required
    - `period_start` string, date, required
    - `period_end` string, date, required: Bucket end — the caller's column key.
    - `out_of` integer, required: Cohort members with a return in this bucket.
    - `rank` integer: Dense rank of the selected fund in this bucket, 1 = best.
    - `by_series` object
    - `rank_by_series` object: ``None`` where the fund has no return for the bucket — no rank, never a last place.
  - `members` CohortMember[]
    - `instrument_id` string, required
    - `instrument_name` string
    - `aum_crores` number
    - `metrics` object
  - `null_reason` string

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/inferedge/apis/india-mutual-funds-data-feed.md) - [All operations](https://skmtc.dev/inferedge/apis/india-mutual-funds-data-feed/llms.txt) - [OpenAPI document](https://skmtc.dev/inferedge/apis/india-mutual-funds-data-feed/revisions/fe0d3be721c0?raw)
