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

# Item API

> Create bulk optical items and retrieve item listings with pagination, sorting, and filtering capabilities

# Item API

The Item API allows you to create optical items in bulk and retrieve paginated item listings. The bulk creation endpoint generates multiple item variants based on SPH (sphere) and CYL (cylinder) value ranges, creating all possible combinations. The listing endpoint provides flexible pagination, sorting, and filtering options.

## Endpoint Details

**Base URL:** `https://joptic.jethings.com`

### Required Headers

```
x-store-id: <store_id>
Authorization: Bearer <token>
```

***

## Create Bulk Items

### Endpoint

**Endpoint:** `POST /items/bulk`\
**Content-Type:** `application/json`

### Request Structure

The request body contains an array of item configurations. Each item configuration will generate multiple items based on SPH and CYL value ranges. The system creates all combinations of SPH and CYL values within the specified ranges.

### Request Body

```json theme={null}
{
  "items": [
    {
      "indice": "1.5",
      "treatment": "Anti-Reflective",
      "color": "Clear",
      "sph": {
        "sph_start": "-2.00",
        "sph_end": "2.00",
        "sign_symbol": "+",
        "jumpBy": "0.25"
      },
      "cly": {
        "cly_start": "0.00",
        "cly_end": "-2.00",
        "sign_symbol": "-",
        "jumpBy": "0.25"
      }
    }
  ]
}
```

### Request Body Fields

| Field   | Type  | Required | Description                            |
| ------- | ----- | -------- | -------------------------------------- |
| `items` | array | ✅ Yes    | Array of item configurations to create |

#### ItemsDto Object

| Field       | Type   | Required | Description                                                 |
| ----------- | ------ | -------- | ----------------------------------------------------------- |
| `indice`    | number | ✅ Yes    | Index/refractive index value (e.g., "1.5", "1.6")           |
| `treatment` | string | ✅ Yes    | Lens treatment type (e.g., "Anti-Reflective", "Blue Light") |
| `color`     | string | ✅ Yes    | Lens color (e.g., "Clear", "Brown", "Gray")                 |
| `sph`       | object | ✅ Yes    | Sphere value range configuration                            |
| `cly`       | object | ✅ Yes    | Cylinder value range configuration                          |

#### SPH Object

| Field         | Type   | Required | Description                                       |
| ------------- | ------ | -------- | ------------------------------------------------- |
| `sph_start`   | string | ✅ Yes    | Starting SPH value (e.g., "-2.00")                |
| `sph_end`     | string | ✅ Yes    | Ending SPH value (e.g., "2.00")                   |
| `sign_symbol` | string | ✅ Yes    | Sign symbol: "+" or "-"                           |
| `jumpBy`      | string | ✅ Yes    | Increment value between SPH values (e.g., "0.25") |

#### CYL Object

| Field         | Type   | Required | Description                                       |
| ------------- | ------ | -------- | ------------------------------------------------- |
| `cly_start`   | string | ✅ Yes    | Starting CYL value (e.g., "0.00")                 |
| `cly_end`     | string | ✅ Yes    | Ending CYL value (e.g., "-2.00")                  |
| `sign_symbol` | string | ✅ Yes    | Sign symbol: "+" or "-"                           |
| `jumpBy`      | string | ✅ Yes    | Increment value between CYL values (e.g., "0.25") |

<Note>
  The system generates all combinations of SPH and CYL values within the specified ranges. For example, if SPH ranges from -2.00 to 2.00 with 0.25 increments, and CYL ranges from 0.00 to -2.00 with 0.25 increments, it will create multiple items (one for each combination).
</Note>

***

## Create Bulk Items Examples

