Reports

Every widget on the Analytics pages has an export: a CSV of exactly the rows it shows, for the date range on top of the page. The same tables are here, over any range, as JSON or CSV. Reports are free.

Ranges, grouping and time zone

Every report takes the same parameters. Days are read in your account's time zone (Settings → Profile; a team workspace uses the team owner's), so a month is your month, not a UTC month. Unset means UTC. Nofrom and no to means All time, by month. The response repeats the range and the zone it used.

fromFirst calendar day, YYYY-MM-DD, in your time zone. Omit it for All time.
toLast calendar day, inclusive, YYYY-MM-DD. Default: today. A bounded range covers at most 366 days.
groupday, week (ISO weeks, Monday start) or month. Default: day when from is given, month otherwise. Day needs a bounded range. The period column is YYYY-MM-DD, YYYY-Www or YYYY-MM.
passIdOptional: one pass. Without it, every pass of the workspace.
formatjson (default) or csv. CSV comes as a download with a header row, commas, UTF-8.

Read and full keys may call reports. A key restricted to specific passes gets those passes only. Analytics covers a workspace: use the key of the workspace whose passes you want.

Installs

What the summary cards, the Pass Breakdown and the downloads chart show: downloads by platform, re-downloads and removals. JSON gives one row per pass per period; by=period (default) or by=pass picks the CSV view.

GET /api/v1/reports/installs?from=2026-10-01&to=2026-10-31&group=week&by=pass&format=csv
Authorization: Bearer <api key>
Pass,Downloads,Apple,Google,Re-downloads,Removed
PMC Diamond Membership,42,30,12,3,1

Points by register

Who awarded what, where. One row per register per period: the number of awards (transactions), the points awarded, deductions and points deducted, and the members touched. Staff registers and partner registers (Camera Scan) both count. Points changed in Studio or over the API appear as "Studio" and "API" rows, so the totals reconcile with the pass. A register deleted since shows as "(deleted register)" with its id.

GET /api/v1/reports/points-by-register?from=2026-10-01&to=2026-10-31&group=month
Authorization: Bearer <api key>
{
  "from": "2026-10-01",
  "to": "2026-10-31",
  "group": "month",
  "timeZone": "Australia/Sydney",
  "rows": [
    {
      "period": "2026-10",
      "actor": "register",
      "registerId": "em06yeHepYnFFZpBSldv",
      "registerName": "Pham Motors Club",
      "registerKind": "partner",
      "transactions": 5,
      "pointsAwarded": 80,
      "deductions": 0,
      "pointsDeducted": 0,
      "members": 1
    },
    {
      "period": "2026-10",
      "actor": "studio",
      "registerId": null,
      "registerName": null,
      "registerKind": null,
      "transactions": 1,
      "pointsAwarded": 25,
      "deductions": 1,
      "pointsDeducted": 10,
      "members": 1
    }
  ]
}

With format=csv the same rows come as a file:

Period,Register,Kind,Transactions,Points awarded,Deductions,Points deducted,Members
2026-10,Pham Motors Club,Partner,5,80,0,0,1
2026-10,Studio,,1,25,1,10,1
  • Every points change on a card is one event with the register that made it; a transaction is one positive change.
  • Points awarded is the sum of positive changes; points deducted is the sum of negative ones, shown as a positive number.
  • Members counts distinct holders in the period, per row.

Acquisition

The Attribution funnel as a table: clicks (share-page views), installs and redemptions by UTM source, medium and campaign over the range. Redemptions attribute to the campaign that first acquired the holder. Untagged activity lands under (direct) and (none).

GET /api/v1/reports/acquisition?from=2026-10-01&to=2026-10-31&format=csv
Authorization: Bearer <api key>
Source,Medium,Campaign,Clicks,Installs,Redemptions
instagram,social,spring-launch,310,58,9
(direct),(none),(none),120,22,4

Loyalty activity

Per loyalty pass per period (a loyalty-type pass, or any pass that carries a loyalty program): new members, active members (anyone who earned, redeemed or visited), points earned, points redeemed, rewards redeemed and tier changes. A card with a loyalty program counts the program's events; a membership card without one counts its points changes. Two limits worth knowing: a membership card without a program has no "issued" event, so new members there counts first installs; a reward unlocked by a points threshold records no point cost and counts only under rewards redeemed.

GET /api/v1/reports/loyalty-activity?from=2026-10-01&to=2026-10-31&group=month&format=csv
Authorization: Bearer <api key>
Period,Pass,New members,Active members,Points earned,Points redeemed,Rewards redeemed,Tier changes
2026-10,PMC Diamond Membership,2,1,105,0,0,0

Redemptions

Every redemption on every pass type, per pass per source per period: the register that scanned (by name), "Square: location", "Shopify order" and the other channels, "API", "Studio". Members counts distinct holders. Revenue and currency appear where the redemption carried an amount, which the redeem API does when you pass an order; Shopify order totals live on the order event and are not joined here.

GET /api/v1/reports/redemptions?from=2026-10-01&to=2026-10-31&group=week&format=csv
Authorization: Bearer <api key>
Period,Pass,Source,Redemptions,Members,Revenue,Currency
2026-W41,Spring Coupon,Front Counter,14,13,,
2026-W41,Spring Coupon,Shopify order,6,6,,
2026-W41,Spring Coupon,API,3,3,145.5,USD

Errors

  • 400 invalid_request: a date is malformed, from is after to, a bounded range exceeds 366 days, or group=day without from.
  • 403 insufficient_scope: the key may not read the pass in passId.
  • A warning: "report_unavailable" with empty rows means the analytics store did not answer; retry.

In Studio

The date range sits on top of the Analytics page, of each pass's analytics page and of the Studio Analytics tab: the last 30 days by day when you arrive, then All time, the last 7 or 90 days, this month, last month, or custom dates, grouped by day, week or month. Every widget follows it and carries an Export CSV link. The CSV header row follows your Studio language; the API's is English.