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

# Bulk SKU Creation API

> Create multiple SKUs (Stock Keeping Units) in your inventory in a single request

## Overview

The Bulk SKU Creation API lets you add up to **100 SKUs** in a single request. Each SKU can have a name and an optional item code. The item code is especially useful for matching line items in purchase orders to your inventory catalog.

## Authentication

All requests require an API key in the request headers.

**Headers:**

```
Authorization: Api-Key YOUR_API_KEY
Content-Type: application/json
```

## Request

**Content-Type:** `application/json`

### Body Parameters

| Parameter | Type  | Required | Description                                                          |
| --------- | ----- | -------- | -------------------------------------------------------------------- |
| `skus`    | array | Yes      | List of SKUs to create. Minimum 1, maximum **100** items per request |

### SKU Object

Each item in the `skus` array must contain:

| Parameter  | Type   | Required | Description                                                        |
| ---------- | ------ | -------- | ------------------------------------------------------------------ |
| `name`     | string | Yes      | Display name of the SKU (1–128 characters)                         |
| `itemCode` | string | No       | Item code for the SKU (1–256 characters)                           |
| `unit`     | string | No       | Unit of measurement, e.g. `pcs`, `kg`, `litre` (max 32 characters) |
| `rate`     | number | No       | Default unit rate or price for the SKU                             |
| `hsnSac`   | string | No       | HSN or SAC code for GST classification (max 16 characters)         |

> **Tip:** `itemCode` is matched case-insensitively against purchase order line items — `SKU-001` and `sku-001` are treated as the same code.

