> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/medusajs/medusa/llms.txt
> Use this file to discover all available pages before exploring further.

# Products

> Admin API endpoints for managing products, variants, options, and inventory.

## Overview

The Products API allows you to create, update, retrieve, and manage products in your Medusa store. Products can have multiple variants, options, images, and be organized into collections and categories.

**Base Path:** `/admin/products`

**Source:** `packages/medusa/src/api/admin/products/route.ts`

## List Products

Retrieve a list of products with filtering and pagination.

```bash theme={null}
GET /admin/products
```

### Query Parameters

<ParamField query="fields" type="string">
  Comma-separated list of fields to include (e.g., `id,title,status,variants.sku`).
</ParamField>

<ParamField query="limit" type="number" default="15">
  Maximum number of products to return.
</ParamField>

<ParamField query="offset" type="number" default="0">
  Number of products to skip.
</ParamField>

<ParamField query="status" type="string">
  Filter by product status: `published`, `draft`, or `proposed`.
</ParamField>

<ParamField query="sales_channel_id" type="string">
  Filter products by sales channel ID.
</ParamField>

<ParamField query="collection_id" type="string">
  Filter products by collection ID.
</ParamField>

<ParamField query="tags" type="string[]">
  Filter products by tag IDs.
</ParamField>

<ParamField query="categories" type="string[]">
  Filter products by category IDs.
</ParamField>

<ParamField query="q" type="string">
  Search query for product title or description.
</ParamField>

### Request

```bash theme={null}
curl -X GET http://localhost:9000/admin/products \
  -H "Authorization: Bearer {token}" \
  -G \
  --data-urlencode "status=published" \
  --data-urlencode "limit=20"
```

### Response

```json theme={null}
{
  "products": [
    {
      "id": "prod_123",
      "title": "Premium T-Shirt",
      "subtitle": "Comfortable cotton tee",
      "status": "published",
      "description": "A high-quality cotton t-shirt",
      "handle": "premium-t-shirt",
      "is_giftcard": false,
      "discountable": true,
      "thumbnail": "https://example.com/image.jpg",
      "collection_id": "pcol_123",
      "type_id": "ptyp_123",
      "variants": [
        {
          "id": "variant_123",
          "title": "Small",
          "sku": "SHIRT-SM",
          "prices": [
            {
              "amount": 2999,
              "currency_code": "usd"
            }
          ]
        }
      ],
      "options": [
        {
          "id": "opt_123",
          "title": "Size",
          "values": ["Small", "Medium", "Large"]
        }
      ],
      "images": [
        {
          "id": "img_123",
          "url": "https://example.com/image.jpg"
        }
      ],
      "tags": [],
      "categories": [],
      "created_at": "2024-03-03T10:00:00.000Z",
      "updated_at": "2024-03-03T10:00:00.000Z"
    }
  ],
  "count": 100,
  "offset": 0,
  "limit": 20
}
```

<ResponseField name="products" type="Product[]">
  Array of product objects.
</ResponseField>

<ResponseField name="count" type="number">
  Total number of products matching the filters.
</ResponseField>

**Source:** `packages/medusa/src/api/admin/products/route.ts:17`

## Create Product

Create a new product with variants and options.

```bash theme={null}
POST /admin/products
```

### Request Body

<ParamField body="title" type="string" required>
  The product's title.
</ParamField>

<ParamField body="subtitle" type="string">
  The product's subtitle.
</ParamField>

<ParamField body="description" type="string">
  The product's description.
</ParamField>

<ParamField body="status" type="string" default="draft">
  Product status: `published`, `draft`, or `proposed`.
</ParamField>

<ParamField body="handle" type="string">
  Unique URL-friendly identifier. Auto-generated from title if not provided.
</ParamField>

<ParamField body="is_giftcard" type="boolean" default="false">
  Whether the product is a gift card.
</ParamField>

<ParamField body="discountable" type="boolean" default="true">
  Whether discounts can be applied to the product.
</ParamField>

<ParamField body="images" type="object[]">
  Product images.

  <Expandable>
    <ParamField body="url" type="string" required>
      Image URL.
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="thumbnail" type="string">
  URL of the product's thumbnail image.
</ParamField>

<ParamField body="collection_id" type="string">
  ID of the collection the product belongs to.
</ParamField>

<ParamField body="type_id" type="string">
  ID of the product type.
</ParamField>

