---
title: "List products"
---

> Documentation Index
> Fetch the complete documentation index at: https://docs.cardzone.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# List products

Path: Cardzone B2B API › Catalog

`GET /api/b2b/v1/products`

Requires an active API credential with the `catalog:read` permission. Each row is a sellable denomination: use its id as product_id when ordering. Inspect recipient_fields for every required account field and its label before showing the order form. These fields are configured on the Cardzone Product, not its fulfillment sources. Catalog availability and credential restrictions still apply. By default only products you can order now are listed, all with `status: available`. Pass `include_unavailable=true` to also list products you can see but cannot order right now, with `status` `out_of_stock` or `unavailable`, so you can pause them instead of losing track of them. Hidden products, products without an active price, unprofitable products, and products of a delivery type your API credential cannot order are never listed. With a sandbox key, this endpoint returns static scenario products. Send one of those product `id` values as `product_id` when creating an order to trigger the matching hardcoded response.

## Authentication

- `BearerAuth`, http, header `Authorization`

## Query parameters

- `category_id` (`listProducts.query.category_id`; string, optional)
- `include_unavailable` (`listProducts.query.include_unavailable`; boolean, optional) — Also list products that cannot be ordered right now (`status` `out_of_stock` or `unavailable`).
  - default `false`

## Code samples

### cURL

```bash
curl --request GET \
  --url https://cardzone.ai/api/b2b/v1/products \
  --header 'Authorization: Bearer <token>'
```

### TypeScript

```typescript
const url = 'https://cardzone.ai/api/b2b/v1/products';
const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};

fetch(url, options)
  .then(res => res.json())
  .then(json => console.log(json))
  .catch(err => console.error(err));
```

### Python

```python
import requests

url = "https://cardzone.ai/api/b2b/v1/products"

headers = {"Authorization": "Bearer <token>"}

response = requests.get(url, headers=headers)

print(response.text)
```

## Responses

### 200

Products. With sandbox keys, this returns static scenario products whose `id` values trigger hardcoded order responses.

#### Example

```json
{
  "products": [
    {
      "id": "018f7b75-0194-726a-9814-e26efa39dfa1",
      "name": "PUBG 60 UC",
      "status": "available",
      "delivery_type": "topup",
      "recipient_fields": [
        {
          "key": "player_id",
          "label": "Player ID",
          "required": true
        }
      ],
      "player_lookup": true,
      "purchase_price": {
        "amount": "10.00",
        "currency": "SAR"
      },
      "recommended_retail_price": {
        "amount": "12.00",
        "currency": "SAR"
      }
    },
    {
      "id": "018f7b75-0194-726a-9814-e26efa39dfa2",
      "name": "Mobile Legends 86 Diamonds",
      "status": "available",
      "delivery_type": "topup",
      "recipient_fields": [
        {
          "key": "player_id",
          "label": "Player ID",
          "required": true
        },
        {
          "key": "zone_id",
          "label": "Zone ID",
          "required": true
        }
      ],
      "player_lookup": true,
      "purchase_price": {
        "amount": "10.00",
        "currency": "SAR"
      },
      "recommended_retail_price": {
        "amount": "12.00",
        "currency": "SAR"
      }
    },
    {
      "id": "018f7b75-0194-726a-9814-e26efa39dfa3",
      "name": "Configurable Game 100 Credits",
      "status": "available",
      "delivery_type": "topup",
      "recipient_fields": [
        {
          "key": "player_id",
          "label": "Player ID",
          "required": true
        },
        {
          "key": "region_id",
          "label": "Region ID",
          "required": true
        },
        {
          "key": "account_tag",
          "label": "Account tag",
          "required": true
        }
      ],
      "player_lookup": false,
      "purchase_price": {
        "amount": "10.00",
        "currency": "SAR"
      },
      "recommended_retail_price": {
        "amount": "12.00",
        "currency": "SAR"
      }
    }
  ]
}
```

