---
title: "List purchases for a user"
method: GET
path: "/users/{user_id}/purchases"
tags: ["Purchases"]
---

# List purchases for a user

`GET /users/{user_id}/purchases`

Returns a paginated list of purchases for the specified user.
Purchases are ordered by purchase date (newest first).
Supports cursor-based pagination and optional platform filtering.

## Path parameters

- `user_id` string, required

## Query parameters

- `limit` integer
- `starting_after` string
- `filter[platform]` string[]

## Response `200`

A paginated list of purchases.

- V4PurchaseList
  - `object` 'list', required
  - `url` string, required
  - `data` V4Purchase[], required
    - `object` 'purchase', required
    - `id` string, required
    - `url` string, required
    - `user_id` string, required
    - `platform` string, required — Store that originated the transaction. Determines the shape of `store_data`.
    - `product_id` string, required — Qonversion product identifier. For Play Store subscriptions with a base plan, the value is `{product_id}:{base_plan_id}`.
    - `currency` string, required — Three-letter ISO 4217 currency code. May be empty when the source transaction lacks currency (e.g. legacy imports).
    - `price` string, required — Monetary amount as a decimal string. May be empty when the source transaction lacks a price.
    - `purchased_at` string, date-time, required — Time the store reported the transaction (RFC 3339 / ISO 8601).
    - `expires_at` string, date-time, nullable — Subscription expiry time, or `null` for non-expiring purchases and consumables.
    - `is_auto_renewing` boolean, required — Whether the subscription is set to auto-renew. `false` for one-time purchases and cancelled subscriptions.
    - `store_data` union, required — Platform-specific identifiers. The `platform` field on the enclosing purchase selects which shape is returned: `app_store` → `V4PurchaseAppStoreData`, `play_store` → `V4PurchasePlayStoreData`, `stripe` → `V4PurchaseStripeStoreData`. A native OpenAPI `discriminator` is not declared because the selector lives on the parent object, not on `store_data` itself.
      - V4PurchaseAppStoreData — `store_data` shape when `platform` is `app_store`.
        - `transaction_id` string, required — App Store transaction identifier for this specific purchase.
        - `original_transaction_id` string, required — App Store original transaction identifier (shared across renewals).
        - `product_id` string, required — App Store product identifier.
      - V4PurchasePlayStoreData — `store_data` shape when `platform` is `play_store`. For subscriptions with a base plan, the enclosing purchase's `product_id` is `{product_id}:{base_plan_id}` (e.g. `com.example.yearly:monthly-base`), while the `product_id` here stays the bare Google Play product id.
        - `order_id` string, required — Google Play order identifier.
        - `purchase_token` string, required — Google Play purchase token.
        - `product_id` string, required — Google Play product identifier.
      - V4PurchaseStripeStoreData — `store_data` shape when `platform` is `stripe`.
        - `subscription_id` string, required — Stripe subscription identifier.
        - `product_id` string, required — Stripe product identifier.
    - `created_at` string, date-time, required — Time Qonversion first recorded the purchase. For history imported from the store this currently mirrors `purchased_at`.
  - `has_more` boolean, required
  - `next_cursor` string, nullable — ID to pass as `starting_after` on the next request. Present only when `has_more` is `true`; otherwise `null`.

## Other responses

- `400` — Invalid request
- `401` — Unauthorized
- `404` — User not found
- `500` — Internal error
- `502` — Storage error
- `504` — Upstream timeout

---

[API](https://skmtc.net/qonversion/apis/qonversion-rest-api-v4.md) · [All operations](https://skmtc.net/qonversion/apis/qonversion-rest-api-v4/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/qonversion/qonversion-rest-api-v4/revisions/e3f72cf8951c/schema)