## Code Examples

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.pazy.io/v1.0/inventory/skus/bulk \
    -H "Authorization: Api-Key YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "skus": [
        {
          "name": "Office Chair - Ergonomic",
          "itemCode": "FURN-001",
          "unit": "pcs",
          "rate": 5000.00,
          "hsnSac": "9401"
        },
        {
          "name": "Standing Desk",
          "itemCode": "FURN-002",
          "unit": "pcs",
          "rate": 15000.00
        },
        {
          "name": "Laptop Stand"
        }
      ]
    }'
  ```

  ```javascript JavaScript (Fetch API) theme={null}
  const response = await fetch('https://api.pazy.io/v1.0/inventory/skus/bulk', {
    method: 'POST',
    headers: {
      'Authorization': 'Api-Key YOUR_API_KEY',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      skus: [
        {
          name: 'Office Chair - Ergonomic',
          itemCode: 'FURN-001',
          unit: 'pcs',
          rate: 5000.00,
          hsnSac: '9401'
        },
        {
          name: 'Standing Desk',
          itemCode: 'FURN-002',
          unit: 'pcs',
          rate: 15000.00
        },
        {
          name: 'Laptop Stand'
        }
      ]
    })
  });

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

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

  url = "https://api.pazy.io/v1.0/inventory/skus/bulk"
  headers = {
      "Authorization": "Api-Key YOUR_API_KEY",
      "Content-Type": "application/json"
  }

  payload = {
      "skus": [
          {
              "name": "Office Chair - Ergonomic",
              "itemCode": "FURN-001",
              "unit": "pcs",
              "rate": 5000.00,
              "hsnSac": "9401"
          },
          {
              "name": "Standing Desk",
              "itemCode": "FURN-002",
              "unit": "pcs",
              "rate": 15000.00
          },
          {
              "name": "Laptop Stand"
          }
      ]
  }

  response = requests.post(url, headers=headers, json=payload)
  result = response.json()
  ```
</CodeGroup>

## Success Response

**HTTP Status:** `200 OK`

### Response Fields

| Field               | Type    | Description                                                      |
| ------------------- | ------- | ---------------------------------------------------------------- |
| `ok`                | boolean | `true` when the request was processed (even if some SKUs failed) |
| `data`              | object  | Summary of the bulk operation                                    |
| `data.total`        | number  | Total number of SKUs submitted                                   |
| `data.successCount` | number  | Number of SKUs successfully created                              |
| `data.failureCount` | number  | Number of SKUs that failed to create                             |
| `data.created`      | array   | List of successfully created SKUs                                |
| `data.failed`       | array   | List of SKUs that failed to create                               |

### Created SKU Object

| Field      | Type           | Description                                   |
| ---------- | -------------- | --------------------------------------------- |
| `name`     | string         | Display name of the SKU                       |
| `itemCode` | string \| null | Item code of the SKU (`null` if not provided) |
| `unit`     | string \| null | Unit of measurement (`null` if not provided)  |
| `rate`     | number \| null | Default unit rate (`null` if not provided)    |
| `hsnSac`   | string \| null | HSN/SAC code (`null` if not provided)         |

### Failed SKU Object

| Field      | Type           | Description                      |
| ---------- | -------------- | -------------------------------- |
| `name`     | string         | Name of the SKU that failed      |
| `itemCode` | string \| null | Item code of the SKU that failed |
| `error`    | string         | Reason for failure               |

### Response Example

```json theme={null}
{
  "ok": true,
  "data": {
    "total": 3,
    "successCount": 3,
    "failureCount": 0,
    "created": [
      {
        "name": "Office Chair - Ergonomic",
        "itemCode": "FURN-001",
        "unit": "pcs",
        "rate": 5000,
        "hsnSac": "9401"
      },
      {
        "name": "Standing Desk",
        "itemCode": "FURN-002",
        "unit": "pcs",
        "rate": 15000,
        "hsnSac": null
      },
      {
        "name": "Laptop Stand",
        "itemCode": null,
        "unit": null,
        "rate": null,
        "hsnSac": null
      }
    ],
    "failed": []
  }
}
```

### Partial Success Response

If some SKUs fail (e.g., due to a database constraint), the API still returns `200 OK` and reports which succeeded and which failed:

```json theme={null}
{
  "ok": true,
  "data": {
    "total": 2,
    "successCount": 1,
    "failureCount": 1,
    "created": [
      {
        "name": "Monitor Stand",
        "itemCode": "DESK-001",
        "unit": null,
        "rate": null,
        "hsnSac": null
      }
    ],
    "failed": [
      {
        "name": "Invalid SKU",
        "itemCode": null,
        "error": "Failed to create SKU"
      }
    ]
  }
}
```

## Error Responses

### Missing Required Fields

**HTTP Status:** `400 Bad Request`

```json theme={null}
{
  "ok": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Validation failed: /body/skus: must NOT have fewer than 1 items"
  }
}
```

### Exceeding Maximum Batch Size

**HTTP Status:** `400 Bad Request`

```json theme={null}
{
  "ok": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Validation failed: /body/skus: must NOT have more than 100 items"
  }
}
```

### SKU Name Too Long

**HTTP Status:** `400 Bad Request`

```json theme={null}
{
  "ok": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Validation failed: /body/skus/0/name: must NOT have more than 128 characters"
  }
}
```

### Authentication Errors

**HTTP Status:** `401 Unauthorized`

```json theme={null}
{
  "ok": false,
  "error": {
    "code": "MISSING_CREDENTIALS",
    "message": "Missing Credentials"
  }
}
```

```json theme={null}
{
  "ok": false,
  "error": {
    "code": "INVALID_API_KEY",
    "message": "Invalid API Key"
  }
}
```

### Permission Errors

**HTTP Status:** `403 Forbidden`

```json theme={null}
{
  "ok": false,
  "error": {
    "code": "INSUFFICIENT_PERMISSIONS",
    "message": "Permission check failed - PERMISSION_CHECK_FAILED"
  }
}
```

## Linking SKUs to Purchase Order Line Items

Once you have created SKUs in your inventory, you can link purchase order line items to them by supplying `skuName` or `skuCode` on each line item when [creating](/apis/po-creation) or [updating](/apis/po-update) a purchase order.

### Matching priority

When both fields are provided, **`skuCode` takes priority** over `skuName`. If the `skuCode` match fails, the system does **not** fall back to `skuName` for the same item — a separate warning is returned.

### Matching rules

| Field     | Match strategy                |
| --------- | ----------------------------- |
| `skuCode` | Exact match, case-insensitive |
| `skuName` | Exact match, case-insensitive |

### Purchase order line item with SKU linking

```json theme={null}
{
  "lineItems": [
    {
      "identifier": "Ergonomic Chair x10",
      "quantity": 10,
      "rate": 5000.00,
      "skuCode": "FURN-001"
    },
    {
      "identifier": "Standing Desk x2",
      "quantity": 2,
      "rate": 15000.00,
      "skuName": "Standing Desk"
    }
  ]
}
```

### When a SKU cannot be matched

If a SKU cannot be found, the purchase order is **still created** and the response includes a `skuMatchWarnings` array describing which line items could not be linked:

```json theme={null}
{
  "ok": true,
  "data": {
    "poId": "po_abc123",
    "skuMatchWarnings": [
      {
        "lineItemIdentifier": "Unknown Item",
        "skuCode": "UNKNOWN-999",
        "message": "SKU with item code \"UNKNOWN-999\" not found in your inventory"
      }
    ]
  }
}
```

> A missing SKU match is a **warning, not an error** — the purchase order is created successfully regardless.

## Best Practices

* Use a consistent, human-readable `itemCode` scheme (e.g., `CATEGORY-NUMBER`) so that external systems can reliably match line items
* Send SKUs in bulk before creating purchase orders to ensure all line items can be matched
* Keep SKU names unique within your organisation to avoid ambiguity when matching by `skuName`
* SKU `name` is limited to **128 characters** — ensure your names stay within this limit
* Always prefer `skuCode` over `skuName` for matching — codes are more stable than display names
* Populate `hsnSac` for items subject to GST to ensure correct tax classification downstream
* Handle `skuMatchWarnings` in your integration to detect and remediate unmatched line items
