{"id":97355,"plugin_id":"plugin_asdk_app_6af088ec57ac81919a158b6b5668b2b6","kind":"skill","collection_source":"plugin_package","comparison_source":null,"observed_at":"2026-11-15T12:08:46.634Z","digest":"b339c004d15cc85317241d969330c0ef03184dec31e19213079aa926fae0a2a4","against":null,"payload":{"description":"Answer questions about a BillDog project's numbers - revenue, MRR and ARR, churn, renewals, billing issues, trial conversion, LTV, paywall and placement conversion, revenue by country, product, offering, paywall or experiment arm, funnels, retention and event trends. Use when the user asks how their app, subscriptions or paywalls are doing, why revenue or conversion changed, or wants a weekly recap. Read-only.","included_files":[],"name":"billdog-analyst","skill_md_contents":"---\nname: billdog-analyst\ndescription: Answer questions about a BillDog project's numbers - revenue, MRR and ARR, churn, renewals, billing issues, trial conversion, LTV, paywall and placement conversion, revenue by country, product, offering, paywall or experiment arm, funnels, retention and event trends. Use when the user asks how their app, subscriptions or paywalls are doing, why revenue or conversion changed, or wants a weekly recap. Read-only.\n---\n\n# Analysing a BillDog project\n\nEvery number comes from `run_analytics_query` and a few list tools on the BillDog\nMCP server. Nothing here changes the project.\n\n## Before you answer\n\n- **Pick the right (source, metric).** Use the table below. If a question does not\n  fit it, call `discover_schema` once: it lists every valid pairing with a one-line\n  hint, and an unsupported pairing fails.\n- **Ranges** are `{ start, end }` as full UTC timestamps ending in `Z`, for example\n  `2026-10-15T00:00:00Z`. Use the last 30 days when the user names no range, and say so.\n  End at today's 00:00 UTC for whole days, or at the current time to include today\n  so far, and say which.\n- **Environment.** Queries read production unless you pass `sandbox: true`. Every\n  result says which one it read in `environment`. If production comes back empty or\n  all zero, retry with `sandbox: true` and tell the user the figures are test data.\n  A project that is still being integrated often has only sandbox data.\n- **Freshness.** `revenue` figures come from a daily rollup. `revenue` / `totals`\n  carries `meta.freshness`: days after `final_through` are provisional or missing.\n  Other reports do not carry it, so when the range ends in the last two days, run\n  `revenue` / `totals` once for the same range and say which days are not final, so a\n  short week is not read as a drop.\n- **Every source and metric in the table below is valid**, including\n  `revenue_segments`, `subscription_charts`, `subscription_cohorts`, `trial_cohorts`\n  and `ltv_prediction`. If your copy of the tool's schema lacks one, it is out of\n  date: `discover_schema` gives the current list.\n\n## Which query answers which question\n\n| Question | Query |\n|---|---|\n| Revenue, refunds, MRR, ARR, active subscriptions, churn rate, trial conversion, ARPU, new customers, all in one call | `revenue` / `totals` |\n| This period against the last one | `revenue` / `compare` with `range.compare_to: \"previous_period\"` (or `\"previous_year\"`) |\n| New, expansion, contraction, churned and net MRR | `subscriptions` / `mrr_movement` |\n| Revenue by country, store, platform, product, offering, paywall or placement | `revenue_segments` / `breakdown` with `dims: [\"<one of those>\"]` |\n| Revenue by experiment arm | `revenue_segments` / `breakdown`, `dims: [\"experiment_variant\"]`, `filters.experiment_id` |\n| Top products | `products` / `top_n`, or `revenue_segments` / `top_n` with `dims: [\"product\"]` |\n| Paywall impressions, purchases and conversion per paywall | `paywalls` / `breakdown` (grouped by paywall) |\n| Presented, started, purchased | `paywalls` / `funnel` |\n| Trial conversion by trial-start week or month | `revenue` / `trial_cohorts` with `range.granularity` |\n| Renewal rate, billing issues and recovery, plan changes, ARPPU | `subscription_charts` / `totals` (or `timeseries`) with `filters.chart`: `renewal_rate`, `billing_issues`, `plan_changes` or `arppu` |\n| Subscription retention, realized and predicted LTV | `subscription_cohorts` / `retention`, `breakdown` or `ltv_prediction` |\n| A funnel across app events | a saved view first (`list_saved_views` → `get_saved_view_results`); else `events` / `funnel` with `filters.event_names` in order |\n| Event volume, trends, top events | `events` / `timeseries`, `top_n` or `breakdown`; `list_event_names` for exact names |\n| A paywall A/B test | `get_experiment_results` (see the billdog-experiments skill) |\n\nTwo easy mistakes: `revenue` / `breakdown` is revenue **per day**, and\n`revenue` / `top_n` is the top **days**. Neither splits by product or country.\nUse `revenue_segments` for that.\n\n## Reading the result\n\n- **Check `meta` before you report.**\n  - `meta.dropped_dims` means a dimension was not valid for that source and the\n    report was grouped by the default instead. For example, `paywalls` does not take\n    `placement`; use `revenue_segments` with `dims: [\"placement\"]`.\n  - `meta.note` with empty `rows` means the query needs more input (the\n    experiment-arm split needs `filters.experiment_id`). Empty rows are not zero.\n- **Name the measure you quote.** \"Net\" means different things in different\n  sources: `revenue` / `totals` has `net_revenue_usd` and `proceeds_usd`, and\n  `revenue_segments` has `revenue_net_of_refunds_usd`. Use the column's label and\n  never add or compare figures from different sources as if they were one measure.\n- **Turn ids into names.** Paywall, placement and offering segments come back as\n  UUIDs. Resolve them with `list_paywalls`, `list_placements` and `list_offerings`\n  before showing them. An id that is not in the list belongs to a deleted item: show\n  the short id and say so.\n- **Paywall money comes from `revenue_segments`.** The `revenue_usd` column of\n  `paywalls` / `breakdown` is each customer's first verified purchase credited to the\n  paywall, without the renewals that followed, so it can be far below\n  `revenue_segments` by `paywall`.\n  Quote `paywalls` for impressions, purchases and conversion rate only.\n- **Not every wall is a paywall.** `paywalls` reports include sign-in and other walls.\n  `list_paywalls` gives each one's `wall_type`; leave out walls that sell nothing when\n  ranking conversion.\n- **\"Unknown\" is a real share.** It holds transactions with no attribution for that\n  dimension. Report its share rather than dropping it. In a period comparison, check\n  \"Unknown\" in both periods first: if the earlier period's revenue sits there, every\n  named segment shows false growth.\n- **Rates on small numbers.** Put the counts beside every rate. A 100% churn rate\n  on four subscriptions is four people.\n- **Funnels count identified users only.** An `events` funnel can show far fewer\n  users than the raw event counts from `list_event_names`.\n- **Experiments.** `experiments` / `ab_results` is an uncorrected z-test. For a\n  verdict, use `get_experiment_results`, and do not call a winner on\n  `keep_running`.\n\n## Recipes\n\nWhen the client offers the BillDog MCP prompts, these match them:\n`weekly_revenue_recap`, `funnel_drop_off_analysis`, `churn_root_cause` and\n`error_session_review`.\n\n**Weekly recap.** `revenue` / `totals` and `revenue` / `compare` for the last 7\ndays, `subscriptions` / `mrr_movement`, `revenue_segments` / `top_n` by product.\nWrite three short paragraphs: revenue and its change, MRR new versus churned versus\nnet, top products. End with one observation the user can act on.\n\n**Why did revenue change?** Compare the two periods with `revenue` / `compare`, then\nfind where the change sits with `revenue_segments` / `compare` on `product`,\n`country` and `platform`, one dimension per call. Check `subscription_charts`\n`renewal_rate` and `billing_issues` before blaming the paywall.\n\n**How are my paywalls doing?** `paywalls` / `breakdown` for conversion per paywall,\n`paywalls` / `funnel` for where buyers stop, and `revenue_segments` / `breakdown`\nby `paywall` and `placement` for the money. Resolve the ids to names.\n\n**Why are customers churning?** `subscriptions` / `mrr_movement` for its size,\n`subscription_charts` `renewal_rate` and `billing_issues` to separate voluntary\nfrom involuntary churn, `subscription_cohorts` / `retention` to find the weakest\ncohorts, and `revenue_segments` / `breakdown` by `product`.\n\n## How to answer\n\nLead with the answer. Then give the range, the environment and any days not yet\nfinal. Show only the figures the question needs, with their counts. Do not invent\nindustry benchmarks. Suggest a change to the project only when the user asks; making\none belongs to the other BillDog skills and needs the user's go-ahead.\n"},"changes":[],"summary":"First saved snapshot. No earlier version is available for comparison.","summary_kind":"deterministic","summary_metadata":{}}