# Categorize products

> Build a category tree, describe it with an attribute, and classify a product.

This guide organizes your catalog with [categories](/api/product-management/categories/). You'll build a small **taxonomy** - a tree of categories - add an **attribute** to describe products in it, and classify a product, so it ends up filed under "Shoes" with a "Color" of "Red".

Three pieces fit together:

- a **category** classifies products and nests under a parent; together, categories form a **taxonomy** (the tree);
- an **attribute** ([list](/api/product-management/attribute-lists/) or [string](/api/product-management/attribute-strings/)) is a property products in a category can have - here a `Color` list;
- an **attribute value** is one entry of that attribute's reference list (`Red`); you build the list once, then associate entries with specific products.

## Prerequisites

You need a **product** on an existing instance. If you don't have one, follow [Create your first product](/guides/create-your-first-product/) first.

As in the other guides, the commands below use the organization `id` (shown as `<org_id>`) and the instance `handle` (the tenant, shown as `<tenant>`). The example reuses one product id, `019af93e-...` - replace it with your own.

## Before you start

You need an OAuth 2.0 **bearer token** for a partner account. Sign in below: your token is dropped into every command on this page, and you can pick your organization and instance to fill `<org_id>` and `<tenant>`. See [Authentication](/authentication/) for more.

## Steps

<Steps>

1. **Create a top-level category.**

   Start the tree with a parent. Capture its `@id` - the child references it next.

   ```bash
   curl -X POST 'https://<tenant>.product-management.flowkiwi.net/rest/api/categories' \
     -H 'Authorization: Bearer {token}' \
     -H 'X-Flowkiwi-Organization-Id: <org_id>' \
     -H 'Content-Type: application/ld+json' \
     -d '{
       "status": "/rest/api/statuses/ACTIVE",
       "name": "Clothing"
     }'
   ```

   ```json
   {
     "@id": "/rest/api/categories/019afd01-1a2b-7c3d-8e4f-0a1b2c3d4e5f",
     "name": "Clothing"
   }
   ```

2. **Create a child category and classify the product.**

   Nest "Shoes" under "Clothing" with `parent`, and file your product into it with `products`. Capture the child's `@id`.

   ```bash
   curl -X POST 'https://<tenant>.product-management.flowkiwi.net/rest/api/categories' \
     -H 'Authorization: Bearer {token}' \
     -H 'X-Flowkiwi-Organization-Id: <org_id>' \
     -H 'Content-Type: application/ld+json' \
     -d '{
       "status": "/rest/api/statuses/ACTIVE",
       "name": "Shoes",
       "parent": "/rest/api/categories/019afd01-1a2b-7c3d-8e4f-0a1b2c3d4e5f",
       "products": [
         "/rest/api/products/019af93e-420e-79f8-800b-6680f03dce20"
       ]
     }'
   ```

   ```json
   {
     "@id": "/rest/api/categories/019afd02-2b3c-7d4e-9f50-1a2b3c4d5e6f",
     "name": "Shoes",
     "parent": "/rest/api/categories/019afd01-1a2b-7c3d-8e4f-0a1b2c3d4e5f"
   }
   ```

3. **Add an attribute to the category.**

   Create a `Color` [list attribute](/api/product-management/attribute-lists/) and apply it to "Shoes" through `categories`. Capture the attribute's `@id`.

   ```bash
   curl -X POST 'https://<tenant>.product-management.flowkiwi.net/rest/api/categories/attribute_lists' \
     -H 'Authorization: Bearer {token}' \
     -H 'X-Flowkiwi-Organization-Id: <org_id>' \
     -H 'Content-Type: application/ld+json' \
     -d '{
       "name": "Color",
       "categories": [
         "/rest/api/categories/019afd02-2b3c-7d4e-9f50-1a2b3c4d5e6f"
       ]
     }'
   ```

   ```json
   {
     "@id": "/rest/api/categories/attribute_lists/019afd10-3c4d-7e5f-8a60-2b3c4d5e6f70",
     "name": "Color"
   }
   ```

4. **Build the reference values (the options).**

   Create the options of your `Color` attribute - this is the reference list. Each option belongs to the attribute, not yet to any product. Create one per option and capture its `@id`.

   ```bash
   curl -X POST 'https://<tenant>.product-management.flowkiwi.net/rest/api/categories/attribute_list_values' \
     -H 'Authorization: Bearer {token}' \
     -H 'X-Flowkiwi-Organization-Id: <org_id>' \
     -H 'Content-Type: application/ld+json' \
     -d '{
       "value": "Red",
       "attribute": "/rest/api/categories/attribute_lists/019afd10-3c4d-7e5f-8a60-2b3c4d5e6f70"
     }'
   ```

   ```json
   {
     "@id": "/rest/api/categories/attribute_list_values/019afd20-5e6f-7081-8a92-4d5e6f708192",
     "value": "Red"
   }
   ```

   Repeat for the other options (`Black`, `Blue`, ...) to fill out the list.

5. **Associate an option with your product.**

   Now link the option to the product by adding it to the value's `products`. The product carries `Color: Red`.

   ```bash
   curl -X PATCH 'https://<tenant>.product-management.flowkiwi.net/rest/api/categories/attribute_list_values/019afd20-5e6f-7081-8a92-4d5e6f708192' \
     -H 'Authorization: Bearer {token}' \
     -H 'X-Flowkiwi-Organization-Id: <org_id>' \
     -H 'Content-Type: application/merge-patch+json' \
     -d '{
       "products": [
         "/rest/api/products/019af93e-420e-79f8-800b-6680f03dce20"
       ]
     }'
   ```

   To give the product several options, add it to each option's `products` in the same way.

</Steps>

> **List vs string attributes**
>
> `Color` is a [list attribute](/api/product-management/attribute-lists/) because its values come from a fixed set of options (Red, Black, ...). For free text - a care note, say - use a [string attribute](/api/product-management/attribute-strings/) and its [string values](/api/product-management/attribute-string-values/) instead.

## Next steps

- **Read the tree back.** [List categories](/api/product-management/categories/list/) to see each node with its `parent` and `childrens`.
- **Describe with free text.** For a value that isn't a fixed option - a care note, say - use a [string attribute](/api/product-management/attribute-strings/) and its [string values](/api/product-management/attribute-string-values/) instead of a list.
- **Reuse the attribute.** A `Color` attribute can apply to several categories - add their IRIs to its `categories`.
