Metrics

Every partner metric is its own endpoint — GET /api/v1/apps/:app/metrics/:name. With no date parameters you get a point-in-time snapshot (object: "metric") for the latest value; pass a single date for the snapshot as of that day; supplying start_date and/or end_date switches the same URL into a paginated time series (object: "list"). Ranksy exposes 16 metrics. Each block below documents only the parameters, components, and errors that apply to it — the shared path, date, and pagination parameters live in Common parameters, and the two response shapes in Response shapes.


Common parameters

Every metric endpoint takes the same path parameter and the same date / pagination query parameters. The per-endpoint sections only call out the extra parameters specific to that metric (basis, window, currency, excluded_plans).

Path parameter

  • Name
    app
    Type
    string
    Description

    The team app's ULID, e.g. 01JN4HKQX0000000000000000.

Query parameters

  • Name
    date
    Type
    string
    Description

    YYYY-MM-DD. Returns a snapshot as of that day instead of the latest. Mutually exclusive with start_date/end_date (supplying both is a 422).

  • Name
    start_date
    Type
    string
    Description

    YYYY-MM-DD. Supplying start_date and/or end_date switches the response to series mode.

  • Name
    end_date
    Type
    string
    Description

    YYYY-MM-DD. Must be greater than or equal to start_date.

  • Name
    granularity
    Type
    string
    Description

    Series only. One of day (default), week, month. Stock metrics take the bucket's last-day value; flow metrics SUM the bucket; ratios sum their components then divide. (nrr is always monthly and ignores this.)

  • Name
    include_test
    Type
    boolean
    Description

    Acknowledged but has no effect — partner metrics never include Shopify test data. Echoed in metadata.

  • Name
    page
    Type
    integer
    Description

    Series only. The page to return. Default 1.

  • Name
    per_page
    Type
    integer
    Description

    Series only. Points per page. Default 50, maximum 200.

Request

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

Revenue and subscription levels — recurring run-rate, transaction and usage revenue, and the paid-subscription and trial counts behind them.

GET/api/v1/apps/:app/metrics/mrr

Monthly recurring revenue

The app's current monthly recurring revenue. A money metric reported in the app's base payout currency (the currency key). Today's snapshot is recomputed live before the daily job writes; a series is a stock, so each bucket is the value as of its last day — never summed.

Additional parameters

  • Name
    currency
    Type
    string
    Description

    3-letter ISO code. Acknowledged but not converted — values stay in the app's base currency; a mismatch is noted in metadata.currency_note.

No components. Otherwise takes only the common parameters.

Request

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

Snapshot

{
  "object": "metric",
  "id": "mrr",
  "app": "01JN4HKQX0000000000000000",
  "date": "2026-05-29",
  "value": 2331.52,
  "currency": "USD",
  "metadata": { "partner_sync_status": "complete", "currency_basis": "base" }
}

GET/api/v1/apps/:app/metrics/arr

Annual recurring revenue

The app's annual recurring revenue — the current mrr annualised (×12). A money metric in the app's base payout currency. Like MRR it is a stock: a series stamps each bucket with the value as of its last day, never summed.

Additional parameters

  • Name
    currency
    Type
    string
    Description

    3-letter ISO code. Acknowledged but not converted (base currency only); a mismatch is noted in metadata.currency_note.

No components. Otherwise takes only the common parameters.

Request

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

Snapshot

{
  "object": "metric",
  "id": "arr",
  "app": "01JN4HKQX0000000000000000",
  "date": "2026-05-29",
  "value": 27978.24,
  "currency": "USD",
  "metadata": { "partner_sync_status": "complete", "currency_basis": "base" }
}

GET/api/v1/apps/:app/metrics/revenue

Revenue (gross + net)

