Accessing RevenueCat charts
When querying a RevenueCat chart, follow this workflow:
- Use
get-chart-options-schema to discover a chart's available options.
- Use
get-chart-data with the right options to retrieve the chart data.
- Analyze the data, using scripts for any non-trivial arithmetic.
Via the rc CLI (see the revenuecat-cli skill): rc charts list to list charts, rc charts options <chart> for the schema, and rc charts show <chart> for the data.
In general, to avoid clogging the context, start with defined timeframes and larger resolution, then narrow down.
1. Discover chart options with get-chart-options-schema
- Treat
get-chart-options-schema as the source of truth for each chart before calling
get-chart-data. It returns the chart's supported resolutions, filters, segments, and
user_selectors. Always call this tool with "realtime": true. Later get-chart-data calls must
use string IDs exactly as returned here.
filters are the dimensions you may later constrain in get-chart-data.
- Each filter has:
- an
id to later use as the filter name.
- a
value_mode that tells you how to choose valid values:
inline_enum means you must use the id of one of the returned options. Resolve
user-supplied names first with the matching list tool, such as list-products,
list-offerings, list-apps, etc.
inferred_standard means use the standard code from value_source such as an ISO country
code.
dynamic means values come from observed project data and must match exactly.
- Do not pass display names, store product identifiers, bundle IDs, or guessed values unless the
schema says they are valid values.
segments are the dimensions you may later group by in get-chart-data using segment.
- A segment entry directly gives the dimension
id to use. It does not list segment values
because the chart will group by it and show all values in the output.
- Filters and segments are separate per-chart lists, so never assume a filterable dimension is
segmentable. For example,
conversion_to_paying may support product_id and
offering_identifier as filters but not as segments.
user_selectors are chart-specific switches that change what metric or window the chart returns.
Each selector is keyed by the selector ID to pass in get-chart-data's selectors JSON object
and usually includes allowed option IDs plus a default. For example, the revenue chart may use
revenue_type (revenue, revenue_net_of_taxes, proceeds), while conversion charts may use
conversion_timeframe and default to 7_days. State non-default selector choices when presenting
results.
resolutions list the supported time granularity and their string IDs for get-chart-data. You
must always pass one of these resolution IDs (such as "0" for day or "2" for month) when later
calling get-chart-data.
2. Retrieve chart data with get-chart-data
Calling get-chart-data
- Always set
"realtime": true and specify start date, end date and resolution ID.
- Always follow the guidelines from a prior
get-chart-options-schema for that chart.
- Consider rate limits: don't query too many charts at once.
- Date ranges are inclusive (start_date and end_date are included in the range). When asked for
data for the "last N days", take that into account (use today as end date, start date is (N-1)
days before today).
- Use available
filters to constrain the output. They are a JSON-encoded array of
{"name": "<filter id>", "values": ["<value id>", ...]}.
- Values within one entry are ORed; separate entries are ANDed. Example: App Store revenue in the
US or the UK:
"[{\"name\": \"store\", \"values\": [\"app_store\"]}, {\"name\": \"country\", \"values\": [\"US\", \"GB\"]}]".
- Use at most one entry per filter name: a repeated name silently replaces the earlier entry
(it does not combine with it). Filter values must not contain commas.
- Use the available
selectors for configuring the chart. They are a JSON-encoded object mapping
selector IDs to option IDs, e.g. "{\"revenue_type\": \"proceeds\"}". Omitted selectors use their
defaults; the response echoes the applied values in user_selectors.
- Use
segment to group the output by some of the segmentable dimension IDs:
- Note that segmenting multiplies output size. You can keep responses small by using a coarser
resolution, a shorter date range,
limit_num_segments (keeps the top N by value and folds the
rest into "Other"), or aggregate when you only need per-segment totals.
- Use
aggregate for summary-only questions such as totals or averages (e.g. "total Q1 revenue").
Prefer this over fetching and computing from raw data points yourself. Combined with segment it
returns compact per-segment summaries (e.g. country averages). In the output, values will be
empty and summary will contain just those operations.
- Pass
currency to convert outputs to some monetary unit (see yaxis_currency in the response).
Reading get-chart-data outputs
measures lists the metrics the chart returns (display name, unit, description). Most charts
return several, e.g. revenue may return Revenue, Transactions, and Ad Impressions.
values is a flat array of points {cohort, measure, value, incomplete}, plus segment when
segmented. cohort is the Unix timestamp of the period start; measure and segment are indexes
into the measures and segments arrays. The first segment is usually a "is_total": true -
never sum it together with the other segments.
summary holds total and average per measure display name, nested per segment when segmented.
- Points with
incomplete: true cover partial periods: the current period, and the first period
when start_date falls mid-period (since expand_periods defaults to false). Exclude them from
trend or comparison analysis, and call them out when presenting. Point-in-time charts (MRR,
actives, trials) ignore expand_periods: their values are snapshots at period boundaries and are
never partial.
annotations lists dated notes the user made on their dashboard (e.g. releases, launches or
experiments). Check them when explaining movements in the data.
- Invalid filters, segments, or selector values fail with a 400
parameter_error whose message
lists the supported IDs. On such errors, re-read the options schema instead of retrying guesses.
3. Analyze the data
- Segmented responses include a
Total segment, and the limit_num_segments cap folds segments
beyond the top N into an Other segment. Use Total as the baseline; do not sum segments
yourself.
- Do complex arithmetic on chart output (growth rates, segment shares, combining numbers across
calls) with scripts (e.g.
jq or a short Python script) instead of reasoning over the numbers.
- The most recent period may be flagged incomplete. Do not compare it against full periods without
saying so.
- Before speculating about the cause of a metric shift, first check the available user annotations.
- Cohort charts measure within a cumulative window from first seen, chosen by a selector
(
conversion_timeframe on conversion charts, customer_lifetime on realized LTV charts), one
window per call. State the window when presenting results and hold it constant when comparing
cohorts.
Interpreting metrics
Subscription apps are driven by four forces:
- Acquisition - how many new customers are arriving to the app
- Conversion - how many of those customers are converting into trials or paid plans
- Retention - how long do those customers retain
- Reactivation - how can you bring back old users
The net movement of an apps revenue will be the result of the combination of these forces. When
giving advice, always use benchmark data to make sure you aren't incorrectly diagnosing an issue.
General guidelines:
- When using the data tools, date ranges are inclusive (start_date and end_date are included in the range). When asked for data for the "last N days", take that into account (use today as end date, start date is (N-1) days before today).
- Provide links to RevenueCat charts (see the Dashboard URL Format section below) where it is useful. Provide specific links including filters, segments, date ranges, etc — eg. if you are asked for proceeds in the last 3 months, link to the revenue chart with custom date range of the last 3 months and the
revenue_type selector set to proceeds, don't link to the plain revenue chart
Revenue
- When asked for general revenue numbers without additional specification, default to gross revenue (ie. revenue including taxes and store commissions) and call it out.
Acquisition
- Use the New Customers chart to understand how much top of funnel the app is driving.
- Segmenting New Customers by Country, or Apple Ads dimensions can be helpful in informing
acquisition.
- RevenueCat's Apple Ads integration sets attribution dimension information like campaign, ad
group, keyword
- Developers can also manually set these attribution dimensions on a per-customer level using
reserved customer attributes
- Do not treat a zero result from an explicit attribution filter as proof that the broader channel
has zero users or zero activity. For example,
attribution_source = Organic only means users
explicitly tagged with that value; it does not include untagged users or every organic/non-paid
user.
- If attribution data is sparse or missing, say that clearly. Use "unattributed" or "not explicitly
tagged" rather than assuming those users came from a specific channel.
Conversion
The definition of conversion may vary depending on what model the app is using. They may be
converting to a trial, that then converts into a subscription. Or they may be sending users directly
to a subscription.
- Use the Initial Conversion chart to see the proportion of new customers that start a subscription
or trial within the selected conversion timeframe.
- Use the Conversion to Paying chart to see the proportion of new customers that made a payment
within the selected conversion timeframe.
- You can then further determine if they are using free trials by looking at the New Trials chart.
- The Trial Conversion Rate chart is a helpful chart for understanding the performance of just that
trial conversion.
- Filtered charts keep the all-new-customers denominator. For example, filtering Conversion to
Paying on a specific
product_id gives the share of ALL new customers converting to that product,
not that product's own conversion rate. State this caveat when presenting filtered results.
Retention
- The Churn chart will tell you the % of the active subscriber base that is lost each period. It can
be difficult to interpret or benchmark because it is a blend of different periods.
- When you want to understand the long term retention of different products, look at the
Subscription Retention chart
Reactivation
- The only real way to understand Reactivation is looking at the MRR Movement chart and the
Resubscription MRR
Analytics comparisons
- Compare like with like. When analyzing an acquisition cohort or segment, compare it against the
overall baseline using the same metric, chart, date range, conversion window, and cohort
definition before making a directional claim.
- For open-ended questions like "how are {segment} users doing?", do not stop at segment-only
metrics. Pull the requested segment and an overall/unfiltered baseline for the key conversion or
revenue-quality metric, then judge performance relative to that baseline. Do not evaluate a
segment as "healthy", "underperforming" etc. without comparing it to a baseline.
- Do not compare revenue or conversions from a filtered new-customer cohort against total app
revenue from all cohorts and renewals. If you cannot get a matching baseline, say so and avoid
directional performance claims.
Chart Dashboard Links
Generate shareable links to RevenueCat dashboard charts.
Constructing a Link
A chart link must follow a specific Dashboard URL Format and must be built
from a verified previous successful get-chart-data call.
- If there isn't a previous successful
get-chart-data call for this chart, follow the Querying
RevenueCat charts workflow above first.
- Construct the link, starting with base:
https://app.revenuecat.com/projects/{project_id}/charts/{chart_name}.
- Add
range param with date range. This is required.
- Add
resolution param with resolution. Don't trust defaults.
- Add any filters as
filter params.
- Add segment as
segment param, if segmenting.
- Add chart-specific selectors as needed.
- URL-encode all values (spaces →
+, colons → %3A, etc.)
Dashboard URL Format
IMPORTANT: Use this exact structure:
https://app.revenuecat.com/projects/{project_id}/charts/{chart_name}?range={range_value}
{project_id} — The short hex ID (e.g., 56965ae1), not the full proj56965ae1
{chart_name} — The same chart name used with get-chart-data (revenue, churn, mrr,
conversion_to_paying, etc.)
- Project ID goes in the path, not as a query parameter
Correct example:
https://app.revenuecat.com/projects/56965ae1/charts/revenue?range=Custom%3A2025-11-16%3A2026-02-13
WRONG — do not use:
https://app.revenuecat.com/charts/revenue?project=proj56965ae1&chart_start=...&chart_end=...
Query Parameters
range param — required
The range parameter controls the date range. Format: {preset}:{start_date}:{end_date}, with
start_date and end_date in YYYY-MM-DD format. Use Custom as the preset.
Always use this format — do not use start_date, end_date, chart_start, or chart_end
params. Note: The : between parts must be URL-encoded as %3A.
Example: range=Custom%3A2025-01-01%3A2025-12-31
resolution param
| Value |
Meaning |
0 |
Daily granularity |
1 |
Weekly granularity |
2 |
Monthly granularity |
3 |
Quarterly granularity |
4 |
Yearly granularity |
segment param
Dimension to break down the data by. Use the exact dimension ID you were using to make the
get-chart-data request.
country — by country
store — by app store (App Store, Play Store, etc.)
product_id — by product identifier
platform — by platform (iOS, Android, etc.)
offering_identifier — by offering
Segments vary per chart — only link a segment you successfully used in a get-chart-data call for
that chart.
filter params
Filters are passed as individual query filter params with the content
{dimension}%3A%3D%3A{value}. Use the dimension names you used for the get-chart-data request.
| Dimension |
Example |
country |
filter=country%3A%3D%3AUS |
store |
filter=store%3A%3D%3Aapp_store |
product_id |
filter=product_id%3A%3D%3Aprodbb68905d98 |
platform |
filter=platform%3A%3D%3AiOS |
To use multiple filters, regardless of whether they are for the same dimension or multiple
dimensions, include multiple filter query parameters. Passing multiple filters for the same
dimension will result in an OR operation, passing filters for different dimensions will result in an
AND operation.
Chart-Specific Selectors
Selectors are passed as individual query params, with the same names and values used in the
get-chart-data selectors argument. Orientative examples (truth in get-chart-data):
revenue_type (revenue chart) — revenue, revenue_net_of_taxes, or proceeds
conversion_timeframe (conversion charts) — 0_days, 3_days, 7_days, 14_days, 30_days,
or unbounded
customer_lifetime (realized LTV charts) — 7_days, 14_days, 30_days, 3_months up to
24_months, or unbounded
API to Dashboard Parameter Mapping
When translating from API parameters to dashboard URLs:
| API Parameter |
Dashboard Parameter |
start_date + end_date |
range=Custom%3A{start}%3A{end} (use Custom preset) |
segment |
segment |
filters (JSON array) |
Individual filter query params |
selectors (JSON object) |
Individual query params |
Example: Building a Link
User wants: "Revenue chart for last 90 days, segmented by country, filtered to US and Germany"
Calculate dates: if today is 2026-02-13, then 90 days ago is 2025-11-16.
https://app.revenuecat.com/projects/56965ae1/charts/revenue?range=Custom%3A2025-11-16%3A2026-02-13&segment=country&filter=country%3A%3D%3AUS&filter=country%3A%3D%3ADE
User wants: "Churn chart from August 2025 to now"
https://app.revenuecat.com/projects/56965ae1/charts/churn?range=Custom%3A2025-08-01%3A2026-02-13
Getting Project ID
The project ID can be found via the list-projects tool, which lists all projects with their ID.
- The tool returns IDs starting with
proj, for example proj56965ae1
- For dashboard URLs, strip the
proj prefix — use just 56965ae1 in the path
1---2name: revenuecat-charts3description: Use when the user asks about RevenueCat data, analytics, charts, or KPIs — querying charts with get-chart-options-schema and get-chart-data, interpreting subscription metrics, or sharing dashboard chart links.4---5
6# Accessing RevenueCat charts
7
8When querying a RevenueCat chart, follow this workflow:
9
101. Use `get-chart-options-schema` to discover a chart's available options.
112. Use `get-chart-data` with the right options to retrieve the chart data.
123. Analyze the data, using scripts for any non-trivial arithmetic.
13
14Via the `rc` CLI (see the `revenuecat-cli` skill): `rc charts list` to list charts, `rc charts options <chart>` for the schema, and `rc charts show <chart>` for the data.
15
16In general, to avoid clogging the context, start with defined timeframes and larger resolution, then narrow down.
17
18## 1. Discover chart options with `get-chart-options-schema`
19
20- Treat `get-chart-options-schema` as the source of truth for each chart before calling
21 `get-chart-data`. It returns the chart's supported `resolutions`, `filters`, `segments`, and
22 `user_selectors`. Always call this tool with `"realtime": true`. Later `get-chart-data` calls must
23 use string IDs exactly as returned here.
24- `filters` are the dimensions you may later constrain in `get-chart-data`.
25 - Each filter has:
26 - an `id` to later use as the filter `name`.
27 - a `value_mode` that tells you how to choose valid values:
28 - `inline_enum` means you must use the `id` of one of the returned `options`. Resolve
29 user-supplied names first with the matching list tool, such as `list-products`,
30 `list-offerings`, `list-apps`, etc.
31 - `inferred_standard` means use the standard code from `value_source` such as an ISO country
32 code.
33 - `dynamic` means values come from observed project data and must match exactly.
34 - Do not pass display names, store product identifiers, bundle IDs, or guessed values unless the
35 schema says they are valid values.
36- `segments` are the dimensions you may later group by in `get-chart-data` using `segment`.
37 - A segment entry directly gives the dimension `id` to use. It does not list segment values
38 because the chart will group by it and show all values in the output.
39 - Filters and segments are separate per-chart lists, so never assume a filterable dimension is
40 segmentable. For example, `conversion_to_paying` may support `product_id` and
41 `offering_identifier` as filters but not as segments.
42- `user_selectors` are chart-specific switches that change what metric or window the chart returns.
43 Each selector is keyed by the selector ID to pass in `get-chart-data`'s `selectors` JSON object
44 and usually includes allowed option IDs plus a default. For example, the `revenue` chart may use
45 `revenue_type` (`revenue`, `revenue_net_of_taxes`, `proceeds`), while conversion charts may use
46 `conversion_timeframe` and default to `7_days`. State non-default selector choices when presenting
47 results.
48- `resolutions` list the supported time granularity and their string IDs for `get-chart-data`. You
49 must always pass one of these resolution IDs (such as `"0"` for day or `"2"` for month) when later
50 calling `get-chart-data`.
51
52## 2. Retrieve chart data with `get-chart-data`
53
54### Calling `get-chart-data`
55
56- Always set `"realtime": true` and specify start date, end date and resolution ID.
57- Always follow the guidelines from a prior `get-chart-options-schema` for that chart.
58- Consider rate limits: don't query too many charts at once.
59- Date ranges are inclusive (start_date and end_date are included in the range). When asked for
60 data for the "last N days", take that into account (use today as end date, start date is (N-1)
61 days before today).
62- Use available `filters` to constrain the output. They are a JSON-encoded array of
63 `{"name": "<filter id>", "values": ["<value id>", ...]}`.
64 - Values within one entry are ORed; separate entries are ANDed. Example: App Store revenue in the
65 US or the UK:
66 `"[{\"name\": \"store\", \"values\": [\"app_store\"]}, {\"name\": \"country\", \"values\": [\"US\", \"GB\"]}]"`.
67 - Use at most one entry per filter name: a repeated name silently replaces the earlier entry
68 (it does not combine with it). Filter values must not contain commas.
69- Use the available `selectors` for configuring the chart. They are a JSON-encoded object mapping
70 selector IDs to option IDs, e.g. `"{\"revenue_type\": \"proceeds\"}"`. Omitted selectors use their
71 defaults; the response echoes the applied values in `user_selectors`.
72- Use `segment` to group the output by some of the segmentable dimension IDs:
73 - Note that segmenting multiplies output size. You can keep responses small by using a coarser
74 resolution, a shorter date range, `limit_num_segments` (keeps the top N by value and folds the
75 rest into "Other"), or `aggregate` when you only need per-segment totals.
76- Use `aggregate` for summary-only questions such as totals or averages (e.g. "total Q1 revenue").
77 Prefer this over fetching and computing from raw data points yourself. Combined with `segment` it
78 returns compact per-segment summaries (e.g. country averages). In the output, `values` will be
79 empty and `summary` will contain just those operations.
80- Pass `currency` to convert outputs to some monetary unit (see `yaxis_currency` in the response).
81
82### Reading `get-chart-data` outputs
83
84- `measures` lists the metrics the chart returns (display name, unit, description). Most charts
85 return several, e.g. `revenue` may return Revenue, Transactions, and Ad Impressions.
86- `values` is a flat array of points `{cohort, measure, value, incomplete}`, plus `segment` when
87 segmented. `cohort` is the Unix timestamp of the period start; `measure` and `segment` are indexes
88 into the `measures` and `segments` arrays. The first segment is usually a `"is_total": true` -
89 never sum it together with the other segments.
90- `summary` holds `total` and `average` per measure display name, nested per segment when segmented.
91- Points with `incomplete: true` cover partial periods: the current period, and the first period
92 when `start_date` falls mid-period (since `expand_periods` defaults to false). Exclude them from
93 trend or comparison analysis, and call them out when presenting. Point-in-time charts (MRR,
94 actives, trials) ignore `expand_periods`: their values are snapshots at period boundaries and are
95 never partial.
96- `annotations` lists dated notes the user made on their dashboard (e.g. releases, launches or
97 experiments). Check them when explaining movements in the data.
98- Invalid filters, segments, or selector values fail with a 400 `parameter_error` whose message
99 lists the supported IDs. On such errors, re-read the options schema instead of retrying guesses.
100
101## 3. Analyze the data
102
103- Segmented responses include a `Total` segment, and the `limit_num_segments` cap folds segments
104 beyond the top N into an `Other` segment. Use `Total` as the baseline; do not sum segments
105 yourself.
106- Do complex arithmetic on chart output (growth rates, segment shares, combining numbers across
107 calls) with scripts (e.g. `jq` or a short Python script) instead of reasoning over the numbers.
108- The most recent period may be flagged incomplete. Do not compare it against full periods without
109 saying so.
110- Before speculating about the cause of a metric shift, first check the available user annotations.
111- Cohort charts measure within a cumulative window from first seen, chosen by a selector
112 (`conversion_timeframe` on conversion charts, `customer_lifetime` on realized LTV charts), one
113 window per call. State the window when presenting results and hold it constant when comparing
114 cohorts.
115
116# Interpreting metrics
117
118Subscription apps are driven by four forces:
119
120- Acquisition - how many new customers are arriving to the app
121- Conversion - how many of those customers are converting into trials or paid plans
122- Retention - how long do those customers retain
123- Reactivation - how can you bring back old users
124
125The net movement of an apps revenue will be the result of the combination of these forces. When
126giving advice, always use benchmark data to make sure you aren't incorrectly diagnosing an issue.
127
128General guidelines:
129
130- When using the data tools, date ranges are inclusive (start_date and end_date are included in the range). When asked for data for the "last N days", take that into account (use today as end date, start date is (N-1) days before today).
131- Provide links to RevenueCat charts (see the Dashboard URL Format section below) where it is useful. Provide specific links including filters, segments, date ranges, etc — eg. if you are asked for proceeds in the last 3 months, link to the revenue chart with custom date range of the last 3 months and the `revenue_type` selector set to `proceeds`, don't link to the plain revenue chart
132
133## Revenue
134
135- When asked for general revenue numbers without additional specification, default to gross revenue (ie. revenue including taxes and store commissions) and call it out.
136
137## Acquisition
138
139- Use the New Customers chart to understand how much top of funnel the app is driving.
140- Segmenting New Customers by Country, or Apple Ads dimensions can be helpful in informing
141 acquisition.
142 - RevenueCat's Apple Ads integration sets attribution dimension information like campaign, ad
143 group, keyword
144 - Developers can also manually set these attribution dimensions on a per-customer level using
145 reserved customer attributes
146- Do not treat a zero result from an explicit attribution filter as proof that the broader channel
147 has zero users or zero activity. For example, `attribution_source = Organic` only means users
148 explicitly tagged with that value; it does not include untagged users or every organic/non-paid
149 user.
150- If attribution data is sparse or missing, say that clearly. Use "unattributed" or "not explicitly
151 tagged" rather than assuming those users came from a specific channel.
152
153## Conversion
154
155The definition of conversion may vary depending on what model the app is using. They may be
156converting to a trial, that then converts into a subscription. Or they may be sending users directly
157to a subscription.
158
159- Use the Initial Conversion chart to see the proportion of new customers that start a subscription
160 or trial within the selected conversion timeframe.
161- Use the Conversion to Paying chart to see the proportion of new customers that made a payment
162 within the selected conversion timeframe.
163- You can then further determine if they are using free trials by looking at the New Trials chart.
164- The Trial Conversion Rate chart is a helpful chart for understanding the performance of just that
165 trial conversion.
166- Filtered charts keep the all-new-customers denominator. For example, filtering Conversion to
167 Paying on a specific `product_id` gives the share of ALL new customers converting to that product,
168 not that product's own conversion rate. State this caveat when presenting filtered results.
169
170## Retention
171
172- The Churn chart will tell you the % of the active subscriber base that is lost each period. It can
173 be difficult to interpret or benchmark because it is a blend of different periods.
174- When you want to understand the long term retention of different products, look at the
175 Subscription Retention chart
176
177## Reactivation
178
179- The only real way to understand Reactivation is looking at the MRR Movement chart and the
180 Resubscription MRR
181
182## Analytics comparisons
183
184- Compare like with like. When analyzing an acquisition cohort or segment, compare it against the
185 overall baseline using the same metric, chart, date range, conversion window, and cohort
186 definition before making a directional claim.
187- For open-ended questions like "how are {segment} users doing?", do not stop at segment-only
188 metrics. Pull the requested segment and an overall/unfiltered baseline for the key conversion or
189 revenue-quality metric, then judge performance relative to that baseline. Do not evaluate a
190 segment as "healthy", "underperforming" etc. without comparing it to a baseline.
191- Do not compare revenue or conversions from a filtered new-customer cohort against total app
192 revenue from all cohorts and renewals. If you cannot get a matching baseline, say so and avoid
193 directional performance claims.
194
195# Chart Dashboard Links
196
197Generate shareable links to RevenueCat dashboard charts.
198
199## Constructing a Link
200
201A chart link must follow a specific [Dashboard URL Format](#dashboard-url-format) and must be built
202from a verified previous successful `get-chart-data` call.
203
2040. If there isn't a previous successful `get-chart-data` call for this chart, follow the Querying
205 RevenueCat charts workflow above first.
2061. Construct the link, starting with base:
207 `https://app.revenuecat.com/projects/{project_id}/charts/{chart_name}`.
2082. Add [`range` param](#range-param--required) with date range. This is required.
2093. Add [`resolution` param](#resolution-param) with resolution. Don't trust defaults.
2104. Add any filters as [`filter` params](#filter-params).
2115. Add segment as [`segment` param](#segment-param), if segmenting.
2126. Add [chart-specific selectors](#chart-specific-selectors) as needed.
2137. URL-encode all values (spaces → `+`, colons → `%3A`, etc.)
214
215## Dashboard URL Format
216
217**IMPORTANT**: Use this exact structure:
218
219```
220https://app.revenuecat.com/projects/{project_id}/charts/{chart_name}?range={range_value}
221```
222
223- `{project_id}` — The short hex ID (e.g., `56965ae1`), not the full `proj56965ae1`
224- `{chart_name}` — The same chart name used with `get-chart-data` (`revenue`, `churn`, `mrr`,
225 `conversion_to_paying`, etc.)
226- Project ID goes in the **path**, not as a query parameter
227
228**Correct example:**
229
230```
231https://app.revenuecat.com/projects/56965ae1/charts/revenue?range=Custom%3A2025-11-16%3A2026-02-13
232```
233
234**WRONG — do not use:**
235
236```
237https://app.revenuecat.com/charts/revenue?project=proj56965ae1&chart_start=...&chart_end=...
238```
239
240## Query Parameters
241
242### `range` param — required
243
244The `range` parameter controls the date range. Format: `{preset}:{start_date}:{end_date}`, with
245start_date and end_date in YYYY-MM-DD format. Use `Custom` as the preset.
246
247**Always use this format** — do not use `start_date`, `end_date`, `chart_start`, or `chart_end`
248params. Note: The `:` between parts must be URL-encoded as `%3A`.
249
250Example: `range=Custom%3A2025-01-01%3A2025-12-31`
251
252### `resolution` param
253
254| Value | Meaning |
255| ----- | --------------------- |
256| `0` | Daily granularity |
257| `1` | Weekly granularity |
258| `2` | Monthly granularity |
259| `3` | Quarterly granularity |
260| `4` | Yearly granularity |
261
262### `segment` param
263
264Dimension to break down the data by. Use the exact dimension ID you were using to make the
265`get-chart-data` request.
266
267- `country` — by country
268- `store` — by app store (App Store, Play Store, etc.)
269- `product_id` — by product identifier
270- `platform` — by platform (iOS, Android, etc.)
271- `offering_identifier` — by offering
272
273Segments vary per chart — only link a segment you successfully used in a `get-chart-data` call for
274that chart.
275
276### `filter` params
277
278Filters are passed as individual query `filter` params with the content
279`{dimension}%3A%3D%3A{value}`. Use the dimension names you used for the `get-chart-data` request.
280
281| Dimension | Example |
282| ------------ | ------------------------------------------ |
283| `country` | `filter=country%3A%3D%3AUS` |
284| `store` | `filter=store%3A%3D%3Aapp_store` |
285| `product_id` | `filter=product_id%3A%3D%3Aprodbb68905d98` |
286| `platform` | `filter=platform%3A%3D%3AiOS` |
287
288To use multiple filters, regardless of whether they are for the same dimension or multiple
289dimensions, include multiple `filter` query parameters. Passing multiple filters for the same
290dimension will result in an OR operation, passing filters for different dimensions will result in an
291AND operation.
292
293### Chart-Specific Selectors
294
295Selectors are passed as individual query params, with the same names and values used in the
296`get-chart-data` `selectors` argument. Orientative examples (truth in `get-chart-data`):
297
298- `revenue_type` (revenue chart) — `revenue`, `revenue_net_of_taxes`, or `proceeds`
299- `conversion_timeframe` (conversion charts) — `0_days`, `3_days`, `7_days`, `14_days`, `30_days`,
300 or `unbounded`
301- `customer_lifetime` (realized LTV charts) — `7_days`, `14_days`, `30_days`, `3_months` up to
302 `24_months`, or `unbounded`
303
304## API to Dashboard Parameter Mapping
305
306When translating from API parameters to dashboard URLs:
307
308| API Parameter | Dashboard Parameter |
309| ------------------------- | ------------------------------------------------------ |
310| `start_date` + `end_date` | `range=Custom%3A{start}%3A{end}` (use `Custom` preset) |
311| `segment` | `segment` |
312| `filters` (JSON array) | Individual `filter` query params |
313| `selectors` (JSON object) | Individual query params |
314
315## Example: Building a Link
316
317User wants: "Revenue chart for last 90 days, segmented by country, filtered to US and Germany"
318
319Calculate dates: if today is 2026-02-13, then 90 days ago is 2025-11-16.
320
321```
322https://app.revenuecat.com/projects/56965ae1/charts/revenue?range=Custom%3A2025-11-16%3A2026-02-13&segment=country&filter=country%3A%3D%3AUS&filter=country%3A%3D%3ADE
323```
324
325User wants: "Churn chart from August 2025 to now"
326
327```
328https://app.revenuecat.com/projects/56965ae1/charts/churn?range=Custom%3A2025-08-01%3A2026-02-13
329```
330
331## Getting Project ID
332
333The project ID can be found via the `list-projects` tool, which lists all projects with their ID.
334
335- The tool returns IDs starting with `proj`, for example `proj56965ae1`
336- **For dashboard URLs, strip the `proj` prefix** — use just `56965ae1` in the path