# Creates an item.

`POST /inventory/items`

Group: Inventory › Items · Operation ID: `createItem`

Creates an item.

Five fields are required: itemCode, itemTypeId, categoryId, inventoryUnitId and unitGroupId. The rest have defaults.

itemCode and itemTypeId cannot be changed after the item is created.

Set a weight if the item will ever meet a landed cost. The Weight and Volume allocation modes fail rather than falling back when an item on the receipt has no measurement. POST inventory/items/search with missingWeight finds the items already in that state.

A valuation method must match its tracking: 'batch' requires isBatch and 'serials' requires isSerial. Every unit named on the item must belong to unitGroupId.

[Open in the interactive reference](https://docs.api.lensing.ai/?op=createItem)

## Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `Api-Version` | header | `"v1"` | yes | The API version this request targets, named by its public identifier. Required on every request; omitting it, or naming a version this company does not have, is answered with 400. This document describes version `v1`. |
| `Idempotency-Key` | header | string | no | An opaque caller-chosen string (1-255 characters) that makes this request safe to retry. Repeating the same key with an identical request body replays the original response instead of re-executing - but only once that original request succeeded; a failed attempt re-executes on retry. Repeating the key with a different body is answered with 422. A key still in flight is answered with 409 - as is a key whose original request was interrupted before it finished, for a few minutes afterwards, until that attempt is presumed dead. A completed response stays replayable for 24 hours. The key is scoped to the caller, not to the action: reusing it for a different action is answered with 409 or 422 rather than treated independently. On read actions this header is ignored. On write actions that cannot offer the guarantee it is answered with `400 IDEMPOTENCY_NOT_SUPPORTED` rather than silently ignored. |

## Request body

Required, `application/json`: createItemInput.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `itemCode` | string | yes | The item code, for example 'WIDGET-01'. Must be unique within the tenant, including against retired items whose codes are never released. It cannot be changed after the item is created. |
| `itemName` | string | no | The display name of the item. |
| `itemTypeId` | string | yes | The unique identifier of the item's type. It cannot be changed after the item is created. See id on GET inventory/item-types/:id. |
| `categoryId` | string | yes | The unique identifier of the item's category. See id on GET inventory/item-categories/:id. |
| `inventoryUnitId` | string | yes | The unique identifier of the unit stock is counted in. Every quantity on an inventory level or transaction will be in this unit. It must be one of the units in unitGroupId. See id on GET inventory/unit-of-measures/:id. |
| `unitGroupId` | string | yes | The unique identifier of the unit of measure group that has the conversions between the item's units. inventoryUnitId, salesUnitId and purchaseUnitId must all be units in this group, and a unit outside it fails with UNIT_NOT_IN_UNIT_GROUP. See id on GET inventory/unit-of-measure-groups/:id. |
| `salesUnitId` | string | no | The unique identifier of the unit used on sales documents. Omit when it is the same as the inventory unit. It must be one of the units in unitGroupId. See id on GET inventory/unit-of-measures/:id. |
| `purchaseUnitId` | string | no | The unique identifier of the unit used on purchase documents. Omit when it is the same as the inventory unit. It must be one of the units in unitGroupId. See id on GET inventory/unit-of-measures/:id. |
| `valuationMethod` | string | no | How the item's stock is valued. Accepted values: 'movingAverage', 'batch', 'serials', 'none'. Use 'none' for an item that is not stocked. Defaults to 'movingAverage'. 'batch' requires isBatch, 'serials' requires isSerial, and 'none' requires isInventory false, and each contradiction fails with TRACKING_MISMATCH. 'fifo' is under development and fails with VALUATION_METHOD_UNAVAILABLE. |
| `isBatch` | boolean | no | Whether the item is tracked by batch. Defaults to false. |
| `isSerial` | boolean | no | Whether the item is tracked by serial number. Defaults to false. |
| `isInventory` | boolean | no | Whether stock levels are kept for the item. Defaults to true. Set false for a service or charge item. |
| `isSalesItem` | boolean | no | Whether the item can appear on sales documents. Defaults to true. |
| `isPurchaseItem` | boolean | no | Whether the item can appear on purchase documents. Defaults to true. |
| `active` | boolean | no | Whether the item can be selected on new documents. Defaults to true. Setting it false retires the item without deleting it. |
| `notes` | string | no | Free text on the item. |
| `externalItemId` | string | no | Your own identifier for this item in an external system. |
| `brandName` | string | no | The display name of the brand. |
| `imageAvatar` | string | no | The URL of the item's avatar image. |
| `eccnNumber` | string | no | The Export Control Classification Number. |
| `htsCode` | string | no | The Harmonized Tariff Schedule code. |
| `countryOfOrigin` | string | no | The country the item originates from. |
| `minStockLevel` | string (decimal) | no | The stock level below which the item should be reordered, in the inventory unit. |
| `minimumTransactionQuantity` | string (decimal) | no | The smallest quantity any document can move. Omit for no restriction. Omitting it is not the same as sending 1. |
| `leadTime` | string (decimal) | no | The number of days between ordering the item and receiving it. |
| `standardCost` | string (decimal) | no | The standard cost carried for planning. State its currency in currency. |
| `itemPurchasePrice` | string (decimal) | no | The expected purchase price. State its currency in currency. |
| `currency` | string | no | The currency of standardCost and itemPurchasePrice. Required when either is given. Format ISO 4217, for example 'USD'. |
| `weight` | string (decimal) | no | The weight of one item, in weightUnit. Set it if the item may be received under a landed cost that uses Weight allocation, because that mode fails rather than falling back when an item has no weight. |
| `weightUnit` | string | no | The unit weight is expressed in. Accepted values: 'G', 'Kg', 'Lbs'. |
| `grossWeight` | string (decimal) | no | The weight including packaging, in weightUnit. |
| `netWeight` | string (decimal) | no | The weight excluding packaging, in weightUnit. |
| `length` | string (decimal) | no | The length of one item. A landed cost Volume allocation needs length, width and height together, and fails when the set is incomplete. |
| `width` | string (decimal) | no | The width of one item. |
| `height` | string (decimal) | no | The height of one item. |
| `volumePerUnit` | string (decimal) | no | The volume of one item, in volumeUnit. |
| `volumeUnit` | string | no | The unit volumePerUnit is expressed in. Accepted values: 'L'. |
| `defaultAllocationMode` | string | no | The allocation mode a landed cost charge billed as this item falls back to when it names none. Accepted values: 'Equal', 'Quantity', 'LineTotal', 'Weight', 'Volume'. |
| `isPerishable` | boolean | no | Whether the item expires. |
| `shelfLifeDays` | number | no | The number of days the item keeps from production. |
| `minShelfLifeDaysOnReceipt` | number | no | The least remaining shelf life a receipt of this item will accept. |
| `minShelfLifeDaysOnDispatch` | number | no | The least remaining shelf life a dispatch of this item will accept. |
| `bestBeforeOffsetDays` | number | no | The number of days between the expiry date and the best-before date printed on it. |
| `storageTempMin` | string (decimal) | no | The lowest storage temperature, in degrees Celsius. |
| `storageTempMax` | string (decimal) | no | The highest storage temperature, in degrees Celsius. |

Example:

```json
{
  "itemCode": "WIDGET-01",
  "itemName": "Standard widget",
  "itemTypeId": "66aea173-07b8-4c4e-bc4a-5c35dedfdc16",
  "categoryId": "6709e2bf-d6cf-4800-9ffa-d5a496ec4d0b",
  "inventoryUnitId": "77bd4c16-e1f0-426d-a98f-07b063df2d9c",
  "unitGroupId": "38b5454a-c3fe-452b-9754-61f9ead49e87",
  "salesUnitId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "purchaseUnitId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "valuationMethod": "movingAverage",
  "isBatch": true,
  "isSerial": true,
  "isInventory": true,
  "isSalesItem": true,
  "isPurchaseItem": true,
  "active": true,
  "notes": "<notes>",
  "externalItemId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "brandName": "<brandName>",
  "imageAvatar": "<imageAvatar>",
  "eccnNumber": "<eccnNumber>",
  "htsCode": "<htsCode>",
  "countryOfOrigin": "<countryOfOrigin>",
  "minStockLevel": "19.99",
  "minimumTransactionQuantity": "19.99",
  "leadTime": "19.99",
  "standardCost": "19.99",
  "itemPurchasePrice": "19.99",
  "currency": "<currency>",
  "weight": "1.4",
  "weightUnit": "Kg",
  "grossWeight": "19.99",
  "netWeight": "19.99",
  "length": "19.99",
  "width": "19.99",
  "height": "19.99",
  "volumePerUnit": "19.99",
  "volumeUnit": "<volumeUnit>",
  "defaultAllocationMode": "<defaultAllocationMode>",
  "isPerishable": true,
  "shelfLifeDays": 0,
  "minShelfLifeDaysOnReceipt": 0,
  "minShelfLifeDaysOnDispatch": 0,
  "bestBeforeOffsetDays": 0,
  "storageTempMin": "19.99",
  "storageTempMax": "19.99"
}
```

## Response

`200` Success

Under `data` (createItemOutput):

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | yes | The unique identifier for the created item. |
| `itemCode` | string | no | The item code of the created item. |

## Response headers

- `Idempotency-Replayed` — Present and `true` only when this response replays a previously stored one for the same Idempotency-Key, rather than reflecting a live execution. Absent on a live response - never sent as `false`.

## Errors

| Code | Status |
| --- | --- |
| `REFERENCE_NOT_FOUND` | 400 |
| `DUPLICATE_CODE` | 400 |
| `UNKNOWN_VALUE` | 400 |
| `TRACKING_MISMATCH` | 400 |
| `ITEM_TYPE_NOT_STOCKABLE` | 400 |
| `VALUATION_METHOD_UNAVAILABLE` | 400 |
| `UNIT_NOT_IN_UNIT_GROUP` | 400 |
| `IDEMPOTENCY_KEY_CONFLICT` | 409 |
| `IDEMPOTENCY_PAYLOAD_MISMATCH` | 422 |

## Statuses

- `400` — Invalid request or business failure. Codes: REFERENCE_NOT_FOUND, DUPLICATE_CODE, UNKNOWN_VALUE, TRACKING_MISMATCH, ITEM_TYPE_NOT_STOCKABLE, VALUATION_METHOD_UNAVAILABLE, UNIT_NOT_IN_UNIT_GROUP
- `401` — Missing or invalid access token
- `403` — Not authorized
- `404` — Not found
- `409` — The Idempotency-Key is still being processed by another request.
- `422` — The Idempotency-Key was already used with a different request payload.
- `429` — Too many requests
- `500` — Internal server error
