GET /api/agent/cohorts/retention
Returns the FULL acquisition-month × period-offset cohort grid — the raw matrix behind the analytics heatmap. Project the cells via ?metric=retention|customers|revenue (default retention). ?periods= (1–24, default 12) caps the number of offset columns. The not-yet-elapsed sentinel (null) is preserved verbatim for every metric, so an agent can tell 'offset has not happened yet' apart from a real churned-to-zero. granularity=week is reserved for a v2 weekly-cohort build and returns 400 until then. Cohorts aggregate by acquisition month — no per-contact PII is on the wire (redactedItemCount is always 0) and the matrix carries no notesForAgent (use /api/agent/cohorts/summary for narrative insight).
Auth
- Required scope:
READ_SUMMARY - Header:
Authorization: Bearer cr_live_<prefix>_<secret>
Query parameters
| Name | Type | Required | Notes |
|---|---|---|---|
metric | string | no | Which metric cohorts[].values[] is projected into. Default retention. |
periods | integer | no | Number of offset columns to return (1–24). Clamped to range; the underlying matrix is capped at 12 columns, so over-asking is a no-op. Default 12. |
Responses
200 — Cohort retention matrix
Body: CohortRetentionResponse
| Field | Type | Required | Notes |
|---|---|---|---|
asOfDate | string (date) | yes | |
currency | string | yes | |
metric | string · one of retention customers revenue | yes | Which metric cohorts[].values[] is projected into. retention (default) = survival fraction 0–1; customers = distinct transacting customers (integer); revenue = cohort revenue as a canonical decimal string. |
periodLabels | array of string | yes | Column headers for the offset grid, e.g. ["M0","M1",…]. Length matches each cohort's values length (capped by ?periods=). |
cohorts | array of CohortRetentionRow | yes | |
redactedItemCount | integer | yes | Always 0 — cohorts aggregate by acquisition month, so no per-contact name is ever masked. |
notesForAgent | array of AgentNote | yes | Always empty for the raw matrix — use /cohorts/summary for narrative insight. |
400 — Unsupported request — e.g. granularity=week (weekly cohorts are a v2 build and not yet available).
Body: ErrorResponse
| Field | Type | Required | Notes |
|---|---|---|---|
error | string | yes |
401 — Unauthorized
Body: ErrorResponse
| Field | Type | Required | Notes |
|---|---|---|---|
error | string | yes |
403 — Key lacks the required scope
Body: ErrorResponse
| Field | Type | Required | Notes |
|---|---|---|---|
error | string | yes |
429 — Rate-limited or quota-exhausted
Body: ErrorResponse
| Field | Type | Required | Notes |
|---|---|---|---|
error | string | yes |
Response headers
Every successful response carries X-CashRunway-Subscription, X-CashRunway-Plan, X-CashRunway-Quota-Remaining, and X-CashRunway-Quota-Reset. Trialing subscriptions also include X-CashRunway-Trial-Days-Remaining. See the overview for details.