# Inventory

> Stock at each location, and the locations themselves.

Source: https://storeware.ai/docs/api-reference/rest/inventory

## List stock

`GET /api/v1/stores/{storeId}/inventory`

One row per variant of every product not archived, with what is on hand, held and left to sell, added up across locations or read for one. `low` is five or fewer left; a variant that is not tracked is never low or out. `meta.counts` says how many of each there are under the same search.

Needs `products:read`.

**Parameters**

| Parameter | In | Type | Description |
| --- | --- | --- | --- |
| `storeId` | path | string | The shop. |
| `filter` | query | string | `all` when not given. One of `all`, `low`, `out`. |
| `search` | query | string | Words in a product’s name, a variant’s name or a SKU. |
| `locationId` | query | string (uuid) | One location. Every location added up when not given. |
| `limit` | query | integer | How many to return, up to 250. Fifty when not given. From 1 to 250. |
| `offset` | query | integer | How many to skip, for the next page. At least 0. |

**Answers** `200`

| Field | Type | Description |
| --- | --- | --- |
| `data` | array of object |  |
| `data[].variantId` | string (uuid) |  |
| `data[].productId` | string (uuid) |  |
| `data[].productTitle` | string |  |
| `data[].variantTitle` | string |  |
| `data[].sku` | string or null |  |
| `data[].tracked` | boolean | False for a variant that carries on selling when it runs out, or is a download. |
| `data[].onHand` | integer |  |
| `data[].reserved` | integer | Held for orders placed and not yet sent. |
| `data[].available` | integer | On hand less reserved. |
| `meta` | object |  |
| `meta.total` | integer | How many match the filter and search, across every page. |
| `meta.counts` | object | How many of each `filter` there are under the same search. |
| `meta.counts.all` | integer |  |
| `meta.counts.low` | integer |  |
| `meta.counts.out` | integer |  |

```bash
curl "https://api.storeware.ai/api/v1/stores/$STORE_ID/inventory" \
  -H "Authorization: Bearer $TOKEN"
```

## List stock on its way

`GET /api/v1/stores/{storeId}/inventory/incoming`

For each variant named, what is on order from vendors and what is in transit between the shop’s locations. None of it is stock that can be sold. Every variant asked about is answered, with zeros when nothing is coming.

Needs `products:read`.

**Parameters**

| Parameter | In | Type | Description |
| --- | --- | --- | --- |
| `storeId` | path | string | The shop. |
| `variantIds` | query | string | Required. Comma separated variant ids, up to 500. |
| `locationId` | query | string (uuid) | Only what is coming to this location. |

**Answers** `200`

| Field | Type | Description |
| --- | --- | --- |
| `data` | array of object |  |
| `data[].variantId` | string (uuid) |  |
| `data[].onOrder` | integer | Asked of a vendor and not yet delivered. |
| `data[].inTransit` | integer | Sent from another of the shop’s locations and not yet arrived. |
| `data[].incoming` | integer | The two together. |

```bash
curl "https://api.storeware.ai/api/v1/stores/$STORE_ID/inventory/incoming" \
  -H "Authorization: Bearer $TOKEN"
```

## Get a variant’s stock levels

`GET /api/v1/stores/{storeId}/inventory/{variantId}`

The variant’s level at each location that has one. A location that has never held it has no row: see `getVariantStock` for every location.

Needs `products:read`.

**Parameters**

| Parameter | In | Type | Description |
| --- | --- | --- | --- |
| `storeId` | path | string | The shop. |
| `variantId` | path | string | The variant. |

**Answers** `200`