### Example 1: Create Single Item Configuration

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://joptic.jethings.com/items/bulk \
    -H "x-store-id: your-store-id" \
    -H "Authorization: Bearer <token>" \
    -H "Content-Type: application/json" \
    -d '{
      "items": [
        {
          "indice": 1.5,
          "treatment": "Anti-Reflective",
          "color": "Clear",
          "sph": {
            "sph_start": "-2.00",
            "sph_end": "2.00",
            "sign_symbol": "+",
            "jumpBy": "0.25"
          },
          "cly": {
            "cly_start": "0.00",
            "cly_end": "-2.00",
            "sign_symbol": "-",
            "jumpBy": "0.25"
          }
        }
      ]
    }'
  ```

  ```javascript JavaScript theme={null}
  const itemData = {
    items: [
      {
        indice: 1.5,
        treatment: "Anti-Reflective",
        color: "Clear",
        sph: {
          sph_start: "-2.00",
          sph_end: "2.00",
          sign_symbol: "+",
          jumpBy: "0.25",
        },
        cly: {
          cly_start: "0.00",
          cly_end: "-2.00",
          sign_symbol: "-",
          jumpBy: "0.25",
        },
      },
    ],
  }

  const response = await fetch("https://joptic.jethings.com/items/bulk", {
    method: "POST",
    headers: {
      "x-store-id": "your-store-id",
      Authorization: "Bearer <token>",
      "Content-Type": "application/json",
    },
    body: JSON.stringify(itemData),
  })

  const result = await response.json()
  ```

  ```python Python theme={null}
  import requests

  url = "https://joptic.jethings.com/items/bulk"

  item_data = {
      "items": [
          {
              "indice": 1.5,
              "treatment": "Anti-Reflective",
              "color": "Clear",
              "sph": {
                  "sph_start": "-2.00",
                  "sph_end": "2.00",
                  "sign_symbol": "+",
                  "jumpBy": "0.25"
              },
              "cly": {
                  "cly_start": "0.00",
                  "cly_end": "-2.00",
                  "sign_symbol": "-",
                  "jumpBy": "0.25"
              }
          }
      ]
  }

  response = requests.post(
      url,
      headers={
          "x-store-id": "your-store-id",
          "Authorization": "Bearer <token>",
          "Content-Type": "application/json"
      },
      json=item_data
  )

  print(response.json())
  ```
</CodeGroup>

**Success Response:**

```json theme={null}
{
  "totalBatches": 1,
  "totalItemsCreated": 225,
  "batches": [
    {
      "totalCreated": 225,
      "items": [
        {
          "product": {
            "id": "550e8400-e29b-41d4-a716-446655440000",
            "storeId": "store-uuid",
            "title": "1.5 Anti-Reflective Clear + 2.00 - 0.00",
            "isActive": true,
            "productTypeId": "lens-type-uuid",
            "createdAt": "2024-01-15T10:00:00.000Z",
            "updatedAt": "2024-01-15T10:00:00.000Z"
          },
          "item": {
            "id": "item-uuid-1",
            "name": "1.5 Anti-Reflective Clear + 2.00 - 0.00",
            "productId": "550e8400-e29b-41d4-a716-446655440000",
            "isActive": true,
            "createdAt": "2024-01-15T10:00:00.000Z",
            "updatedAt": "2024-01-15T10:00:00.000Z"
          },
          "itemVariant": {
            "id": "variant-uuid-1",
            "itemId": "item-uuid-1",
            "name": "1.5 Anti-Reflective Clear + 2.00 - 0.00",
            "isActive": true,
            "createdAt": "2024-01-15T10:00:00.000Z",
            "updatedAt": "2024-01-15T10:00:00.000Z"
          }
        }
      ]
    }
  ]
}
```

***

### Example 2: Create Multiple Item Configurations

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://joptic.jethings.com/items/bulk \
    -H "x-store-id: your-store-id" \
    -H "Authorization: Bearer <token>" \
    -H "Content-Type: application/json" \
    -d '{
      "items": [
        {
          "indice": 1.5,
          "treatment": "Anti-Reflective",
          "color": "Clear",
          "sph": {
            "sph_start": "-1.00",
            "sph_end": "1.00",
            "sign_symbol": "+",
            "jumpBy": "0.25"
          },
          "cly": {
            "cly_start": "0.00",
            "cly_end": "-1.00",
            "sign_symbol": "-",
            "jumpBy": "0.25"
          }
        },
        {
          "indice": 1.6,
          "treatment": "Blue Light",
          "color": "Brown",
          "sph": {
            "sph_start": "-0.50",
            "sph_end": "0.50",
            "sign_symbol": "+",
            "jumpBy": "0.25"
          },
          "cly": {
            "cly_start": "0.00",
            "cly_end": "-0.50",
            "sign_symbol": "-",
            "jumpBy": "0.25"
          }
        }
      ]
    }'
  ```

  ```javascript JavaScript theme={null}
  const itemData = {
    items: [
      {
        indice: 1.5,
        treatment: "Anti-Reflective",
        color: "Clear",
        sph: {
          sph_start: "-1.00",
          sph_end: "1.00",
          sign_symbol: "+",
          jumpBy: "0.25",
        },
        cly: {
          cly_start: "0.00",
          cly_end: "-1.00",
          sign_symbol: "-",
          jumpBy: "0.25",
        },
      },
      {
        indice: 1.6,
        treatment: "Blue Light",
        color: "Brown",
        sph: {
          sph_start: "-0.50",
          sph_end: "0.50",
          sign_symbol: "+",
          jumpBy: "0.25",
        },
        cly: {
          cly_start: "0.00",
          cly_end: "-0.50",
          sign_symbol: "-",
          jumpBy: "0.25",
        },
      },
    ],
  }

  const response = await fetch("https://joptic.jethings.com/items/bulk", {
    method: "POST",
    headers: {
      "x-store-id": "your-store-id",
      Authorization: "Bearer <token>",
      "Content-Type": "application/json",
    },
    body: JSON.stringify(itemData),
  })

  const result = await response.json()
  ```

  ```python Python theme={null}
  import requests

  url = "https://joptic.jethings.com/items/bulk"

  item_data = {
      "items": [
          {
              "indice": 1.5,
              "treatment": "Anti-Reflective",
              "color": "Clear",
              "sph": {
                  "sph_start": "-1.00",
                  "sph_end": "1.00",
                  "sign_symbol": "+",
                  "jumpBy": "0.25"
              },
              "cly": {
                  "cly_start": "0.00",
                  "cly_end": "-1.00",
                  "sign_symbol": "-",
                  "jumpBy": "0.25"
              }
          },
          {
              "indice": 1.6,
              "treatment": "Blue Light",
              "color": "Brown",
              "sph": {
                  "sph_start": "-0.50",
                  "sph_end": "0.50",
                  "sign_symbol": "+",
                  "jumpBy": "0.25"
              },
              "cly": {
                  "cly_start": "0.00",
                  "cly_end": "-0.50",
                  "sign_symbol": "-",
                  "jumpBy": "0.25"
              }
          }
      ]
  }

  response = requests.post(
      url,
      headers={
          "x-store-id": "your-store-id",
          "Authorization": "Bearer <token>",
          "Content-Type": "application/json"
      },
      json=item_data
  )

  print(response.json())
  ```
