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

# Get Product Details

> Retrieve a single product by slug, its subscription variants, and related products.

## GET /products/{slug}

Get detailed product information by slug. Includes categories, subscription variants, course structure, and codes availability.

### Authentication

None required.

### Path Parameters

| Parameter | Type   | Description      |
| --------- | ------ | ---------------- |
| slug      | string | Product URL slug |

### Example Request

<CodeGroup>
  ```bash cURL theme={null}
  curl "https://front.rmz.gg/api/products/premium-game-key"
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch("https://front.rmz.gg/api/products/premium-game-key");
  const data = await response.json();
  ```

  ```python Python theme={null}
  response = requests.get("https://front.rmz.gg/api/products/premium-game-key")
  data = response.json()
  ```

  ```php PHP theme={null}
  $response = Http::get("https://front.rmz.gg/api/products/premium-game-key");
  $data = $response->json();
  ```
</CodeGroup>

### Response

#### Success (200)

The response uses the same `ProductResource` structure as the list endpoint, including nested `price`, `stock`, and `seo` objects. Subscription variants and course data are included when applicable.

```json theme={null}
{
  "success": true,
  "data": {
    "id": 101,
    "name": "Premium Game Key",
    "marketing_title": null,
    "slug": "premium-game-key",
    "description": "Premium game activation key for PC",
    "short_description": "Premium game activation key for PC...",
    "type": "code",
    "status": 1,
    "is_featured": false,
    "is_noticeable": false,
    "is_new": false,
    "is_discounted": false,
    "is_discount_expired": false,
    "show_reviews": true,
    "price": {
      "original": 199.99,
      "actual": 199.99,
      "discount": null,
      "discount_expiry": null,
      "show_discount_countdown": false,
      "show_discount_savings": false,
      "savings_amount": 0,
      "formatted": "199.99 ر.س",
      "formatted_original": "199.99 ر.س",
      "discount_percentage": 0,
      "currency": "SAR"
    },
    "stock": {
      "available": 50,
      "unlimited": false,
      "min_qty": 1,
      "codes_count": 50,
      "is_in_stock": true
    },
    "sales": {
      "badge": null
    },
    "image": {
      "id": 1,
      "url": "https://...",
      "full_link": "https://...",
      "path": "...",
      "filename": "image.webp",
      "alt_text": "Premium Game Key"
    },
    "categories": [
      {
        "id": 1,
        "name": "Games",
        "slug": "games",
        "description": null,
        "image": null,
        "icon": null,
        "is_active": true,
        "sort_order": 0,
        "created_at": "2024-01-01T00:00:00.000000Z",
        "updated_at": "2024-06-15T10:30:00.000000Z"
      }
    ],
    "subscription_variants": [],
    "course": null,
    "fields": null,
    "meta": null,
    "metadata": null,
    "tags": null,
    "seo": {
      "meta_title": null,
      "meta_description": null,
      "meta_keywords": null
    },
    "created_at": "2024-06-15T10:30:00.000000Z",
    "updated_at": "2024-06-15T10:30:00.000000Z"
  }
}
```

For a **subscription** product, the `subscription_variants` field contains plan options with localized formatting:

```json theme={null}
{
  "subscription_variants": [
    {
      "id": 1,
      "price": 49.99,
      "duration": "monthly",
      "duration_text": "شهري",
      "duration_text_en": "1 Month",
      "formatted_price": "49.99 ر.س",
      "features": [
        { "id": 1, "name": "Feature A", "description": "..." },
        { "id": 2, "name": "Feature B", "description": "..." }
      ]
    }
  ]
}
```

For a **course** product, the `course` field contains the course structure:

```json theme={null}
{
  "course": {
    "id": 5,
    "instructor": "John Doe",
    "level": "beginner",
    "level_arabic": "مبتدئ",
    "sections": [
      {
        "id": 1,
        "title": "Getting Started",
        "description": "Introduction to the course",
        "sort_index": 0,
        "modules": [
          { "id": 1, "title": "Introduction", "description": "...", "type": "video", "sort_index": 0, "duration_minutes": 15 },
          { "id": 2, "title": "Setup", "description": "...", "type": "text", "sort_index": 1, "duration_minutes": 10 }
        ]
      }
    ],
    "total_modules": 2,
    "estimated_duration": 25
  }
}
```

#### Error Responses

| Status | Description                                                |
| ------ | ---------------------------------------------------------- |
| 404    | Product not found (invalid slug, inactive, or wrong store) |

<Note>
  Products with status `3` (hidden/deleted) are excluded from this endpoint.
</Note>

