---
title: "Returns calendar (run_id comes from GET /v1/backtests/{id})"
method: GET
path: "/v1/runs/{runId}/monthly-returns"
---

# Returns calendar (run_id comes from GET /v1/backtests/{id})

`GET /v1/runs/{runId}/monthly-returns`

## Request

- Base URL: `https://app.texttoquant.com/api`
- URL: `https://app.texttoquant.com/api/v1/runs/{runId}/monthly-returns`
- Auth: one of:
  - API key in header `x-api-key`
  - HTTP bearer

Period over period returns as a grid: rows x columns plus a compounded row total, with best/worst cell and the green cell rate. Computed from the FULL equity curve, never paged, because a partial window would compute a different grid. The bucket ADAPTS: decades when the run is too long to show by month, months from half a year up, otherwise days, otherwise hours, and never finer than the bar interval. Read `granularity` before interpreting a cell. `columns` labels the cells left to right; `totalLabel` names the trailing total (DECADE/YTD/MTD/DAY). The run's first bucket measures from inception and is therefore partial. `data` is null when the run is too short to grid at any bucket.

## Path parameters

- `runId` string, uuid, required

## Query parameters

- `granularity` 'year' | 'month' | 'day' | 'hour'

## Response `200`

Success

- object
  - `success` true, required
  - `data` object, nullable, required
    - `granularity` 'year' | 'month' | 'day' | 'hour'
    - `totalRows` integer: Rows the data produced; equals rows.length unless a display bound applied.
    - `basis` string
    - `columns` string[]: Column headers left to right: Jan..Dec, 1..31, or 00..23.
    - `totalLabel` 'YTD' | 'MTD' | 'DAY'
    - `rows` object[]
      - `label` string: Row label: "2024" | "Mar 2024" | "12 Mar".
      - `cells` number[]: Return in percent per column; null where the curve has no point there.
      - `totalPct` number, nullable: The row's cells compounded.
    - `bestCell` object, nullable
      - `cell` string
      - `pct` number
    - `worstCell` object, nullable
      - `cell` string
      - `pct` number
    - `greenCells` integer: Cells that closed above where they opened.
    - `redCells` integer: Cells that closed below.
    - `flatCells` integer: Cells the curve covered but the strategy never moved through: no position, and so no outcome to be green or red about. On a selective strategy this is most of the calendar.
    - `activeCells` integer: greenCells + redCells. The denominator for greenRatePct.
    - `totalCells` integer: greenCells + redCells + flatCells.
    - `greenRatePct` number, nullable: Green share of the ACTIVE cells, not of the calendar. A strategy in the market one day in four is not "green 19% of the time"; it is green 19% of all days and 69% of the days it held a position, and only the second is a statement about the strategy.
    - `seasonality` object, nullable: Whether one slice of the calendar (day of week for a daily grid, month of year for a monthly one, hour of day for an hourly one) differs from the typical slice by more than chance produces. Carries `headline` (the finding as a sentence, with its own evidence), `basis` (how to read it), `method`, and per group means, q values and verdicts. A null `verdict` is a REFUSAL for want of sample. Report it as "no verdict", never as "no effect". Null for a decade grid, which has no season.

## Other responses

- `404`: not_found (run not owned, expired, or no equity curve)

---

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