# Package purchases

> Each checkout a client completed for one of your packages, paid or free.

Source: https://hubfit.com/developers/api/package-purchases


A package purchase is one checkout a client completed for one of your packages, paid or free, with the package's name as it was then and what the client paid. A purchase isn't revenue: renewals and refunds aren't purchases. Purchases made before this API launched aren't recorded.

Endpoints:

- `GET /v1/package-purchases`: [List package purchases](https://hubfit.com/developers/api/package-purchases#list-package-purchases)
- `GET /v1/package-purchases/{purchaseId}`: [Get a package purchase](https://hubfit.com/developers/api/package-purchases#get-package-purchase)

## Package purchase object

### Attributes

- `id` (string): Its unique ID.
- `client` (object)
  - `id` (string): Its unique ID.
  - `name` (string)
- `package` (object)
  - `id` (string): Its unique ID.
  - `name` (string): As it was when bought.
- `amount` (integer): What the client paid at checkout, in the currency's minor units (cents, or thousandths for KWD and BHD), as Stripe's amounts are. `0` for a free package, a free trial or a full discount.
- `currency` (string): ISO 4217, lowercase, e.g. `usd`.
- `free` (boolean): Whether the package was free. A paid package bought on a free trial or with a full discount is `false`, with an `amount` of `0`.
- `purchasedAt` (timestamp)

### Example

```json
{
  "id": "6ad6afb04b9e86b14ba019ae",
  "client": {
    "id": "6ad6af41d3199442d31b2743",
    "name": "Jordan Miller"
  },
  "package": {
    "id": "6ad6afd1a10559d0a103c6cf",
    "name": "12-week online coaching"
  },
  "amount": 14900,
  "currency": "usd",
  "free": false,
  "purchasedAt": "2026-10-26T14:32:05.000Z"
}
```

## List package purchases

`GET https://api.hubfit.com/v1/package-purchases`

Packages your clients bought, most recent first. Across every client you can reach (team members with the Standard role only see their assigned clients), or one client's with `clientId`. To pick up new purchases, read from the newest and stop at one you've seen before. Requires `clients:read`.

### Query parameters

- `clientId` (string): Only this client's purchases.
- `startDate` (date): Only purchases from this day, included, as `YYYY-MM-DD`, in your own calendar (the timezone in your HubFit settings).
- `endDate` (date): Only purchases up to this day, included, as `YYYY-MM-DD`, in your own calendar.
- `limit` (integer): How many results to return, from 1 to 100. Default `25`.
- `cursor` (string): The `nextCursor` from the previous page.

### Returns

A page of package purchases.

### Example request

cURL:

```bash
curl -G https://api.hubfit.com/v1/package-purchases \
  -H "Authorization: Bearer $HUBFIT_API_KEY" \
  -d startDate=2026-10-01
```

Node.js:

```javascript
const response = await fetch("https://api.hubfit.com/v1/package-purchases?startDate=2026-10-01", {
  headers: {
    Authorization: `Bearer ${process.env.HUBFIT_API_KEY}`,
  },
});

const { data, nextCursor } = await response.json();
```

Python:

```python
import os
import requests

response = requests.get(
    "https://api.hubfit.com/v1/package-purchases",
    headers={"Authorization": f"Bearer {os.environ['HUBFIT_API_KEY']}"},
    params={
        "startDate": "2026-10-01",
    },
)

page = response.json()
data, next_cursor = page["data"], page["nextCursor"]
```

### Example response (200 OK)

```json
{
  "data": [
    {
      "id": "6ad6afb04b9e86b14ba019ae",
      "client": {
        "id": "6ad6af41d3199442d31b2743",
        "name": "Jordan Miller"
      },
      "package": {
        "id": "6ad6afd1a10559d0a103c6cf",
        "name": "12-week online coaching"
      },
      "amount": 14900,
      "currency": "usd",
      "free": false,
      "purchasedAt": "2026-10-26T14:32:05.000Z"
    }
  ],
  "nextCursor": "eyJpZCI6IjZhZDZhZjNmMjljNTk3ZjE1In0",
  "totalCount": 48
}
```

## Get a package purchase

`GET https://api.hubfit.com/v1/package-purchases/{purchaseId}`

One package purchase, such as the one a `package_purchase.created` webhook names. Requires `clients:read`.

### Path parameters

- `purchaseId` (string, required): The purchase's `id`.

### Returns

The package purchase.

### Example request

cURL:

```bash
curl https://api.hubfit.com/v1/package-purchases/6ad6afb04b9e86b14ba019ae \
  -H "Authorization: Bearer $HUBFIT_API_KEY"
```

Node.js:

```javascript
const response = await fetch("https://api.hubfit.com/v1/package-purchases/6ad6afb04b9e86b14ba019ae", {
  headers: {
    Authorization: `Bearer ${process.env.HUBFIT_API_KEY}`,
  },
});

const { data } = await response.json();
```

Python:

```python
import os
import requests

response = requests.get(
    "https://api.hubfit.com/v1/package-purchases/6ad6afb04b9e86b14ba019ae",
    headers={"Authorization": f"Bearer {os.environ['HUBFIT_API_KEY']}"},
)

data = response.json()["data"]
```

### Example response (200 OK)

```json
{
  "data": {
    "id": "6ad6afb04b9e86b14ba019ae",
    "client": {
      "id": "6ad6af41d3199442d31b2743",
      "name": "Jordan Miller"
    },
    "package": {
      "id": "6ad6afd1a10559d0a103c6cf",
      "name": "12-week online coaching"
    },
    "amount": 14900,
    "currency": "usd",
    "free": false,
    "purchasedAt": "2026-10-26T14:32:05.000Z"
  }
}
```

## Webhook events

- `package_purchase.created`: A client bought a package. Sent once the client exists, for a paid or a free package. Fetch the purchase with `GET /package-purchases/{id}`. It records a purchase, not revenue: renewals and refunds aren't sent.

An event carries the record's `id` and its `clientId`, not the record. See [Webhooks](https://hubfit.com/developers/webhooks).
