Usage events
Read back the individual events your app has recorded through /track — each with its type, meta, timestamp, and shop — as a paginated object: "list". This is the per-event log; for aggregated metered totals by event_handle, use Usage metrics.
This endpoint only reads back your own /track data, so it is exempt from metering — it never counts against your monthly read quota.
Requires the usage:read scope. There is no Partner or BigQuery gate — an app that has tracked no events returns an empty list, not an error. Rows come back newest first.
Usage events
Returns the events your backend has posted to /track, newest first. Filter by an exact type, an exact shop, or an occurred_after / occurred_before window. The list is paginated — read has_more and total_count to page through it.
Path parameter
- Name
app- Type
- string
- Description
The team app's ULID, e.g.
01JN4HKQX0000000000000000.
Query parameters
- Name
type- Type
- string
- Description
Exact event type, e.g.
app_opened. Omit for every type.
- Name
shop- Type
- string
- Description
A
.myshopify.comdomain. Narrows to one shop's events. Omit for every shop.
- Name
occurred_after- Type
- string
- Description
ISO-8601 lower bound (inclusive) on when the event was recorded.
- Name
occurred_before- Type
- string
- Description
ISO-8601 upper bound (inclusive).
- Name
page- Type
- integer
- Description
The page to return. Default
1.
- Name
per_page- Type
- integer
- Description
Rows per page. Default
50, maximum100.
Request
curl -G https://ranksyapp.com/api/v1/apps/01JN4HKQX0000000000000000/usage-events \
-H "Authorization: Bearer rk_live_..." \
-d type=app_opened \
-d shop=acme-store.myshopify.com \
-d per_page=50
Response
{
"object": "list",
"url": "/api/v1/apps/01JN4HKQX0000000000000000/usage-events",
"page": 1,
"per_page": 50,
"total_count": 3,
"has_more": false,
"metadata": {
"filters": {
"type": "app_opened",
"shop": "acme-store.myshopify.com",
"occurred_after": null,
"occurred_before": null
}
},
"data": [
{
"id": 90218,
"type": "app_opened",
"meta": { "plan": "Pro", "page": "dashboard" },
"occurred_at": "2026-07-18T09:32:11+00:00",
"shop_domain": "acme-store.myshopify.com"
}
]
}
Response shapes
List envelope (object: "list")
- Name
object- Type
- string
- Description
Always
"list".
- Name
url- Type
- string
- Description
The endpoint path for this resource.
- Name
page- Type
- integer
- Description
The current page number (1-based).
- Name
per_page- Type
- integer
- Description
Rows per page.
- Name
total_count- Type
- integer
- Description
Total events across all pages, after filters.
- Name
has_more- Type
- boolean
- Description
Whether further pages exist.
- Name
metadata- Type
- object
- Description
Echoes the
filtersthat were applied.
- Name
data- Type
- array
- Description
The event rows for this page.
Event row
- Name
id- Type
- integer
- Description
Stable event id. Use it for MERGE / dedup.
- Name
type- Type
- string
- Description
The event type your backend recorded, e.g.
app_opened.
- Name
meta- Type
- object
- Description
Arbitrary metadata your backend attached, or
null.
- Name
occurred_at- Type
- string
- Description
ISO-8601 time the event was recorded.
- Name
shop_domain- Type
- string
- Description
The emitting shop's
.myshopify.comdomain, ornullwhen unresolved.
Pagination
Use page and per_page (default 50, max 100) to walk the list. total_count and has_more are computed after your filters. Ordering is fixed to newest first — there is no sort parameter.
Errors
Beyond the universal 401 / 403 / 422 / 429 (see Errors), this endpoint adds nothing. There is no 409 — events are written directly through /track, so the endpoint always returns a (possibly empty) list.