| Field | Type | Description |
| --- | --- | --- |
| `data` | array of [InventoryLevel](https://storeware.ai/docs/api-reference/rest/objects#inventorylevel) |  |

```bash
curl "https://api.storeware.ai/api/v1/stores/$STORE_ID/inventory/$VARIANT_ID" \
  -H "Authorization: Bearer $TOKEN"
```

## Change stock at a location

`POST /api/v1/stores/{storeId}/inventory/{variantId}`

Send `delta` to add or take away, or `onHand` to set the shelf to a count, never both. Stock cannot fall below zero, nor below what is held for orders. A location kept by a supplier cannot be changed. A delta sent twice is applied twice, so send an `Idempotency-Key` header to make a retry safe.

Needs `products:write`.

**Parameters**

| Parameter | In | Type | Description |
| --- | --- | --- | --- |
| `storeId` | path | string | The shop. |
| `variantId` | path | string | The variant. |

**Body**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `locationId` | string (uuid) | Yes | The location whose shelf changes. |
| `delta` | integer | No | How many to add, or take away when negative. |
| `onHand` | integer | No | What was counted on the shelf. From 0 to 10,000,000. |
| `reason` | string | No | Why, for the stock history. Up to 200 characters. |

**Answers** `200`

| Field | Type | Description |
| --- | --- | --- |
| `data` | [InventoryLevel](https://storeware.ai/docs/api-reference/rest/objects#inventorylevel) |  |

```bash
curl -X POST "https://api.storeware.ai/api/v1/stores/$STORE_ID/inventory/$VARIANT_ID" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d @body.json
```

## List a variant’s stock history

`GET /api/v1/stores/{storeId}/inventory/{variantId}/movements`

Every change to the variant’s stock, newest first: what changed, by how much, what it left, and why where somebody said. Pass `meta.next` back as `before` for the next page.

Needs `products:read`.

**Parameters**

| Parameter | In | Type | Description |
| --- | --- | --- | --- |
| `storeId` | path | string | The shop. |
| `variantId` | path | string | The variant. |
| `limit` | query | integer | How many to return, up to 200. Fifty when not given. From 1 to 200. |
| `before` | query | string | The `meta.next` of the page before. |

**Answers** `200`

| Field | Type | Description |
| --- | --- | --- |
| `data` | array of object |  |
| `data[].id` | string | A 64 bit number, sent as a string. |
| `data[].storeId` | string (uuid) |  |
| `data[].variantId` | string (uuid) |  |
| `data[].locationId` | string (uuid) |  |
| `data[].kind` | string | opening, adjustment, count, reserved, released, shipped, received, returned, transfer_out or transfer_in. |
| `data[].onHandDelta` | number |  |
| `data[].reservedDelta` | number |  |
| `data[].onHandAfter` | number |  |
| `data[].reservedAfter` | number |  |
| `data[].reason` | string or null |  |
| `data[].referenceType` | string or null | What it was for, such as an order or a transfer. |
| `data[].referenceId` | string or null |  |
| `data[].actorType` | string or null | `staff`, `customer`, `plugin`, `agent` or `system`, where known. |
| `data[].actorId` | string or null |  |
| `data[].createdAt` | string (date-time) |  |
| `data[].locationName` | string or null |  |
| `meta` | object |  |
| `meta.next` | string or null | Pass back as `before`. Null on the last page. |

```bash
curl "https://api.storeware.ai/api/v1/stores/$STORE_ID/inventory/$VARIANT_ID/movements" \
  -H "Authorization: Bearer $TOKEN"
```

## Get a variant’s stock at every location

`GET /api/v1/stores/{storeId}/inventory/{variantId}/stock`

The variant, and a row for each of the shop’s locations, including those that hold none of it, default first.

Needs `products:read`.

**Parameters**

| Parameter | In | Type | Description |
| --- | --- | --- | --- |
| `storeId` | path | string | The shop. |
| `variantId` | path | string | The variant. |

**Answers** `200`

| Field | Type | Description |
| --- | --- | --- |
| `data` | object |  |
| `data.variant` | object |  |
| `data.variant.id` | string (uuid) |  |
| `data.variant.productId` | string (uuid) |  |
| `data.variant.productTitle` | string |  |
| `data.variant.variantTitle` | string |  |
| `data.variant.sku` | string or null |  |
| `data.variant.tracked` | boolean | False for a variant that carries on selling when it runs out, or is a download. |
| `data.levels` | array of object |  |
| `data.levels[].locationId` | string (uuid) |  |
| `data.levels[].locationName` | string |  |
| `data.levels[].kind` | string | `supplier` stock is refreshed from the supplier and cannot be changed here. One of `own`, `supplier`. |
| `data.levels[].onHand` | integer |  |
| `data.levels[].reserved` | integer |  |
| `data.levels[].available` | integer |  |

```bash
curl "https://api.storeware.ai/api/v1/stores/$STORE_ID/inventory/$VARIANT_ID/stock" \
  -H "Authorization: Bearer $TOKEN"
```

## List locations

`GET /api/v1/stores/{storeId}/locations`

Every place the shop keeps stock.

Needs `products:read`.

**Parameters**

| Parameter | In | Type | Description |
| --- | --- | --- | --- |
| `storeId` | path | string | The shop. |

**Answers** `200`

| Field | Type | Description |
| --- | --- | --- |
| `data` | array of [Location](https://storeware.ai/docs/api-reference/rest/objects#location) |  |

```bash
curl "https://api.storeware.ai/api/v1/stores/$STORE_ID/locations" \
  -H "Authorization: Bearer $TOKEN"
```

## Create a location

`POST /api/v1/stores/{storeId}/locations`

With `isDefault`, the new location becomes the one orders take their stock from, in place of the old default.

Needs `products:write`.

**Parameters**

| Parameter | In | Type | Description |
| --- | --- | --- | --- |
| `storeId` | path | string | The shop. |

**Body**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | Yes |  |
| `isDefault` | boolean | No |  |

**Answers** `201`

| Field | Type | Description |
| --- | --- | --- |
| `data` | [Location](https://storeware.ai/docs/api-reference/rest/objects#location) |  |

```bash
curl -X POST "https://api.storeware.ai/api/v1/stores/$STORE_ID/locations" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d @body.json
```

## Update a location

`PATCH /api/v1/stores/{storeId}/locations/{locationId}`

Renames it, or makes it the default, which moves where every later order takes its stock from. The default cannot be turned off, only moved.

Needs `products:write`.

**Parameters**

| Parameter | In | Type | Description |
| --- | --- | --- | --- |
| `storeId` | path | string | The shop. |
| `locationId` | path | string | The stock location. |

**Body**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | No | 1 to 200 characters. |
| `isDefault` | `true` | No |  |

**Answers** `200`

| Field | Type | Description |
| --- | --- | --- |
| `data` | [Location](https://storeware.ai/docs/api-reference/rest/objects#location) |  |

```bash
curl -X PATCH "https://api.storeware.ai/api/v1/stores/$STORE_ID/locations/$LOCATION_ID" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d @body.json
```
