# Products

> Create, retrieve, update, delete, and list products.

A product describes a good or service you sell. Products are the top-level catalog object; pricing
information is attached separately via [Prices](/docs/api-reference/prices).

> **Illustrative content.** Hand-authored to demonstrate the Standard/Advanced pattern; the production
> page will be generated from the VINR OpenAPI spec (roadmap item #1). Field names are representative.

## The product object

- **id** `string` — Unique identifier for the product, e.g. `prod_7Kc4mNpQ`.
- **name** `string` — The product's display name, shown on invoices and the customer portal.
- **description** `string` — An optional description of the product. Shown on invoices.
- **active** `boolean` — Whether the product is currently available for purchase. Defaults to `true`.
- **images** `array` — A list of up to 8 URLs of images for this product.
- **created** `integer` — Unix timestamp of when the product was created, e.g. `1716300000`.

## Create a product

Pass a `name` and optional `description` to create a new product in your catalog.

`POST /v1/products`

```bash
curl -X POST https://api.vinr.com/v1/products \
-H "X-Api-Key: $VINR_SECRET_KEY" \
-d name="Pro Plan" \
-d description="Full access to all VINR features"
```

```js
import { Vinr } from '@vinr/sdk';

const vinr = new Vinr({ secretKey: process.env.VINR_SECRET_KEY });

const product = await vinr.products.create({
name: 'Pro Plan',
description: 'Full access to all VINR features',
});
```

```python
import vinr

product = vinr.Product.create(
  name="Pro Plan",
  description="Full access to all VINR features",
)
```

```ruby
product = Vinr::Product.create(
name: 'Pro Plan',
description: 'Full access to all VINR features',
)
```

```json
{
"id": "prod_7Kc4mNpQ",
"name": "Pro Plan",
"description": "Full access to all VINR features",
"active": true,
"images": [],
"created": 1716300000
}
```

## Retrieve a product

`GET /v1/products/{id}`

```bash
curl https://api.vinr.com/v1/products/prod_7Kc4mNpQ \
-H "X-Api-Key: $VINR_SECRET_KEY"
```

```js
import { Vinr } from '@vinr/sdk';

const vinr = new Vinr({ secretKey: process.env.VINR_SECRET_KEY });

const product = await vinr.products.retrieve('prod_7Kc4mNpQ');
```

```python
import vinr

product = vinr.Product.retrieve("prod_7Kc4mNpQ")
```

```ruby
product = Vinr::Product.retrieve('prod_7Kc4mNpQ')
```

```json
{
"id": "prod_7Kc4mNpQ",
"name": "Pro Plan",
"description": "Full access to all VINR features",
"active": true,
"images": [],
"created": 1716300000
}
```

## Update a product

`POST /v1/products/{id}`

```bash
curl -X POST https://api.vinr.com/v1/products/prod_7Kc4mNpQ \
-H "X-Api-Key: $VINR_SECRET_KEY" \
-d name="Pro Plan (Updated)" \
-d active=true
```

```js
import { Vinr } from '@vinr/sdk';

const vinr = new Vinr({ secretKey: process.env.VINR_SECRET_KEY });

const product = await vinr.products.update('prod_7Kc4mNpQ', {
name: 'Pro Plan (Updated)',
active: true,
});
```

```python
import vinr

product = vinr.Product.modify(
  "prod_7Kc4mNpQ",
  name="Pro Plan (Updated)",
  active=True,
)
```

```ruby
product = Vinr::Product.update(
'prod_7Kc4mNpQ',
name: 'Pro Plan (Updated)',
active: true,
)
```

```json
{
"id": "prod_7Kc4mNpQ",
"name": "Pro Plan (Updated)",
"description": "Full access to all VINR features",
"active": true,
"images": [],
"created": 1716300000
}
```

## Delete a product

Deleting a product removes it from the catalog. Products with active prices cannot be deleted;
archive them by setting `active: false` instead.

`DELETE /v1/products/{id}`

```bash
curl -X DELETE https://api.vinr.com/v1/products/prod_7Kc4mNpQ \
-H "X-Api-Key: $VINR_SECRET_KEY"
```

```js
import { Vinr } from '@vinr/sdk';

const vinr = new Vinr({ secretKey: process.env.VINR_SECRET_KEY });

await vinr.products.delete('prod_7Kc4mNpQ');
```

```python
import vinr

vinr.Product.delete("prod_7Kc4mNpQ")
```

```ruby
Vinr::Product.delete('prod_7Kc4mNpQ')
```

```json
{
"id": "prod_7Kc4mNpQ",
"deleted": true
}
```

## List products

Returns a paginated list of products. Pass `active=true` to show only purchasable products.

`GET /v1/products`

```bash
curl "https://api.vinr.com/v1/products?active=true&limit=10" \
-H "X-Api-Key: $VINR_SECRET_KEY"
```

```js
import { Vinr } from '@vinr/sdk';

const vinr = new Vinr({ secretKey: process.env.VINR_SECRET_KEY });

const products = await vinr.products.list({ active: true, limit: 10 });
```

```python
import vinr

products = vinr.Product.list(active=True, limit=10)
```

```ruby
products = Vinr::Product.list(active: true, limit: 10)
```

```json
{
"object": "list",
"data": [
  {
    "id": "prod_7Kc4mNpQ",
    "name": "Pro Plan",
    "description": "Full access to all VINR features",
    "active": true,
    "images": [],
    "created": 1716300000
  }
],
"has_more": false
}
```

## Related events

`product.created`, `product.updated`, and `product.deleted`. See [Events](/docs/api-reference/events).