Transaction revenue in the app's base payout currency. A money breakdown: value is gross revenue (the total transaction value before Shopify's revenue share). components carries the payout breakdown — net (after Shopify's cut), the derived shopify_fee (gross − net), and the per-stream sale flows subscription_revenue / usage_revenue / one_time_revenue (each the summed gross of that sale type). A flow metric — week/month buckets SUM the value and every component. The three streams do not add up to gross: refunds, credits, adjustments and referral transactions also move gross/net/shopify_fee but are not sale streams. Recurring subscription run-rate (MRR) is a point-in-time stock on a different time-basis — get it from the mrr metric, not here.

Additional parameters

  • Name
    currency
    Type
    string
    Description

    3-letter ISO code. Acknowledged but not converted (base currency only).

Components: gross, net, shopify_fee, subscription_revenue, usage_revenue, one_time_revenue.

Request

GET
/api/v1/apps/:app/metrics/revenue
curl -G https://ranksyapp.com/api/v1/apps/01JN4HKQX0000000000000000/metrics/revenue \
  -H "Authorization: Bearer rk_live_..." \
  -d start_date=2026-05-01 \
  -d end_date=2026-05-31 \
  -d granularity=month

Series

{
  "object": "list",
  "url": "/api/v1/apps/01JN4HKQX0000000000000000/metrics/revenue",
  "currency": "USD",
  "page": 1,
  "per_page": 50,
  "total_count": 1,
  "has_more": false,
  "coverage": {
    "requested": { "start": "2026-05-01", "end": "2026-05-31" },
    "available": { "start": "2026-05-01", "end": "2026-05-31" }
  },
  "metadata": {
    "partner_sync_status": "complete",
    "currency_basis": "base",
    "value_note": "value is gross revenue; components.net is after Shopify's cut"
  },
  "data": [
    {
      "date": "2026-05-01",
      "value": 8421.00,
      "components": {
        "gross": 8421.00,
        "net": 6736.80,
        "shopify_fee": 1684.20,
        "subscription_revenue": 7400.00,
        "usage_revenue": 821.00,
        "one_time_revenue": 200.00
      }
    }
  ]
}

GET/api/v1/apps/:app/metrics/usage_revenue

Usage revenue

Metered (usage-based) sale revenue in the app's base payout currency — the same stream that appears as components.usage_revenue in revenue, exposed on its own. A money metric and a flow: a week/month bucket SUMS the daily values; day keeps every row. A snapshot returns the latest stored day.

Additional parameters

  • Name
    currency
    Type
    string
    Description

    3-letter ISO code. Acknowledged but not converted (base currency only).

No components. Otherwise takes only the common parameters.

Request

GET
/api/v1/apps/:app/metrics/usage_revenue
curl -G https://ranksyapp.com/api/v1/apps/01JN4HKQX0000000000000000/metrics/usage_revenue \
  -H "Authorization: Bearer rk_live_..." \
  -d start_date=2026-05-01 \
  -d end_date=2026-05-31 \
  -d granularity=month

Series

{
  "object": "list",
  "url": "/api/v1/apps/01JN4HKQX0000000000000000/metrics/usage_revenue",
  "currency": "USD",
  "page": 1,
  "per_page": 50,
  "total_count": 1,
  "has_more": false,
  "coverage": {
    "requested": { "start": "2026-05-01", "end": "2026-05-31" },
    "available": { "start": "2026-05-01", "end": "2026-05-31" }
  },
  "metadata": { "partner_sync_status": "complete", "currency_basis": "base" },
  "data": [
    { "date": "2026-05-01", "value": 821.00 }
  ]
}

GET/api/v1/apps/:app/metrics/active_subscriptions

Active subscriptions

Point-in-time count of active paid subscriptions. A stock — a series bucket reports the value as of its last day, never summed. No components, no currency. Takes only the common parameters.

Request

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

Snapshot

{
  "object": "metric",
  "id": "active_subscriptions",
  "app": "01JN4HKQX0000000000000000",
  "date": "2026-05-29",
  "value": 214,
  "metadata": { "partner_sync_status": "complete" }
}

GET/api/v1/apps/:app/metrics/active_trials

Active trials

Point-in-time count of subscriptions currently in a trial. A stock — series buckets take the last-day value, never summed. No components, no currency. Takes only the common parameters.

Request

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

Snapshot

{
  "object": "metric",
  "id": "active_trials",
  "app": "01JN4HKQX0000000000000000",
  "date": "2026-05-29",
  "value": 18,
  "metadata": { "partner_sync_status": "complete" }
}

Lifetime value and retention — the dashboard's live LTV, cohort NRR, and trial conversion.

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

Estimated lifetime value (LTV)

The dashboard's live, plan-aware estimated LTV (current ARPU ÷ 30-day churn rate) — computed live, never the lagging stored columns. A money metric. LTV is a point-in-time level, so a series stamps the current value on each bucket (never summed).

Additional parameters

  • Name
    basis
    Type
    string
    Description

    month (default — monthly estimated LTV) or year (that figure annualised, ×12). Any other value returns 400 invalid_basis.

  • Name
    excluded_plans
    Type
    string | string[]
    Description

    Plan names to drop from the calculation — comma-separated (excluded_plans=Free,Trial) or repeated (excluded_plans[]=Free). Mirrors the dashboard LTV page.

  • Name
    currency
    Type
    string
    Description

    3-letter ISO code. Acknowledged but not converted (base currency only).

No components.

Request

GET
/api/v1/apps/:app/metrics/ltv
curl -G https://ranksyapp.com/api/v1/apps/01JN4HKQX0000000000000000/metrics/ltv \
  -H "Authorization: Bearer rk_live_..." \
  -d basis=year \
  -d excluded_plans=Free

Snapshot

{
  "object": "metric",
  "id": "ltv",
  "app": "01JN4HKQX0000000000000000",
  "date": "2026-05-29",
  "value": 612.40,
  "currency": "USD",
  "metadata": {
    "partner_sync_status": "complete",
    "currency_basis": "base",
    "basis": "year",
    "computed": "live",
    "excluded_plans": ["Free"]
  }
}

GET/api/v1/apps/:app/metrics/nrr

Net revenue retention (NRR)

Net revenue retention, cohort-anchored and reported monthly (reuses the dashboard NRR calc). value is a fraction (1.05 = 105%). The snapshot is the trailing-12-month cohort NRR; a series returns one point per month and the granularity parameter has no effect.

Components: mrr_retained, mrr_base, plus the moving parts expansion, contraction, churn, and the derived net_change (expansion − contraction − churn) — all MRR amounts in the app's base currency. The value itself is dimensionless, so there is no currency key. Takes only the common parameters.

Request

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

Snapshot

{
  "object": "metric",
  "id": "nrr",
  "app": "01JN4HKQX0000000000000000",
  "date": "2026-05-29",
  "value": 1.05,
  "components": {
    "mrr_retained": 14962.50,
    "mrr_base": 14250.00,
    "expansion": 1200.00,
    "contraction": 312.50,
    "churn": 175.00,
    "net_change": 712.50
  },
  "metadata": {
    "partner_sync_status": "complete",
    "basis": "cohort",
    "window": "12mo",
    "granularity_note": "NRR is reported monthly; the granularity param has no effect."
  }
}

GET/api/v1/apps/:app/metrics/trial_conversion_rate

Trial conversion rate

Share of trials that convert to a paid subscription, cohort-anchored on the trial-start date (matches the dashboard + MCP). value is a fraction (0.30 = 30%). The snapshot is the trailing-30-day cohort and reads low because that cohort hasn't finished; a week/month series SUMS numerators and denominators then divides — daily rates are never averaged.

Components: trials_converted, trials_started. metadata also carries two supplementary figures for the same window — trials_churned (trials that cancelled without converting) and avg_time_to_convert_days (mean days from trial start to conversion). Takes only the common parameters.

Request

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

Snapshot

{
  "object": "metric",
  "id": "trial_conversion_rate",
  "app": "01JN4HKQX0000000000000000",
  "date": "2026-05-29",
  "value": 0.30,
  "components": { "trials_converted": 30, "trials_started": 100 },
  "metadata": {
    "partner_sync_status": "complete",
    "basis": "cohort",
    "window": "30d",
    "trials_churned": 12,
    "avg_time_to_convert_days": 4.2,
    "window_note": "Snapshot rate is the cohort of trials started in the trailing 30 days; it reads low because that cohort has not finished."
  }
}

Churn — rolling logo and revenue churn from the frozen daily snapshot, plus the churned-shop count.

GET/api/v1/apps/:app/metrics/churn_rate

Customer churn rate

Rolling logo churn rate — the canonical "real churn" calc shared with the dashboard, frozen daily into a snapshot keyed on the Shopify event date (metadata.computed = "stored", never computed live). value is a fraction (0.125 = 12.5%). Overlapping windows are never summed: each series point is the rate as of the bucket's last day.

Additional parameters

  • Name
    window
    Type
    string
    Description

    Rolling-window length: 7d, 30d (default), 90d, 365d. Selects which frozen daily snapshot column is read.

  • Name
    basis
    Type
    string
    Description

    real_churn only (the default and only basis in v1). Any other value returns 400 unsupported_basis.

Components: customers_churned, customers_at_risk — present only for the default 30d window; other windows store the rate alone and omit components (flagged by metadata.components_note).

Request

GET
/api/v1/apps/:app/metrics/churn_rate
curl -G https://ranksyapp.com/api/v1/apps/01JN4HKQX0000000000000000/metrics/churn_rate \
  -H "Authorization: Bearer rk_live_..." \
  -d start_date=2026-04-01 \
  -d end_date=2026-04-30 \
  -d granularity=day \
  -d window=30d

Series

{
  "object": "list",
  "url": "/api/v1/apps/01JN4HKQX0000000000000000/metrics/churn_rate",
  "page": 1,
  "per_page": 50,
  "total_count": 30,
  "has_more": false,
  "coverage": {
    "requested": { "start": "2026-04-01", "end": "2026-04-30" },
    "available": { "start": "2026-04-01", "end": "2026-04-30" }
  },
  "metadata": {
    "partner_sync_status": "complete",
    "basis": "real_churn",
    "computed": "stored",
    "window": "30d",
    "window_note": "Rolling 30d churn, frozen daily snapshot keyed on Shopify event date."
  },
  "data": [
    {
      "date": "2026-04-30",
      "value": 0.042,
      "components": { "customers_churned": 9, "customers_at_risk": 214 }
    }
  ]
}

GET/api/v1/apps/:app/metrics/revenue_churn_rate

Revenue churn rate

Rolling revenue (MRR) churn rate from the same frozen daily snapshot as churn_rate (metadata.computed = "stored"), keyed on the Shopify event date. value is a fraction. Series points take the value as of the bucket's last day — never summed.

Additional parameters

  • Name
    window
    Type
    string
    Description

    Rolling-window length: 7d, 30d (default), 90d, 365d.

  • Name
    basis
    Type
    string
    Description

    real_churn only (the default). Any other value returns 400 unsupported_basis.

Components: mrr_churned — the churned MRR amount behind the rate, present only for the default 30d window. Other windows store the rate alone and omit components (flagged by metadata.components_note).

Request

GET
/api/v1/apps/:app/metrics/revenue_churn_rate
curl -G https://ranksyapp.com/api/v1/apps/01JN4HKQX0000000000000000/metrics/revenue_churn_rate \
  -H "Authorization: Bearer rk_live_..." \
  -d start_date=2026-04-01 \
  -d end_date=2026-04-30 \
  -d window=90d

Series

{
  "object": "list",
  "url": "/api/v1/apps/01JN4HKQX0000000000000000/metrics/revenue_churn_rate",
  "page": 1,
  "per_page": 50,
  "total_count": 30,
  "has_more": false,
  "coverage": {
    "requested": { "start": "2026-04-01", "end": "2026-04-30" },
    "available": { "start": "2026-04-01", "end": "2026-04-30" }
  },
  "metadata": {
    "partner_sync_status": "complete",
    "basis": "real_churn",
    "computed": "stored",
    "window": "90d",
    "window_note": "Rolling 90d churn, frozen daily snapshot keyed on Shopify event date."
  },
  "data": [
    { "date": "2026-04-30", "value": 0.038 }
  ]
}

GET/api/v1/apps/:app/metrics/churned_total

Churned merchants

Count of distinct paying shops that churned in the trailing 30 days as of each date — a rolling window, not a per-day count (metadata.window = "30d"). A stock: series buckets report the value as of the bucket's last day; do not sum across days. No components, no currency. Takes only the common parameters.

Request

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

Snapshot

{
  "object": "metric",
  "id": "churned_total",
  "app": "01JN4HKQX0000000000000000",
  "date": "2026-05-29",
  "value": 9,
  "metadata": {
    "partner_sync_status": "complete",
    "window": "30d",
    "window_note": "churned_total is the count of distinct paying shops that churned in the trailing 30 days as of each date — a rolling window, not a per-day count."
  }
}

Installs and merchants — daily install flows and the active-merchant stock.

GET/api/v1/apps/:app/metrics/installs

Installs

Daily app installs. A flow count — a week/month bucket SUMS the daily installs (dated to the bucket's last day); day keeps every row. A snapshot returns the latest stored day's value. No components, no currency. Takes only the common parameters.

Request

GET
/api/v1/apps/:app/metrics/installs
curl -G https://ranksyapp.com/api/v1/apps/01JN4HKQX0000000000000000/metrics/installs \
  -H "Authorization: Bearer rk_live_..." \
  -d start_date=2026-05-01 \
  -d end_date=2026-05-31 \
  -d granularity=week

Series

{
  "object": "list",
  "url": "/api/v1/apps/01JN4HKQX0000000000000000/metrics/installs",
  "page": 1,
  "per_page": 50,
  "total_count": 5,
  "has_more": false,
  "coverage": {
    "requested": { "start": "2026-05-01", "end": "2026-05-31" },
    "available": { "start": "2026-05-01", "end": "2026-05-31" }
  },
  "metadata": { "partner_sync_status": "complete" },
  "data": [
    { "date": "2026-05-04", "value": 41 },
    { "date": "2026-05-11", "value": 38 }
  ]
}

GET/api/v1/apps/:app/metrics/uninstalls

Uninstalls

Daily app uninstalls. A flow count — a week/month bucket SUMS the daily uninstalls; day keeps every row. No components, no currency. Takes only the common parameters.

Request

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

Snapshot

{
  "object": "metric",
  "id": "uninstalls",
  "app": "01JN4HKQX0000000000000000",
  "date": "2026-05-29",
  "value": 6,
  "metadata": { "partner_sync_status": "complete" }
}

GET/api/v1/apps/:app/metrics/reactivations

Reactivations

Daily reinstalls by shops that had previously uninstalled. A flow count — a week/month bucket SUMS the daily values; day keeps every row. No components, no currency. Takes only the common parameters.

Request

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

Snapshot

{
  "object": "metric",
  "id": "reactivations",
  "app": "01JN4HKQX0000000000000000",
  "date": "2026-05-29",
  "value": 3,
  "metadata": { "partner_sync_status": "complete" }
}

GET/api/v1/apps/:app/metrics/active_merchants

Active merchants

Point-in-time count of active (paying) merchants. The value is a stock — series buckets take the last-day value, never summed. components adds the period's flows: new activations and churned, plus the derived net_change (new − churned) — these do SUM across a week/month bucket. No currency.

Components: new, churned, net_change.

Request

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

Snapshot

{
  "object": "metric",
  "id": "active_merchants",
  "app": "01JN4HKQX0000000000000000",
  "date": "2026-05-29",
  "value": 1284,
  "components": { "new": 22, "churned": 9, "net_change": 13 },
  "metadata": { "partner_sync_status": "complete" }
}

Response shapes

Two shapes, selected by whether you pass dates. Money series declare currency once on the envelope — never per point.

Snapshot (object: "metric")

  • Name
    object
    Type
    string
    Description

    Always "metric".

  • Name
    id
    Type
    string
    Description

    The metric name, e.g. mrr.

  • Name
    app
    Type
    string
    Description

    The app ULID.

  • Name
    date
    Type
    string
    Description

    The date the value is current as of (YYYY-MM-DD) — the requested date, or the latest available day when none was given.

  • Name
    value
    Type
    number
    Description

    The metric value. For ratios this is a fraction (e.g. 0.30), not a percentage.

  • Name
    currency
    Type
    string
    Description

    Present only for money metrics; the app's base payout currency.

  • Name
    components
    Type
    object
    Description

    Present only for ratio and breakdown metrics; the raw inputs behind value.

  • Name
    metadata
    Type
    object
    Description

    Partner-sync health (partner_sync_status, currency_basis) plus any per-metric notes.

Series (object: "list")

  • Name
    object
    Type
    string
    Description

    Always "list".

  • Name
    url
    Type
    string
    Description

    The endpoint path for this metric.

  • Name
    currency
    Type
    string
    Description

    Present only for money metrics; applies to every point in data.

  • Name
    page
    Type
    integer
    Description

    The current page number.

  • Name
    per_page
    Type
    integer
    Description

    Points per page.

  • Name
    total_count
    Type
    integer
    Description

    Total number of points across all pages.

  • Name
    has_more
    Type
    boolean
    Description

    Whether further pages exist.

  • Name
    coverage
    Type
    object
    Description

    What was requested vs what was available. available is null when there is no data in range.

  • Name
    metadata
    Type
    object
    Description

    Partner-sync health plus per-metric notes.

  • Name
    data
    Type
    array
    Description

    The series points.

Point

Series points are compact — no per-row object tag and no per-row currency.

  • Name
    date
    Type
    string
    Description

    The bucket date (YYYY-MM-DD); for week/month, the bucket's last day.

  • Name
    value
    Type
    number
    Description

    The value for that bucket. Ratios are fractions.

  • Name
    components
    Type
    object
    Description

    Present only for ratio and breakdown metrics.

Coverage

coverage tells the caller exactly how much data was available versus requested, so a short or empty result is never ambiguous.

coverage

"coverage": {
  "requested": { "start": "2026-03-01", "end": "2026-05-29" },
  "available": { "start": "2026-03-01", "end": "2026-05-29" }
}

Pagination

Series responses are paginated. Use page and per_page (default 50, max 200) to walk the result set, and check has_more / total_count to know when to stop. The currency and metadata on the envelope apply to every page.


Errors

Beyond the universal 401 / 403 / 422 / 429 (see Errors), the metric endpoints return:

  • 409 — the app's Shopify Partner integration isn't usable. error.code is partner_integration_not_connected (never connected), partner_integration_unauthorized (credentials revoked or rejected — reconnect in Ranksy), or partner_integration_pending (first sync still running — retry shortly). Every metric returns this until the integration is connected and has synced. Metrics never read BigQuery, so a BigQuery error is never returned here.
  • 400 invalid_basis — on ltv only: basis must be month or year. error.param is basis.
  • 400 unsupported_basis — on churn_rate / revenue_churn_rate only: basis must be real_churn. error.param is basis.

Of the 16 metrics, only ltv, churn_rate, and revenue_churn_rate accept a rejectable basis. Every other endpoint has a route-fixed name and no basis, so it never returns 400 — a bad query parameter surfaces as 422 instead.


Things to keep in mind

  • Ratio value is a fraction, not a percentage. 0.30 means 30%; the raw inputs live in components.
  • Money metrics carry currency once. Inline on a snapshot, once on a series envelope — never on individual points. Values are always in the app's base payout currency (v1 does not convert).
  • Stock vs flow vs ratio. Stock metrics take the bucket's last-day value; flow metrics SUM the bucket; ratios SUM their components then divide. Rolling-window metrics (churned_total, churn_rate, revenue_churn_rate) overlap day-to-day and are never summed.
  • coverage is your source of truth for how much data backed a series response.

Was this page helpful?