Lifecycle events
A chronological stream of classified customer lifecycle events for one of your apps — install, trial, subscribe, upgrade/downgrade, freeze, churn, uninstall, and more. GET /api/v1/apps/:app/lifecycle-events returns a paginated object: "list" of events, newest first, ideal for building retention curves or ingesting the full history into a warehouse. Requires the metrics:read scope.
Lifecycle events come from your Shopify Partner API integration. If the integration was never configured for the app, the feed is simply empty (a 200, not an error). Each row now carries subscription_id — the id of the Ranksy subscription the shop held at the time of the event — so you can join events straight onto a subscription's timeline.
Lifecycle events
Returns the app's classified lifecycle events as a paginated object: "list", newest event first. total_count is the count after filters and has_more tells you when to fetch the next page. Filter by event_type, by date window (event_date_after / event_date_before), and optionally fold in test stores with include_test.
Each row includes the newly added subscription_id — the id of the Ranksy subscription the shop held at the time of that event. It is null for events with no subscription in effect (e.g. INSTALLED, FREE_PLAN_SELECTED, or any pre-subscription event), and lets you stitch events onto a subscription's timeline without a second lookup.
For exporting the entire stream into a warehouse, prefer cursor pagination (see Pagination) — it is stable under concurrent inserts and not subject to the page-mode row cap.
Path parameter
- Name
app- Type
- string
- Description
The team app's ULID, e.g.
01JN4HKQX0000000000000000.
Query parameters
- Name
event_type- Type
- string
- Description
Filter to one event type. One of
INSTALLED,REINSTALLED,TRIAL_STARTED,FREE_PLAN_SELECTED,SUBSCRIBED,TRIAL_CONVERTED,TRIAL_CANCELLED,UPGRADED,DOWNGRADED,FROZEN,UNFROZEN,CHURNED,UNINSTALLED,SHOP_CLOSED,SHOP_REOPENED. Any other value returns a422.
- Name
event_date_after- Type
- string
- Description
YYYY-MM-DD. Only events on or after this date.
- Name
event_date_before- Type
- string
- Description
YYYY-MM-DD. Only events on or before this date.
- Name
include_test- Type
- boolean
- Description
Include events from test / development stores. Defaults to
false(they are excluded).
- Name
cursor- Type
- string
- Description
Opt-in cursor for cursor pagination. Opaque, maximum 64 characters. See Pagination.
- Name
page- Type
- integer
- Description
The page to return. Minimum
1.
- Name
per_page- Type
- integer
- Description
Events per page,
1–100.
Request
curl -G https://ranksyapp.com/api/v1/apps/01JN4HKQX0000000000000000/lifecycle-events \
-H "Authorization: Bearer rk_live_..." \
-d event_type=SUBSCRIBED \
-d event_date_after=2026-07-01 \
-d per_page=25
Response
{
"object": "list",
"url": "/api/v1/apps/01JN4HKQX0000000000000000/lifecycle-events",
"currency": "USD",
"page": 1,
"per_page": 25,
"total_count": 128,
"has_more": true,
"metadata": {},
"data": [
{
"shop_domain": "acme-store.myshopify.com",
"shop_id": "5271523",
"subscription_id": 44120,
"event_type": "SUBSCRIBED",
"event_date": "2026-07-08T14:30:00+00:00",
"plan_name": "Growth",
"amount": 49.00,
"previous_amount": null,
"trial_days": 7,
"is_test": false
}
]
}
Response fields
Each item in data is a lifecycle event row.
- Name
shop_domain- Type
- string
- Description
The
*.myshopify.comdomain of the shop, ornullwhen unknown.
- Name
shop_id- Type
- string
- Description
The Shopify shop id, or
nullwhen unknown.
- Name
subscription_id- Type
- integer
- Description
The id of the Ranksy subscription the shop held at the time of this event.
nullfor events with no subscription in effect (e.g.INSTALLED,FREE_PLAN_SELECTED, or pre-subscription events).
- Name
event_type- Type
- string
- Description
The classified event — one of
INSTALLED,REINSTALLED,TRIAL_STARTED,FREE_PLAN_SELECTED,SUBSCRIBED,TRIAL_CONVERTED,TRIAL_CANCELLED,UPGRADED,DOWNGRADED,FROZEN,UNFROZEN,CHURNED,UNINSTALLED,SHOP_CLOSED,SHOP_REOPENED.
- Name
event_date- Type
- string
- Description
ISO-8601 timestamp of when the event occurred.
- Name
plan_name- Type
- string
- Description
The plan name associated with the event, or
null.
- Name
amount- Type
- number
- Description
The subscription amount at the event, in the plan currency, or
null.
- Name
previous_amount- Type
- number
- Description
The prior amount, for
UPGRADED/DOWNGRADEDevents, ornull.
- Name
trial_days- Type
- integer
- Description
The trial length in days, or
null.
- Name
is_test- Type
- boolean
- Description
Whether the event came from a test / development store.
The event rows sit inside the shared object: "list" envelope: object ("list"), url, currency, page, per_page, total_count, has_more, metadata (object), and data (the array of rows). In cursor mode the envelope additionally includes next_cursor, and returns page and total_count as null.
Pagination
By default the list uses offset pagination. Walk it with page and per_page (1–100), and check has_more / total_count to know when to stop.
For exporting the full event stream — for example into a warehouse such as BigQuery — use cursor pagination instead. Pass cursor starting empty, read next_cursor from the response envelope, and pass it back on the next request; repeat until next_cursor is null (equivalently, has_more is false). Cursor mode is stable under concurrent inserts and is not subject to the page-mode row cap, which makes it the recommended way to page the whole history. In cursor mode page and total_count come back as null.
Errors
Beyond the universal 401 / 403 / 422 / 429 (see Errors):
- The endpoint never
404s — an app with no configured Partner API integration, or no events matching your filters, returns an emptydatalist (a200). - An unknown
event_type, or a malformed date, surfaces as422 validation_failed.