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

# Manage Your Product Catalog in Synq

> Create, read, update, and delete products in Synq's PIM. Learn how to model your catalog with titles, descriptions, categories, and status fields.

The product is the core resource in Synq's Product Information Management (PIM) system. Every item you sell — whether a physical good, a digital download, or a bundle — lives as a product record scoped to your tenant. Each product carries a human-readable `title`, an optional `description`, a `category` label, and a lifecycle `status` (defaulting to `ACTIVE`). Products can have one or more [variants](/guides/variants) (e.g., sizes and colors), belong to a structured [category or brand](/guides/categories-brands), and carry rich [custom attributes](/guides/attributes) through product type templates.

<Note>
  Every request to the PIM API must include three headers:

  * `Authorization: Bearer <token>` — your API token
  * `X-Tenant-ID` — the UUID of the tenant you are operating on
  * `X-Org-ID` — the UUID of your organization

  Requests that omit these headers receive a `401 Unauthorized` response.
</Note>

## List products

Retrieve up to 100 of your most recently updated products for a tenant.

```bash theme={null}
GET /api/v1/pim/products
```

**Request**

```bash theme={null}
curl https://api.synq.com/api/v1/pim/products \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Tenant-ID: $TENANT_ID" \
  -H "X-Org-ID: $ORG_ID"
```

**Response** `200 OK`

```json theme={null}
[
  {
    "id": "018e7c3a-1f2b-7d4e-9a0c-3f5b6e7d8c90",
    "title": "Merino Wool Crew Neck Sweater",
    "category": "Knitwear",
    "status": "ACTIVE",
    "updated_at": "2024-11-15T10:32:00Z"
  },
  {
    "id": "018e7c3a-2a3b-4c5d-8e9f-0a1b2c3d4e5f",
    "title": "Classic Oxford Button-Down",
    "category": "Shirts",
    "status": "ACTIVE",
    "updated_at": "2024-11-14T08:10:00Z"
  }
]
```

<Tip>
  The list endpoint returns a lightweight projection (`id`, `title`, `category`, `status`, `updated_at`). Fetch a single product by ID to retrieve the full record including SEO fields, flags, and metadata.
</Tip>

***

## Create a product

Send a `POST` request with a JSON body to create a new product. The `title` field is required. The `description` and `category` fields are optional but recommended for catalog quality.

```bash theme={null}
POST /api/v1/pim/products
```

**Request body**

<ParamField body="title" type="string" required>
  The display name of the product shown to customers and operators.
</ParamField>

<ParamField body="description" type="string">
  A long-form description of the product.
</ParamField>

<ParamField body="category" type="string">
  A free-text category label. To use a structured category, associate the product with a `category_id` after creation.
</ParamField>

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.synq.com/api/v1/pim/products \
    -H "Authorization: Bearer $TOKEN" \
    -H "X-Tenant-ID: $TENANT_ID" \
    -H "X-Org-ID: $ORG_ID" \
    -H "Content-Type: application/json" \
    -d '{
      "title": "Merino Wool Crew Neck Sweater",
      "description": "Crafted from 100% Grade-A merino wool. Naturally temperature-regulating and machine washable.",
      "category": "Knitwear"
    }'
  ```

  ```json Request body theme={null}
  {
    "title": "Merino Wool Crew Neck Sweater",
    "description": "Crafted from 100% Grade-A merino wool. Naturally temperature-regulating and machine washable.",
    "category": "Knitwear"
  }
  ```
</CodeGroup>

**Response** `200 OK`

```json theme={null}
{
  "id": "018e7c3a-1f2b-7d4e-9a0c-3f5b6e7d8c90",
  "org_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "tenant_id": "f9e8d7c6-b5a4-3210-fedc-ba9876543210",
  "title": "Merino Wool Crew Neck Sweater",
  "description": "Crafted from 100% Grade-A merino wool. Naturally temperature-regulating and machine washable.",
  "status": "ACTIVE",
  "category": "Knitwear",
  "created_at": "2024-11-15T10:00:00Z",
  "updated_at": "2024-11-15T10:00:00Z"
}
```

<ResponseField name="id" type="string">
  System-generated UUID for the new product. Use this to fetch, update, or delete the product later.
</ResponseField>

<ResponseField name="status" type="string">
  Defaults to `ACTIVE` on creation. Other lifecycle values include `DRAFT` and `ARCHIVED`.
</ResponseField>

***

## Get a product by ID

Retrieve the full product record including all optional fields.

```bash theme={null}
GET /api/v1/pim/products/{id}
```

```bash theme={null}
curl https://api.synq.com/api/v1/pim/products/018e7c3a-1f2b-7d4e-9a0c-3f5b6e7d8c90 \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Tenant-ID: $TENANT_ID" \
  -H "X-Org-ID: $ORG_ID"
