# Points Shop catalogue

> Browse the synchronized Steam Points Shop catalogue and inspect individual rewards.


Read the same catalogue SteamLabs uses in its Points Shop picker. The catalogue is shared across users and refreshed by SteamLabs through the shared proxy pool. Use a [`buy_point_shop_items` task](/docs/api/en/endpoints/tasks#account-and-wallet) to purchase exact definitions or spend against catalogue filters.

The `point-shop.read` scope covers both catalogue endpoints. Creating and reading purchase tasks uses `tasks.write` and `tasks.read`.

## List catalogue items

```endpoint
method: GET
path: /api/v1/point-shop/items
description: List active rewards that Steam allows clients to purchase directly.
auth: bearer
```

Requires `point-shop.read`.

| Parameter | Type | Description |
| --- | --- | --- |
| `search` | string | At least 2 characters. Matches the displayed title, internal name, and Steam description |
| `classes[]` | integer[] | One or more Steam community item class IDs. `1` is seasonal badges |
| `app_id` | integer | Only rewards attached to this Steam app |
| `apps[]` | integer[] | Rewards attached to any of these Steam apps, up to 20. Combined with `app_id` when both are sent |
| `minimum_cost` | integer | Minimum point cost, inclusive |
| `maximum_cost` | integer | Maximum point cost, inclusive |
| `sort` | string | `newest` (default), `updated`, `cost_low`, `cost_high`, or `name` |
| `per_page` | integer | Defaults to 50, capped at 200 |
| `page` | integer | Page number |

```bash tab=curl
curl "https://dashboard.steamlabs.dev/api/v1/point-shop/items?classes[]=3&maximum_cost=2000&sort=cost_low" \
  -H "Authorization: Bearer $STEAMLABS_API_KEY"
```

```php tab=PHP
$items = Http::withToken($apiKey)
    ->get('https://dashboard.steamlabs.dev/api/v1/point-shop/items', [
        'classes' => [3],
        'maximum_cost' => 2000,
        'sort' => 'cost_low',
    ])
    ->json();
```

```json
{
    "data": [
        {
            "definition_id": 120050,
            "app_id": 730,
            "app_name": "Counter-Strike 2",
            "title": "Blue Horizon",
            "name": "blue_horizon",
            "category": {
                "id": 3,
                "label": "Profile backgrounds"
            },
            "point_cost": 2000,
            "animated": false,
            "images": {
                "small": "https://shared.fastly.steamstatic.com/community_assets/images/items/730/example.png",
                "large": "https://shared.fastly.steamstatic.com/community_assets/images/items/730/example.png"
            },
            "steam_created_at": "2026-07-01T12:00:00+00:00",
            "steam_updated_at": "2026-07-28T09:20:00+00:00",
            "fetched_at": "2026-08-05T14:20:00+00:00"
        }
    ],
    "meta": {
        "page": 1,
        "per_page": 50,
        "total": 1,
        "last_page": 1
    }
}
```

Only active catalogue entries with direct purchasing enabled appear in the list. Past Summer and Winter collection badges stay active in Steam's dump with no end date, but Steam's Seasonal Badge page only sells the current sale, so those past-year definitions are omitted here too. A reward may still require the account to own its game or meet Steam's playtime requirement. Those rules are account-specific and cannot be decided from the public catalogue alone.

## Read one item

```endpoint
method: GET
path: /api/v1/point-shop/items/{definition_id}
description: Read one reward definition from the current catalogue.
auth: bearer
```

Requires `point-shop.read`.

```bash tab=curl
curl https://dashboard.steamlabs.dev/api/v1/point-shop/items/120050 \
  -H "Authorization: Bearer $STEAMLABS_API_KEY"
```

The response adds the reward description, raw category fields, quantity, availability window, bundle definition IDs, and bundle discount to the list shape.

An item outside the current synchronized catalogue returns `404`. This includes rewards Steam removed after a completed catalogue refresh, and past seasonal collection badges the storefront is no longer selling.

## Catalogue freshness

`fetched_at` tells you when SteamLabs last fetched that definition. A catalogue refresh is generation-based: incomplete or paused runs never remove items from the previous complete generation. Items disappear only after a complete sweep confirms that Steam no longer returns them.

The standard `401`, `403 missing_scope`, `404 not_found`, `422 validation_failed`, and `429` responses apply. See [Errors](/docs/api/en/concepts/errors).
