# Collections

> Groups of products, set by hand or by rules.

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

## List collections

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

Every collection, or a page of them when any of `search`, `kind`, `sort`, `limit` or `offset` is given. A page carries `meta.total` and, in `meta.counts`, how many products each collection on it holds.

Needs `products:read`.

**Parameters**

| Parameter | In | Type | Description |
| --- | --- | --- | --- |
| `storeId` | path | string | The shop. |
| `search` | query | string | Words in the title or handle. |
| `kind` | query | string | One of `manual`, `automatic`. |
| `sort` | query | string | By title unless `updated_desc`, most recently changed first. Any other value is ignored. One of `title_asc`, `updated_desc`. |
| `limit` | query | integer | How many to return. Fifty when not given. From 1 to 200. |
| `offset` | query | integer | How many to skip, for the next page. At least 0. |

**Answers** `200`

| Field | Type | Description |
| --- | --- | --- |
| `data` | array of [Collection](https://storeware.ai/docs/api-reference/rest/objects#collection) |  |
| `meta` | object | Only on a page. |
| `meta.total` | integer |  |
| `meta.counts` | map of integer | Products in each collection on this page, by id. |

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

## Create a collection

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

Needs `products:write`.

**Parameters**

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

**Body**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `title` | string | Yes | 1 to 300 characters. |
| `handle` | string | No | Up to 128 characters. Matches `^[a-z0-9][a-z0-9-]*$`. |
| `description` | string | No | Up to 50,000 characters. |
| `parentId` | string (uuid) | No |  |
| `seoTitle` | string | No | Up to 300 characters. |
| `seoDescription` | string | No | Up to 1,000 characters. |
| `kind` | string | No | One of `manual`, `automatic`. Default `manual`. |
| `rules` | array of object | No | Up to 10 items. Default `[]`. |
| `rules[].field` | string | Yes | One of `title`, `product_type`, `vendor`, `tag`, `price`. |
| `rules[].operator` | string | Yes | One of `equals`, `not_equals`, `contains`, `starts_with`, `ends_with`, `greater_than`, `less_than`. |
| `rules[].value` | string | Yes | 1 to 200 characters. |
| `rules[].currency` | string | No | Matches `^[A-Z]{3}$`. |
| `sortOrder` | string | No | One of `manual`, `title_asc`, `title_desc`, `created_desc`, `price_asc`, `price_desc`. Default `manual`. |
| `filterable` | boolean | No |  |

**Answers** `201`

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

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

## Get a collection

`GET /api/v1/stores/{storeId}/collections/{collectionId}`

Needs `products:read`.

**Parameters**

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

**Answers** `200`

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

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

## Update a collection

`PATCH /api/v1/stores/{storeId}/collections/{collectionId}`

Changes only the fields sent.

Needs `products:write`.

**Parameters**

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

**Body**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `title` | string | No | 1 to 300 characters. |
| `handle` | string | No | Up to 128 characters. Matches `^[a-z0-9][a-z0-9-]*$`. |
| `description` | string | No | Up to 50,000 characters. |
| `seoTitle` | string | No | Up to 300 characters. |
| `seoDescription` | string | No | Up to 1,000 characters. |
| `rules` | array of object | No | Up to 10 items. |
| `rules[].field` | string | Yes | One of `title`, `product_type`, `vendor`, `tag`, `price`. |
| `rules[].operator` | string | Yes | One of `equals`, `not_equals`, `contains`, `starts_with`, `ends_with`, `greater_than`, `less_than`. |
| `rules[].value` | string | Yes | 1 to 200 characters. |
| `rules[].currency` | string | No | Matches `^[A-Z]{3}$`. |
| `sortOrder` | string | No | One of `manual`, `title_asc`, `title_desc`, `created_desc`, `price_asc`, `price_desc`. |
| `filterable` | boolean | No |  |

**Answers** `200`

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

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

## Delete a collection

`DELETE /api/v1/stores/{storeId}/collections/{collectionId}`

Deletes the collection and says what it touched. Its products are kept, and its children move to the top level.

Needs `products:write`.

**Parameters**

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

**Answers** `200`

| Field | Type | Description |
| --- | --- | --- |
| `data` | object |  |
| `data.id` | string (uuid) |  |
| `data.title` | string |  |
| `data.handle` | string |  |
| `data.productsUnlinked` | integer | Products that were in it. The products are untouched. |
| `data.childrenPromoted` | integer | Child collections moved to the top level. |
| `data.menuItemsRemoved` | integer | Menu entries that pointed at it. |
| `data.discountTargetsRemoved` | integer | Discounts that named it, which now apply to less. |

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

## List a collection’s products

`GET /api/v1/stores/{storeId}/collections/{collectionId}/products`

A page of the products in the collection, in its own order. Pass `meta.next` back as `after` for the next page.

Needs `products:read`.

**Parameters**

| Parameter | In | Type | Description |
| --- | --- | --- | --- |
| `storeId` | path | string | The shop. |
| `collectionId` | path | string | The collection. |
| `search` | query | string | Words in a product’s title. |
| `ids` | query | string | Comma separated product ids: which of these are in it. |
| `limit` | query | integer | How many to return. Fifty when not given. From 1 to 200. |
| `after` | query | string | The `meta.next` of the page before. |

**Answers** `200`

| Field | Type | Description |
| --- | --- | --- |
| `data` | array of [Product](https://storeware.ai/docs/api-reference/rest/objects#product) |  |
| `meta` | object |  |
| `meta.total` | integer | Members the search and ids match. |
| `meta.held` | integer | Every product in the collection. |
| `meta.next` | string or null | Pass back as `after`. Null on the last page. |
| `meta.truncated` | boolean | True when a price sort was cut short at its cap. |

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

## Add products to a collection

`POST /api/v1/stores/{storeId}/collections/{collectionId}/products`

Adds products to a manual collection. Products already in it are left where they are.

Needs `products:write`.

**Parameters**

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

**Body**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `productIds` | array of string (uuid) | Yes | The products to add. |

**Answers** `201`

| Field | Type | Description |
| --- | --- | --- |
| `data` | object |  |
| `data.added` | integer |  |

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

## Remove a product from a collection

`DELETE /api/v1/stores/{storeId}/collections/{collectionId}/products/{productId}`

Needs `products:write`.

**Parameters**

| Parameter | In | Type | Description |
| --- | --- | --- | --- |
| `storeId` | path | string | The shop. |
| `collectionId` | path | string | The collection. |
| `productId` | path | string | The product. |

**Answers** `200`

| Field | Type | Description |
| --- | --- | --- |
| `data` | object |  |
| `data.removed` | `true` |  |

```bash
curl -X DELETE "https://api.storeware.ai/api/v1/stores/$STORE_ID/collections/$COLLECTION_ID/products/$PRODUCT_ID" \
  -H "Authorization: Bearer $TOKEN"
```

## List a collection’s metafields

`GET /api/v1/stores/{storeId}/collections/{collectionId}/metafields`

Every metafield value set on a collection, each with its definition.

Needs `products:read`.

**Parameters**

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

**Answers** `200`

| Field | Type | Description |
| --- | --- | --- |
| `data` | array of object |  |
| `data[].definitionId` | string (uuid) |  |
| `data[].namespace` | string |  |
| `data[].key` | string |  |
| `data[].label` | string | The merchant’s name for the field. |
| `data[].type` | string | single_line_text, multi_line_text, integer, decimal, boolean, date, url and the other definition types. |
| `data[].isList` | boolean |  |
| `data[].storefrontVisible` | boolean |  |
| `data[].searchFacet` | boolean |  |
| `data[].position` | integer |  |
| `data[].value` | any | The value, or a list of values when `isList`. |
| `data[].displayValue` | string | The value as one line of text, lists joined. |
| `data[].source` | string | Who set it: the merchant, an import, or an app’s slug. |

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

## Set a collection’s metafields

`PUT /api/v1/stores/{storeId}/collections/{collectionId}/metafields`

Sets up to 25 values in one call. A null value clears its field; keys not named are left alone. An app may set only the fields its manifest declares.

Needs `products:write`.

**Parameters**

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

**Body**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `metafields` | array of object | Yes | Up to 25 items. At least 1 item. |
| `metafields[].namespace` | string | No | Default `custom`. |
| `metafields[].key` | string | Yes |  |
| `metafields[].value` | any | No |  |

**Answers** `200`

| Field | Type | Description |
| --- | --- | --- |
| `data` | array of object |  |
| `data[].definitionId` | string (uuid) |  |
| `data[].namespace` | string |  |
| `data[].key` | string |  |
| `data[].label` | string | The merchant’s name for the field. |
| `data[].type` | string | single_line_text, multi_line_text, integer, decimal, boolean, date, url and the other definition types. |
| `data[].isList` | boolean |  |
| `data[].storefrontVisible` | boolean |  |
| `data[].searchFacet` | boolean |  |
| `data[].position` | integer |  |
| `data[].value` | any | The value, or a list of values when `isList`. |
| `data[].displayValue` | string | The value as one line of text, lists joined. |
| `data[].source` | string | Who set it: the merchant, an import, or an app’s slug. |

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

## List a collection’s translations

`GET /api/v1/stores/{storeId}/collections/{collectionId}/translations`

Every translated field, by locale.

Needs `products:read`.

**Parameters**

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

**Answers** `200`

| Field | Type | Description |
| --- | --- | --- |
| `data` | map of map of string | Locale, then field, then the translated text. |

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

## Set a collection’s translations

`PUT /api/v1/stores/{storeId}/collections/{collectionId}/translations`

Sets translated fields for one locale. Fields not named are left alone, and a null clears one.

Needs `products:write`.

**Parameters**

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

**Body**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `locale` | string | Yes | Matches `^[a-z]{2,3}(-[A-Z]{2})?$`. |
| `fields` | map of string or null | Yes |  |

**Answers** `200`

| Field | Type | Description |
| --- | --- | --- |
| `data` | map of string | The locale’s fields after the change. |

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