```

**Response** `200 OK`

```json theme={null}
{
  "id": "018e7c3a-1f2b-7d4e-9a0c-3f5b6e7d8c90",
  "org_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "tenant_id": "f9e8d7c6-b5a4-3210-fedc-ba9876543210",
  "title": "Merino Wool Crew Neck Sweater",
  "description": "Crafted from 100% Grade-A merino wool.",
  "short_description": "100% merino wool. Machine washable.",
  "status": "ACTIVE",
  "category": "Knitwear",
  "brand": "NordicThread",
  "is_taxable": true,
  "is_returnable": true,
  "seo_title": "Merino Wool Sweater – NordicThread",
  "seo_description": "Shop our bestselling merino wool crew neck.",
  "data_quality_score": 82,
  "created_at": "2024-11-15T10:00:00Z",
  "updated_at": "2024-11-15T10:00:00Z"
}
```

<Warning>
  If the product ID does not exist within your tenant's scope, the API returns `404 Not Found`. Products soft-deleted via `DELETE` are also excluded from `GET` responses.
</Warning>

***

## Update a product

Partially update a product's `title`, `description`, or `category`. Only fields you include in the request body are changed — omitted fields retain their current values.

```bash theme={null}
PUT /api/v1/pim/products/{id}
```

<CodeGroup>
  ```bash cURL theme={null}
  curl -X PUT https://api.synq.com/api/v1/pim/products/018e7c3a-1f2b-7d4e-9a0c-3f5b6e7d8c90 \
    -H "Authorization: Bearer $TOKEN" \
    -H "X-Tenant-ID: $TENANT_ID" \
    -H "X-Org-ID: $ORG_ID" \
    -H "Content-Type: application/json" \
    -d '{
      "title": "Merino Wool Crew Neck Sweater – 2025 Edition",
      "description": "Updated for 2025 with a relaxed fit and reinforced cuffs.",
      "category": "Knitwear"
    }'
  ```

  ```json Request body theme={null}
  {
    "title": "Merino Wool Crew Neck Sweater – 2025 Edition",
    "description": "Updated for 2025 with a relaxed fit and reinforced cuffs.",
    "category": "Knitwear"
  }
  ```
</CodeGroup>

The response returns the full updated product object, identical in shape to the `GET /products/{id}` response.

***

## Delete a product

Soft-delete a product. The record is retained with a timestamp and is excluded from all list and get operations.

```bash theme={null}
DELETE /api/v1/pim/products/{id}
```

```bash theme={null}
curl -X DELETE https://api.synq.com/api/v1/pim/products/018e7c3a-1f2b-7d4e-9a0c-3f5b6e7d8c90 \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Tenant-ID: $TENANT_ID" \
  -H "X-Org-ID: $ORG_ID"
```

**Response** `204 No Content`

A successful deletion returns an empty body with status `204`. If the product is not found or already deleted, the API returns `500` — verify the ID and tenant headers are correct.

***

## Dashboard stats

Retrieve a real-time snapshot of your catalog's health, including total product count, low-stock variants, out-of-stock variants, and total inventory value.

```bash theme={null}
GET /api/v1/pim/stats
```

```bash theme={null}
curl https://api.synq.com/api/v1/pim/stats \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Tenant-ID: $TENANT_ID" \
  -H "X-Org-ID: $ORG_ID"
```

**Response** `200 OK`

```json theme={null}
{
  "totalProducts": 1240,
  "lowStockVariants": 37,
  "outOfStockVariants": 12,
  "totalInventoryValue": 482500.00
}
```

<ResponseField name="totalProducts" type="integer">
  Count of active (non-deleted) products in the tenant.
</ResponseField>

<ResponseField name="lowStockVariants" type="integer">
  Number of variants with fewer than 20 units available.
</ResponseField>

<ResponseField name="outOfStockVariants" type="integer">
  Number of variants with zero available units.
</ResponseField>

<ResponseField name="totalInventoryValue" type="number">
  Sum of available quantity multiplied by cost price across all variants.
</ResponseField>
