APIProduct category

Upsert a product category

POST
/public/v1/product-categories

Create or update a single product category. Include the id of an existing category to update it in place; omit id to create a new one. A create returns 201, an update returns 200. Updates are sparse — only the fields you send change, and omitted fields keep their current value.

name must be unique within your company. A name currently held by a soft-deleted category is also rejected, so restore or rename that deleted category first. Names are trimmed of surrounding whitespace and may not contain special characters.

official_product_category_id maps the category to Distru's system-defined official category list and is required when creating. Once a category maps to a non-null official category that mapping is locked: on update, omit it or resend the same value — sending a different value is rejected. The one exception is a category that is currently unmapped (null), which can happen for categories created before this mapping existed: you may set its mapping on an update, but not change it afterward. This mapping also drives how the category is synced to your connected point-of-sale integrations (Blaze, Dutchie, Treez), so treat it as permanent once chosen.

Subcategories are not editable through this endpoint; manage them with the product subcategory endpoints. Existing products keep their category assignment.

Required permission: settings_permissions_product_categories.

Authorization

Bearer
headerAuthorizationBearer <token>

API token generated in Distru (Settings → Distru API). Send it on every request as Authorization: Bearer YOUR_API_TOKEN.

Request Body

application/json
  1. body
id?string

ID of the category to update. When present, that category is updated in place; when absent, a new category is created.

name*string

The category's display name. Must be unique within your company (a name held by a soft-deleted category is also rejected). Trimmed of surrounding whitespace; special characters are not allowed. Required when creating; on update, omit to leave the current name unchanged.

official_product_category_id*string

ID of the official (Distru system-defined) category this maps to; list valid IDs with GET /public/v1/official-product-categories. Required when creating. Once a category holds a non-null mapping it is locked — on update omit it or resend the same value, since a different value is rejected. A category that is currently unmapped (null) is the one exception: you may set its mapping on an update, but not change it afterward. This mapping drives how the category syncs to your point-of-sale integrations (Blaze, Dutchie, Treez). This is an external-facing string ID, not a numeric one.

Response Body

The updated product category

*/*
  1. response

A single product category

data?

A product category

Example Request
curl -X POST 'https://app.distru.com/public/v1/product-categories' \  -H 'Content-Type: application/json' \  -d '{  "id": "00000000-0000-0000-0000-0000000000a7",  "name": "New"}'
Example Response
{  "data": {    "id": "00000000-0000-0000-0000-0000000000a7",    "inserted_datetime": "2026-08-24T16:01:06.658921Z",    "name": "New",    "official_product_category_id": "OTHER",    "subcategories": [      {        "id": "00000000-0000-0000-0000-00000000009e",        "name": "Gummies"      }    ],    "updated_datetime": "2026-08-24T16:01:06.703383Z"  }}