CLI command
analytics ltv
Read realised revenue per paying subject with a linear and a decay lifetime-value forecast for one segment of RevenueCat or Stripe payments.
Invocation#
echo-cli analytics ltv --source revenuecat|stripe --app <app-id|web source> --environment <name> --history-days <days> --horizon-days <days> [--product <id>] [--store <store>]Inputs and output#
The result names source, app_id, environment, the segment filters given, history_days, horizon_days, since, events_read and unattributed_events (payments naming no subject), the method and decay_method sentences, and per currency: subjects, realised_net_revenue, realised_per_subject, daily_per_subject, forecast_ltv_per_subject, decay (first_half_daily_per_subject, second_half_daily_per_subject, daily_factor, forecast_ltv_per_subject and unmeasured — why the decay forecast could not be made, or null) and each subject's realised net revenue. For --source revenuecat a subject is RevenueCat's original_app_user_id, else app_user_id; for --source stripe it is the user id the payment's metadata named, else its anonymous id. Net revenue is revenue less refund_amount. The linear forecast spreads the realised net revenue per subject over the history days, carries it over the horizon days and adds it to what is realised. The decay forecast measures how revenue per subject changed: the daily net revenue per subject of the history's second half over its first half, to the power one over half the history days, is a daily factor; each horizon day t adds the second half's daily rate times the factor to the t-th power to what is realised, so falling revenue tapers and rising revenue compounds, as the window showed. A first half with no net revenue, or a second half netting below zero, leaves it unmeasured with that sentence. Amounts in different currencies are never added. The equivalent MCP tool is echo_ltv.
State effect#
The command calls Echo Web's authenticated /api/analytics/ltv with ECHO_INTERNAL_BEARER at ECHO_WEB_BASE_URL. With --source revenuecat it reads every revenuecat_webhook_events row of the RevenueCat app and environment since the history window began, narrowed to the product or store when given; with --source stripe it reads every payment the Stripe webhook recorded as a web event of the web source --app names (provider stripe) in --environment, production or test as the webhook names it from Stripe's livemode. The Lifetime value section of the dashboard's tracking screen and Echo Desktop's Revenue destination read the same operation with the source chosen. It writes nothing.
Refusals#
- A missing --source, --app, --environment, --history-days or --horizon-days is refused by name with the usage status 2; a window that is not a positive whole number is refused the same way.
- An unknown, repeated or valueless flag is refused with the usage status 2.
- A stored payment of a subject without its currency, or with a revenue or refund that is not a number, ends the read with status 1 naming the table, the subject and the value; Echo Web answers a bad request with "source must be one of revenuecat, stripe; got <value>", "product_id and store narrow RevenueCat payments only; Stripe payments are read for the whole web source", or naming app_id, environment, history_days or horizon_days when one reaches it missing or not a positive whole number.