LTV cohorts

A single endpoint returns per-acquisition-cohort lifetime value as a paginated object: "list" — GET /api/v1/apps/:app/ltv/cohorts. Each row is one install month, with the cohort's customer count and its average / median / total lifetime revenue. Monetary values share one base payout currency, declared once on the envelope.


GET/api/v1/apps/:app/ltv/cohorts

LTV cohorts

Per-acquisition-cohort lifetime value — one row per install month, with the cohort's customer count and its average / median / total lifetime revenue. This is the cohort detail behind the aggregate ltv metric: LTV per shop is SUM(gross_amount) over its real paid transactions, and the cohort is the month a shop first installed. Rows are ordered oldest cohort first.

Monetary values share one base payout currency, declared once on the envelope's currency key (never per row). Only pagination parameters are accepted — the breakdown is a full computed set.

Path parameter

  • Name
    app
    Type
    string
    Description

    The team app's ULID.

Query parameters

  • Name
    page
    Type
    integer
    Description

    Page to return. Default 1.

  • Name
    per_page
    Type
    integer
    Description

    Cohorts per page. Default 100, maximum 100.

Request

GET
/api/v1/apps/:app/ltv/cohorts
curl https://ranksyapp.com/api/v1/apps/01JN4HKQX0000000000000000/ltv/cohorts \
  -H "Authorization: Bearer rk_live_..."

Response

{
  "object": "list",
  "url": "/api/v1/apps/01JN4HKQX0000000000000000/ltv/cohorts",
  "currency": "USD",
  "page": 1,
  "per_page": 100,
  "total_count": 18,
  "has_more": false,
  "metadata": {
    "summary": { "total_cohorts": 18 },
    "value_note": "LTV is per-shop SUM(gross_amount) over real paid transactions; cohort = the month a shop first installed. Amounts are in the app's base payout currency."
  },
  "data": [
    {
      "cohort": "2026-01",
      "customers": 42,
      "average_ltv": 184.5,
      "median_ltv": 96.0,
      "total_revenue": 7749.0
    },
    {
      "cohort": "2026-02",
      "customers": 51,
      "average_ltv": 132.4,
      "median_ltv": 72.0,
      "total_revenue": 6752.4
    }
  ]
}

LTV cohorts decompose the aggregate ltv series in the revenue metrics.


Response shape

The standard object: "list" envelope. This list is not date-windowed in the series sense, so there is no coverage block. Unlike subscriptions and transactions, the currency key sits on the envelope and applies to every row.

  • Name
    object
    Type
    string
    Description

    Always "list".

  • Name
    url
    Type
    string
    Description

    The endpoint path.

  • Name
    currency
    Type
    string
    Description

    Base-currency ISO code. Applies to every row's monetary values.

  • Name
    page
    Type
    integer
    Description

    Current page number.

  • Name
    per_page
    Type
    integer
    Description

    Rows per page.

  • Name
    total_count
    Type
    integer
    Description

    Total cohorts across all pages.

  • Name
    has_more
    Type
    boolean
    Description

    Whether further pages exist.

  • Name
    metadata
    Type
    object
    Description

    Carries summary.total_cohorts and a value_note describing the calculation.

  • Name
    data
    Type
    array
    Description

    The cohort rows for this page.

Cohort row

  • Name
    cohort
    Type
    string
    Description

    The install month (YYYY-MM) the shops in this cohort first installed.

  • Name
    customers
    Type
    integer
    Description

    Number of shops in the cohort.

  • Name
    average_ltv
    Type
    number
    Description

    Average lifetime revenue per shop, in the envelope currency.

  • Name
    median_ltv
    Type
    number
    Description

    Median lifetime revenue per shop, in the envelope currency.

  • Name
    total_revenue
    Type
    number
    Description

    Total lifetime revenue for the cohort, in the envelope currency.


Pagination

Walk the result set with page and per_page (default 100, maximum 100), and check has_more / total_count to know when to stop. The envelope currency and metadata apply to every page.


Errors

Beyond the universal 401 / 403 / 422 / 429 (see Errors), this endpoint returns:

  • 409 — the app's Shopify Partner integration isn't usable: partner_integration_not_connected, partner_integration_unauthorized (reconnect in Ranksy), or partner_integration_pending (first sync still running — retry shortly).

A bad query parameter (out-of-range per_page) surfaces as a 422.

Was this page helpful?