***

## GET /products/{id}/variants

Get subscription variants for a subscription product. Returns active variants sorted by display order.

### Authentication

None required.

### Path Parameters

| Parameter | Type    | Description                                      |
| --------- | ------- | ------------------------------------------------ |
| id        | integer | Product ID (must be a subscription-type product) |

### Example Request

<CodeGroup>
  ```bash cURL theme={null}
  curl "https://front.rmz.gg/api/products/101/variants"
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch("https://front.rmz.gg/api/products/101/variants");
  const data = await response.json();
  ```

  ```python Python theme={null}
  response = requests.get("https://front.rmz.gg/api/products/101/variants")
  data = response.json()
  ```

  ```php PHP theme={null}
  $response = Http::get("https://front.rmz.gg/api/products/101/variants");
  $data = $response->json();
  ```
</CodeGroup>

### Response

#### Success (200)

The variants endpoint returns raw database fields (not the ProductResource format):

```json theme={null}
{
  "success": true,
  "data": [
    {
      "id": 1,
      "name": "Monthly Plan",
      "description": "Access for one month",
      "price": 49.99,
      "duration_type": "month",
      "duration_value": 1,
      "features": "..."
    },
    {
      "id": 2,
      "name": "Annual Plan",
      "description": "Access for one year",
      "price": 399.99,
      "duration_type": "year",
      "duration_value": 1,
      "features": "..."
    }
  ]
}
```

#### Error Responses

| Status | Description                                  |
| ------ | -------------------------------------------- |
| 404    | Product not found or not a subscription type |

***

## GET /products/{id}/related

Get products related to the specified product, based on shared categories.

### Authentication

None required.

### Path Parameters

| Parameter | Type    | Description |
| --------- | ------- | ----------- |
| id        | integer | Product ID  |

### Query Parameters

| Parameter | Type    | Required | Description                               |
| --------- | ------- | -------- | ----------------------------------------- |
| limit     | integer | No       | Number of related products (default: `8`) |

### Example Request

<CodeGroup>
  ```bash cURL theme={null}
  curl "https://front.rmz.gg/api/products/101/related?limit=4"
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch("https://front.rmz.gg/api/products/101/related?limit=4");
  const data = await response.json();
  ```

  ```python Python theme={null}
  response = requests.get("https://front.rmz.gg/api/products/101/related", params={"limit": 4})
  data = response.json()
  ```

  ```php PHP theme={null}
  $response = Http::get("https://front.rmz.gg/api/products/101/related", ["limit" => 4]);
  $data = $response->json();
  ```
</CodeGroup>

### Response

#### Success (200)

Returns the same `ProductResource` structure as `GET /products`. See [List Products](/storefront-api/products/list-products) for the full response schema.

```json theme={null}
{
  "success": true,
  "data": [
    {
      "id": 102,
      "name": "Standard Game Key",
      "marketing_title": null,
      "slug": "standard-game-key",
      "description": "Standard game activation key",
      "short_description": "Standard game activation key...",
      "type": "code",
      "status": 1,
      "is_featured": false,
      "is_noticeable": false,
      "is_new": false,
      "is_discounted": false,
      "is_discount_expired": false,
      "show_reviews": true,
      "price": {
        "original": 99.99,
        "actual": 99.99,
        "discount": null,
        "discount_expiry": null,
        "show_discount_countdown": false,
        "show_discount_savings": false,
        "savings_amount": 0,
        "formatted": "99.99 ر.س",
        "formatted_original": "99.99 ر.س",
        "discount_percentage": 0,
        "currency": "SAR"
      },
      "stock": {
        "available": 25,
        "unlimited": false,
        "min_qty": 1,
        "codes_count": 25,
        "is_in_stock": true
      },
      "sales": {
        "badge": null
      },
      "image": {
        "id": 2,
        "url": "https://...",
        "full_link": "https://...",
        "path": "...",
        "filename": "image.webp",
        "alt_text": "Standard Game Key"
      },
      "categories": [],
      "fields": null,
      "meta": null,
      "metadata": null,
      "tags": null,
      "seo": {
        "meta_title": null,
        "meta_description": null,
        "meta_keywords": null
      },
      "created_at": "2024-06-10T08:00:00.000000Z",
      "updated_at": "2024-06-10T08:00:00.000000Z"
    }
  ]
}
```

<Tip>
  Related products are randomly shuffled from products sharing the same categories. Results will vary between requests. Only the `image` relation is loaded for related products.
</Tip>

#### Error Responses

| Status | Description       |
| ------ | ----------------- |
| 404    | Product not found |