- `products` (`listProducts.response.200.products`; array<object>, required)
  - `id` (`listProducts.response.200.products.id`; string, required) — Sellable Cardzone product/variant UUID. In sandbox mode, this is also the scenario selector for hardcoded order responses.
    - format `uuid`
  - `name` (`listProducts.response.200.products.name`; string, required)
  - `status` (`listProducts.response.200.products.status`; string, required) — `available`: you can order it now. `out_of_stock`: Cardzone has marked it out of stock, and your store has none of its own stock. It stays out of stock until Cardzone marks it available again. `unavailable`: there is no way to fulfill it for your store. In order errors it also covers products that are hidden for your store or have no active price; the catalog never lists those. Orders for products that are not `available` are rejected with `404` and the same value in `error.product_status`.
    - one of `"available"`, `"out_of_stock"`, `"unavailable"`
  - `delivery_type` (`listProducts.response.200.products.delivery_type`; string, required)
    - one of `"voucher"`, `"topup"`
  - `purchase_price` (`listProducts.response.200.products.purchase_price`; object, required) — Your merchant unit price
    - `amount` (`listProducts.response.200.products.purchase_price.amount`; string, required) — Decimal amount as a string
      - example `"12.00"`
    - `currency` (`listProducts.response.200.products.purchase_price.currency`; string, required)
      - example `"SAR"`
  - `recommended_retail_price` (`listProducts.response.200.products.recommended_retail_price`; object, required) — Suggested resale unit price
    - `amount` (`listProducts.response.200.products.recommended_retail_price.amount`; string, required) — Decimal amount as a string
      - example `"12.00"`
    - `currency` (`listProducts.response.200.products.recommended_retail_price.currency`; string, required)
      - example `"SAR"`
  - `recipient_fields` (`listProducts.response.200.products.recipient_fields`; array<object>, required) — Required fields configured on the Cardzone Product, in display order and independent of provider routing. Empty for voucher rows.
    - `key` (`listProducts.response.200.products.recipient_fields.key`; string, required) — Product-configured canonical key, including custom keys such as region_id or account_tag. Never a provider parameter name.
      - pattern `^(?!constructor$|prototype$)[a-z][a-z0-9_]*$`
    - `label` (`listProducts.response.200.products.recipient_fields.label`; string, required) — Localized display label; use key, not label, in recipient requests.
    - `required` (`listProducts.response.200.products.recipient_fields.required`; boolean, required)
      - one of `true`
  - `product_code` (`listProducts.response.200.products.product_code`; string, optional) — Cardzone internal product code for support/debugging. In sandbox mode this identifies the static response scenario.
  - `description` (`listProducts.response.200.products.description`; string, optional, nullable)
  - `category_id` (`listProducts.response.200.products.category_id`; string, optional, nullable) — Category slug
  - `category_name` (`listProducts.response.200.products.category_name`; string, optional, nullable)
  - `player_lookup` (`listProducts.response.200.products.player_lookup`; boolean, optional) — True when `POST /api/b2b/v1/player_profiles` can resolve the in-game profile for this product's recipient. Always false for voucher rows.

### 401

Missing, revoked, or unknown API key. A live key also gets this while its store is inactive, or until the store's business verification is approved and its primary user's email is verified.

#### Example

```json
{
  "error": {
    "code": "string",
    "message": "string",
    "details": null,
    "product_status": "out_of_stock"
  }
}
```

- `error` (`listProducts.response.401.error`; object, required)
  - `code` (`listProducts.response.401.error.code`; string, required)
  - `message` (`listProducts.response.401.error.message`; string, required)
  - `details` (`listProducts.response.401.error.details`; unknown, optional) — Optional field-level validation details
  - `product_status` (`listProducts.response.401.error.product_status`; string, optional) — Present on `404` product errors when the product exists but cannot be ordered: `out_of_stock` or `unavailable`, with the same meaning as the catalog `status`. Absent when the product id is unknown or deleted.
    - one of `"out_of_stock"`, `"unavailable"`

### 403

`forbidden` when the API credential lacks the required permission, or `insufficient_store_wallet_balance` when a live key's store does not meet the wallet requirement.

#### Example

```json
{
  "error": {
    "code": "string",
    "message": "string",
    "details": null,
    "product_status": "out_of_stock"
  }
}
```

- `error` (`listProducts.response.403.error`; object, required)
  - `code` (`listProducts.response.403.error.code`; string, required)
  - `message` (`listProducts.response.403.error.message`; string, required)
  - `details` (`listProducts.response.403.error.details`; unknown, optional) — Optional field-level validation details
  - `product_status` (`listProducts.response.403.error.product_status`; string, optional) — Present on `404` product errors when the product exists but cannot be ordered: `out_of_stock` or `unavailable`, with the same meaning as the catalog `status`. Absent when the product id is unknown or deleted.
    - one of `"out_of_stock"`, `"unavailable"`

### 404

Category was not found

#### Example

```json
{
  "error": {
    "code": "string",
    "message": "string",
    "details": null,
    "product_status": "out_of_stock"
  }
}
```

- `error` (`listProducts.response.404.error`; object, required)
  - `code` (`listProducts.response.404.error.code`; string, required)
  - `message` (`listProducts.response.404.error.message`; string, required)
  - `details` (`listProducts.response.404.error.details`; unknown, optional) — Optional field-level validation details
  - `product_status` (`listProducts.response.404.error.product_status`; string, optional) — Present on `404` product errors when the product exists but cannot be ordered: `out_of_stock` or `unavailable`, with the same meaning as the catalog `status`. Absent when the product id is unknown or deleted.
    - one of `"out_of_stock"`, `"unavailable"`


Source: https://docs.cardzone.ai/reference/products/list/index.md
