Skip to main content
The subscription analytics endpoints power the Admin analytics dashboard. You can fetch KPI summary cards, retrieve grouped time-series data for charts, export a flattened dataset as JSON or CSV, and trigger a manual rebuild of daily analytics snapshots for a historical range. All routes require an authenticated Medusa Admin user. Read routes share a common filter contract; the rebuild route uses a separate request body.
All routes require an authenticated Medusa Admin user. Unauthenticated requests return 401.

Metric keys

MRR and LTV resolve to null when the selected dataset lacks a single valid currency context.
created_subscriptions_count is returned by the trends response only. KPI cards remain mrr, churn_rate, ltv, and active_subscriptions_count.

Shared filter parameters

All three read routes (/kpis, /trends, /export) accept the same filter parameters.
string
ISO datetime lower bound. Must be on or before date_to. Maximum analytics window is 731 days.
string
ISO datetime upper bound.
string | string[]
Filter by subscription status. Supported values: active, paused, cancelled, past_due.
string | string[]
Filter by product ID. Accepts a single value or an array.
string | string[]
Filter by cadence using serialized tokens such as week:1, month:1, or year:1. Accepts a single value or an array.
string
Time bucket granularity. One of day, week, or month. Defaults to day.
string
Timezone for bucket boundaries. Only UTC is supported in MVP.

GET /admin/subscription-analytics/kpis

Returns the KPI summary payload used by the Admin analytics overview cards.

Response

object[]
required
Array of KPI summaries, one per supported metric key.
object
required
Resolved filter values used for the query.
string
required
Analytics schema version identifier.
string
required
Timestamp when the response was generated.
Response example

Errors


GET /admin/subscription-analytics/trends

Returns grouped time-series data for Admin analytics charts. Each series covers one metric key and contains one point per time bucket within the requested range.
created_subscriptions_count is a special-case series:
  • it is sourced from subscription.created_at
  • it always returns one UTC day bucket per point
  • it ignores status, product_id, frequency, and group_by
  • it zero-fills missing days inside the selected range

Response

object[]
required
Array of trend series, one per metric key.
object
required
Resolved filter values.
string
required
Analytics schema version identifier.
string
required
Timestamp when the response was generated.
Response example

Errors


GET /admin/subscription-analytics/export

Returns an export payload aligned with the active analytics filters. The export is synchronous and supports json and csv formats. Rows represent one entry per time bucket.

Additional query parameter

string
Export format. One of json or csv. Defaults to json.

Response

string
required
Resolved export format.
object
required
Resolved filter values.
string
required
Analytics schema version identifier.
string
required
Timestamp when the export was generated.
string
required
Suggested file name for the export.
string
required
MIME type for the export format.
string[]
required
Ordered column names for the export dataset.
object[]
required
Flattened export rows. Each row contains one value per column. Metric cells may be null.
Response example

Errors


POST /admin/subscription-analytics/rebuild

Triggers a manual rebuild of daily analytics snapshots for a historical date range. Reuses the same shared workflow used by scheduled and incremental analytics jobs. Rebuild is day-level idempotent — rerunning the same range is safe.

Body parameters

string
required
ISO datetime start of the rebuild range.
string
required
ISO datetime end of the rebuild range. Maximum manual rebuild window is 365 days.
string
Optional reason for the rebuild, recorded for audit purposes.
Request example

Response

string
required
Rebuild range start.
string
required
Rebuild range end.
number
required
Number of calendar days processed.
number
required
Total subscription records evaluated.
number
required
Snapshot rows created or updated.
number
required
Rows skipped during the rebuild.
string[]
required
Days that could not be processed.
string[]
required
Days where processing failed. Partial failure does not change the HTTP status to 500.
Response example

Errors