Products API
List, create, update and deactivate the products and materials in your catalog. Paths and fields as the API accepts them.
Products are the catalog your batches are recorded against: a name and an optional variety, such as "Turmeric · Lakadong". Materials are inputs you buy and use in processing, such as packaging or an ingredient. Every request needs an access token (see Authentication).
Endpoints
| Method | Path | What it does |
|---|---|---|
| GET | /api/v1/products/ |
List your active products and materials |
| POST | /api/v1/products/ |
Add one |
| GET | /api/v1/products/{id}/ |
Read one |
| PUT | /api/v1/products/{id}/ |
Update it; fields you leave out keep their values |
| DELETE | /api/v1/products/{id}/ |
Deactivate it (admins only) |
List products
GET /api/v1/products/?item_type=product
Authorization: Bearer <access token>
item_type is optional: product or material. The response is a plain array (not paginated), sorted by name and variety:
[
{
"id": 7,
"name": "Turmeric",
"variety": "Lakadong",
"item_type": "product",
"image_url": "https://…/turmeric.jpg",
"origin_story": "…",
"shop_url": null,
"is_shop_enabled": true,
"video_url": null,
"is_video_enabled": false,
"is_active": true,
"batch_count": 12
}
]
Add a product
POST /api/v1/products/
{"name": "Turmeric", "variety": "Lakadong", "item_type": "product", "origin_story": "Grown on hill farms in Meghalaya."}
nameis required.variety,item_type(defaultproduct),origin_storyandimage_urlare optional.- The same name and variety can exist only once per organization; a duplicate returns
400. shop_url(the Buy Again button on the trace page) andvideo_url(a product video) need the Growth or Pro plan. Without it the API returns402with"code": "plan_feature_blocked".
A new batch copies the product's name, variety, image and origin story into its own record, so later catalog edits don't change batches that already exist.
Deactivate a product
DELETE /api/v1/products/{id}/ hides the product from your catalog and pickers (is_active becomes false). Existing batches keep it. Only admins can do this.
Errors
| Status | Meaning |
|---|---|
| 400 | Invalid input, for example a missing name or a duplicate name and variety ({"error": "message"}) |
| 401 | Missing or expired access token |
| 402 | The feature needs a higher plan (plan_feature_blocked) |
| 403 | Your role may not do this |
| 404 | No such product in your organization |