<ParamField body="categories" type="object[]">
  Product categories.

  <Expandable>
    <ParamField body="id" type="string" required>
      Category ID.
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="tags" type="object[]">
  Product tags.

  <Expandable>
    <ParamField body="id" type="string" required>
      Tag ID.
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="options" type="object[]" required>
  Product options (e.g., Size, Color).

  <Expandable>
    <ParamField body="title" type="string" required>
      Option name.
    </ParamField>

    <ParamField body="values" type="string[]" required>
      Available option values.
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="variants" type="object[]">
  Product variants.

  <Expandable>
    <ParamField body="title" type="string" required>
      Variant title.
    </ParamField>

    <ParamField body="sku" type="string">
      Stock keeping unit.
    </ParamField>

    <ParamField body="prices" type="object[]" required>
      Variant prices.

      <Expandable>
        <ParamField body="currency_code" type="string" required>
          Currency code (e.g., "usd").
        </ParamField>

        <ParamField body="amount" type="number" required>
          Price amount in cents.
        </ParamField>
      </Expandable>
    </ParamField>

    <ParamField body="options" type="object">
      Option values for this variant (e.g., `{"Size": "Small"}`).
    </ParamField>

    <ParamField body="manage_inventory" type="boolean" default="true">
      Whether Medusa manages inventory for this variant.
    </ParamField>

    <ParamField body="allow_backorder" type="boolean" default="false">
      Allow orders when out of stock.
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="sales_channels" type="object[]">
  Sales channels where the product is available.

  <Expandable>
    <ParamField body="id" type="string" required>
      Sales channel ID.
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="weight" type="number">
  Product weight.
</ParamField>

<ParamField body="length" type="number">
  Product length.
</ParamField>

<ParamField body="height" type="number">
  Product height.
</ParamField>

<ParamField body="width" type="number">
  Product width.
</ParamField>

<ParamField body="metadata" type="object">
  Key-value pairs of custom metadata.
</ParamField>

### Request

```bash theme={null}
curl -X POST http://localhost:9000/admin/products \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Premium T-Shirt",
    "description": "A comfortable cotton t-shirt",
    "status": "published",
    "options": [
      {
        "title": "Size",
        "values": ["Small", "Medium", "Large"]
      }
    ],
    "variants": [
      {
        "title": "Small",
        "sku": "SHIRT-SM",
        "options": {"Size": "Small"},
        "prices": [
          {
            "currency_code": "usd",
            "amount": 2999
          }
        ]
      }
    ]
  }'
```

### Response

```json theme={null}
{
  "product": {
    "id": "prod_123",
    "title": "Premium T-Shirt",
    "status": "published",
    "variants": [...],
    "options": [...]
  }
}
```

**Source:** `packages/medusa/src/api/admin/products/route.ts:94`

**Types:** `packages/core/types/src/http/product/admin/payloads.ts:159`

## Get Product

Retrieve a single product by ID.

```bash theme={null}
GET /admin/products/{id}
```

### Path Parameters

<ParamField path="id" type="string" required>
  The product's ID.
</ParamField>

### Request

```bash theme={null}
curl -X GET http://localhost:9000/admin/products/prod_123 \
  -H "Authorization: Bearer {token}"
```

### Response

```json theme={null}
{
  "product": {
    "id": "prod_123",
    "title": "Premium T-Shirt",
    "variants": [...],
    "options": [...]
  }
}
```

## Update Product

Update an existing product.

```bash theme={null}
POST /admin/products/{id}
```

### Path Parameters

<ParamField path="id" type="string" required>
  The product's ID.
</ParamField>

### Request Body

Accepts the same fields as Create Product, all optional.

### Request

```bash theme={null}
curl -X POST http://localhost:9000/admin/products/prod_123 \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Updated Product Title",
    "status": "published"
  }'
```

### Response

```json theme={null}
{
  "product": {
    "id": "prod_123",
    "title": "Updated Product Title",
    "status": "published"
  }
}
```

## Delete Product

Delete a product (soft delete).

```bash theme={null}
DELETE /admin/products/{id}
```

### Path Parameters

<ParamField path="id" type="string" required>
  The product's ID.
</ParamField>

### Request

```bash theme={null}
curl -X DELETE http://localhost:9000/admin/products/prod_123 \
  -H "Authorization: Bearer {token}"
```

### Response

```json theme={null}
{
  "id": "prod_123",
  "object": "product",
  "deleted": true
}
```

## Product Variants

### Create Variant

Add a new variant to an existing product.

```bash theme={null}
POST /admin/products/{id}/variants
```

### Update Variant

Update a product variant.

```bash theme={null}
POST /admin/products/{id}/variants/{variant_id}
```

### Delete Variant

Remove a variant from a product.

```bash theme={null}
DELETE /admin/products/{id}/variants/{variant_id}
```

## Product Options

### Create Option

Add a new option to a product.

```bash theme={null}
POST /admin/products/{id}/options
```

### Update Option

Update a product option.

```bash theme={null}
POST /admin/products/{id}/options/{option_id}
```

### Delete Option

Remove an option from a product.

```bash theme={null}
DELETE /admin/products/{id}/options/{option_id}
```

## Batch Operations

### Batch Create/Update Products

Create or update multiple products in a single request.

```bash theme={null}
POST /admin/products/batch
```

### Request Body

<ParamField body="create" type="object[]">
  Products to create.
</ParamField>

<ParamField body="update" type="object[]">
  Products to update.

  <Expandable>
    <ParamField body="id" type="string" required>
      Product ID to update.
    </ParamField>
  </Expandable>
</ParamField>

## Next Steps

<CardGroup cols={2}>
  <Card title="Inventory" icon="boxes" href="/api/admin/inventory">
    Manage product inventory
  </Card>

  <Card title="Pricing" icon="dollar-sign" href="/api/admin/pricing">
    Configure product pricing
  </Card>
</CardGroup>