</CodeGroup>

**Success Response:**

```json theme={null}
{
  "totalBatches": 2,
  "totalItemsCreated": 450,
  "batches": [
    {
      "totalCreated": 225,
      "items": [...]
    },
    {
      "totalCreated": 225,
      "items": [...]
    }
  ]
}
```

***

## Get All Items

### Endpoint

**Endpoint:** `GET /items`

### Query Parameters

| Parameter   | Type   | Required | Default   | Description                                     |
| ----------- | ------ | -------- | --------- | ----------------------------------------------- |
| `page`      | number | No       | 1         | Page number for pagination                      |
| `limit`     | number | No       | 10        | Number of records per page (max 100)            |
| `sortBy`    | string | No       | createdAt | Sort field: "createdAt", "updatedAt", or "name" |
| `sortOrder` | string | No       | desc      | Sort order: "asc" or "desc"                     |

<Note>
  The `storeId` is automatically extracted from the `x-store-id` header and does not need to be provided as a query parameter.
</Note>

### Sort Options

The `sortBy` parameter accepts the following values:

* `"createdAt"` - Sort by creation date (default)
* `"updatedAt"` - Sort by last update date
* `"name"` - Sort by item name alphabetically

***

## Get Items Examples

### Example 1: Get All Items (Default Pagination)

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET "https://joptic.jethings.com/items" \
    -H "x-store-id: your-store-id" \
    -H "Authorization: Bearer <token>"
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch("https://joptic.jethings.com/items", {
    method: "GET",
    headers: {
      "x-store-id": "your-store-id",
      Authorization: "Bearer <token>",
    },
  })

  const result = await response.json()
  ```

  ```python Python theme={null}
  import requests

  url = "https://joptic.jethings.com/items"

  response = requests.get(
      url,
      headers={
          "x-store-id": "your-store-id",
          "Authorization": "Bearer <token>"
      }
  )

  print(response.json())
  ```
</CodeGroup>

**Success Response:**

```json theme={null}
{
  "data": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "itemName": "1.5 Anti-Reflective Clear + 2.00 - 0.00",
      "diameter": 0,
      "brand": "Acme Optics",
      "status": "active",
      "createdAt": "2024-01-15T10:00:00.000Z",
      "updatedAt": "2024-01-15T10:00:00.000Z"
    },
    {
      "id": "660e8400-e29b-41d4-a716-446655440001",
      "itemName": "1.5 Anti-Reflective Clear + 1.75 - 0.25",
      "diameter": 0,
      "brand": null,
      "status": "active",
      "createdAt": "2024-01-15T09:30:00.000Z",
      "updatedAt": "2024-01-15T09:30:00.000Z"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 10,
    "total": 225,
    "totalPages": 23,
    "hasNext": true,
    "hasPrev": false
  }
}
```

***

### Example 2: Get Items with Custom Pagination and Sorting

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET "https://joptic.jethings.com/items?page=2&limit=20&sortBy=name&sortOrder=asc" \
    -H "x-store-id: your-store-id" \
    -H "Authorization: Bearer <token>"
  ```

  ```javascript JavaScript theme={null}
  const params = new URLSearchParams({
    page: "2",
    limit: "20",
    sortBy: "name",
    sortOrder: "asc",
  })

  const response = await fetch(`https://joptic.jethings.com/items?${params}`, {
    method: "GET",
    headers: {
      "x-store-id": "your-store-id",
      Authorization: "Bearer <token>",
    },
  })

  const result = await response.json()
  ```

  ```python Python theme={null}
  import requests

  url = "https://joptic.jethings.com/items"

  params = {
      "page": 2,
      "limit": 20,
      "sortBy": "name",
      "sortOrder": "asc"
  }

  response = requests.get(
      url,
      headers={
          "x-store-id": "your-store-id",
          "Authorization": "Bearer <token>"
      },
      params=params
  )

  print(response.json())
  ```
</CodeGroup>

***

### Example 3: Get Items Sorted by Update Date

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET "https://joptic.jethings.com/items?sortBy=updatedAt&sortOrder=desc&limit=50" \
    -H "x-store-id: your-store-id" \
    -H "Authorization: Bearer <token>"
  ```

  ```javascript JavaScript theme={null}
  const params = new URLSearchParams({
    sortBy: "updatedAt",
    sortOrder: "desc",
    limit: "50",
  })

  const response = await fetch(`https://joptic.jethings.com/items?${params}`, {
    method: "GET",
    headers: {
      "x-store-id": "your-store-id",
      Authorization: "Bearer <token>",
    },
  })

  const result = await response.json()
  ```

  ```python Python theme={null}
  import requests

  url = "https://joptic.jethings.com/items"

  params = {
      "sortBy": "updatedAt",
      "sortOrder": "desc",
      "limit": 50
  }

  response = requests.get(
      url,
      headers={
          "x-store-id": "your-store-id",
          "Authorization": "Bearer <token>"
      },
      params=params
  )

  print(response.json())
  ```
</CodeGroup>

***

## Response Structures

### Create Bulk Items Response

```json theme={null}
{
  "totalBatches": "number",
  "totalItemsCreated": "number",
  "batches": [
    {
      "totalCreated": "number",
      "items": [
        {
          "product": {
            "id": "string (UUID)",
            "storeId": "string (UUID)",
            "title": "string",
            "isActive": "boolean",
            "productTypeId": "string (UUID)",
            "createdAt": "ISO date string",
            "updatedAt": "ISO date string"
          },
          "item": {
            "id": "string (UUID)",
            "name": "string",
            "productId": "string (UUID)",
            "isActive": "boolean",
            "createdAt": "ISO date string",
            "updatedAt": "ISO date string"
          },
          "itemVariant": {
            "id": "string (UUID)",
            "itemId": "string (UUID)",
            "name": "string",
            "isActive": "boolean",
            "createdAt": "ISO date string",
            "updatedAt": "ISO date string"
          }
        }
      ]
    }
  ]
}
```

### Get Items Response

```json theme={null}
{
  "data": [
    {
      "id": "string (UUID)",
      "itemName": "string",
      "diameter": "number",
      "brand": "string | null",
      "status": "active | unactive",
      "createdAt": "ISO date string",
      "updatedAt": "ISO date string"
    }
  ],
  "pagination": {
    "page": "number",
    "limit": "number",
    "total": "number",
    "totalPages": "number",
    "hasNext": "boolean",
    "hasPrev": "boolean"
  }
}
```

***

## Error Responses

### 400 Bad Request

```json theme={null}
{
  "statusCode": 400,
  "message": "items must be an array",
  "error": "Bad Request"
}
```

Or for validation errors:

```json theme={null}
{
  "statusCode": 400,
  "message": ["sph.sign_symbol must be one of the following values: +, -"],
  "error": "Bad Request"
}
```

### 403 Forbidden

```json theme={null}
{
  "statusCode": 403,
  "message": "You do not have access to this store",
  "error": "Forbidden"
}
```

### 404 Not Found

```json theme={null}
{
  "statusCode": 404,
  "message": "Product type with code 'LENS' not found",
  "error": "Not Found"
}
```

### 500 Internal Server Error

```json theme={null}
{
  "statusCode": 500,
  "message": "Failed to create items",
  "error": "Internal Server Error"
}
```

***

## Important Notes

### Bulk Item Creation

<AccordionGroup>
  <Accordion title="Value Range Generation">
    * The system generates all combinations of SPH and CYL values within specified ranges
    * Values are incremented by the `jumpBy` parameter
    * Both SPH and CYL ranges are inclusive (start and end values are included)
    * Values are rounded to 2 decimal places to avoid floating-point precision issues
  </Accordion>

  <Accordion title="Item Naming">
    * Each item is named using the format: `{indice} {treatment} {color} {sph.sign} {sph.value} {cly.sign} {cly.value}`
    * Example: "1.5 Anti-Reflective Clear + 2.00 - 0.00"
    * The same name format is used for product title, item name, and item variant name
  </Accordion>

  <Accordion title="Product Type">
    * All items are created with the product type code "LENS"
    * The system automatically fetches the LENS product type from the database
    * If the LENS product type doesn't exist, a 404 error is returned
  </Accordion>

  <Accordion title="Variant Structure">
    * Each item creates variants for: SPH, CYL, color, indice, and treatment
    * Variant values are stored separately for each property
    * This structure allows for flexible filtering and searching
  </Accordion>
</AccordionGroup>

### Item Listing

<CardGroup cols={2}>
  <Card title="Pagination Limits" icon="list">
    Maximum 100 items per page

    <br />

    <code>limit: 1-100</code>
  </Card>

  <Card title="Soft Delete" icon="trash">
    Deleted items are excluded

    <br />

    <code>deletedAt IS NULL</code>
  </Card>
</CardGroup>

### Pagination

<Tabs>
  <Tab title="Default Behavior">
    ```javascript theme={null}
    {
      page: 1,
      limit: 10,
      sortBy: "createdAt",
      sortOrder: "desc"
    }
    ```

    Returns 10 most recent items by default
  </Tab>

  <Tab title="Custom Pagination">
    ```javascript theme={null}
    {
      page: 2,
      limit: 50,
      sortBy: "name",
      sortOrder: "asc"
    }
    ```

    Customize page size and sorting
  </Tab>
</Tabs>

### Sorting Options

The API supports sorting by:

* **Created At** (`sortBy=createdAt`) - Creation timestamp (default)
* **Updated At** (`sortBy=updatedAt`) - Last update timestamp
* **Name** (`sortBy=name`) - Alphabetical sorting by item name

Both ascending (`asc`) and descending (`desc`) orders are supported.

### Pagination Metadata

The pagination object includes:

* `page` - Current page number
* `limit` - Number of items per page
* `total` - Total number of items matching the query
* `totalPages` - Total number of pages
* `hasNext` - Boolean indicating if there's a next page
* `hasPrev` - Boolean indicating if there's a previous page

### Item Status

* Items are created with `isActive: true` by default
* Status is returned as "active" or "unactive" in the response
* Only non-deleted items are returned in GET requests

***

## Summary

<Steps>
  <Step title="Authenticate">Obtain JWT token and ensure store access</Step>

  <Step title="Create Bulk Items">
    POST request with item configurations to create multiple items with SPH/CYL combinations
  </Step>

  <Step title="Retrieve Items">
    GET request with optional pagination, sorting, and filtering parameters
  </Step>

  <Step title="Handle Response">
    Process item data, batch information, or pagination metadata
  </Step>
</Steps>

This API provides comprehensive item management for optical stores, including bulk creation of lens items with automatic SPH/CYL combination generation, flexible querying with pagination and sorting, and efficient item retrieval.

***

<CardGroup cols={2}>
  <Card title="Brand API" icon="tag" href="/j-optic/brand-api">
    Create and manage optical brands
  </Card>

  <Card title="Customer API" icon="users" href="/j-optic/customer-api">
    Create and manage optical customers
  </Card>
</CardGroup>
