Products
scope: inventoryCreate and manage your product catalog. Products represent the items your organization stores and ships. Each product has a unique SKU that cannot be changed after creation.
Where products fit in
Products are the foundation of your inventory. Create products first, then define cartons that contain them.
Endpoints
/v0/inventory/productsList all products with search, filter, and sort
/v0/inventory/products/:idGet a single product by ID
/v0/inventory/products/:id/historyGet change history for a product
/v0/inventory/productsCreate a new product
/v0/inventory/products/:idUpdate a product (name, description)
/v0/inventory/products/:idDelete a product (soft-delete, must have 0 stock)
/v0/inventory/products/:id/restoreRestore a previously deleted product
List Products
Returns a paginated list of products. By default, deleted products are excluded.
Query Parameters
| Parameter | Type | Description |
|---|---|---|
search | string | Partial match on product name or SKU |
sku | string | Filter by exact SKU |
includeDeleted | boolean | Include soft-deleted products (default: false) |
sortBy | string | Sort field: name, sku, createdAt, updatedAt (default: createdAt) |
sortOrder | string | Sort direction: asc or desc (default: desc) |
skip | number | Number of records to skip (default: 0) |
take | number | Number of records to return (default: 10, max: 50) |
curl "https://api.3plguys.com/v0/inventory/products?search=egg&sortBy=name&sortOrder=asc" \-H "Authorization: Bearer <token>"
const res = await fetch("https://api.3plguys.com/v0/inventory/products?search=egg&sortBy=name&sortOrder=asc",{ headers: { Authorization: `Bearer ${token}` } });const products = await res.json();
res = httpx.get("https://api.3plguys.com/v0/inventory/products",params={"search": "egg", "sortBy": "name", "sortOrder": "asc"},headers={"Authorization": f"Bearer {token}"},)products = res.json()
[{"id": "1","name": "Egg Shells","sku": "ABC123","description": "Premium egg shells for baking","createdAt": "2025-01-15T08:30:00.000Z","updatedAt": "2025-02-20T14:00:00.000Z","deletedAt": null}]
Get Product
Retrieve a single product by its ID. Returns 404 if the product does not exist or belongs to another organization.
{"id": "1","name": "Egg Shells","sku": "ABC123","description": "Premium egg shells for baking","createdAt": "2025-01-15T08:30:00.000Z","updatedAt": "2025-02-20T14:00:00.000Z","deletedAt": null}
Create Product
Request Body
| Parameter | Type | Description |
|---|---|---|
name* | string | Product name (minimum 2 characters) |
sku* | string | Unique SKU within your organization (minimum 2 characters, immutable) |
description | string | Optional product description |
curl -X POST "https://api.3plguys.com/v0/inventory/products" \-H "Authorization: Bearer <token>" \-H "Content-Type: application/json" \-d '{ "name": "Egg Shells", "sku": "ABC123", "description": "Premium egg shells for baking" }'
const res = await fetch("https://api.3plguys.com/v0/inventory/products", {method: "POST",headers: {Authorization: `Bearer ${token}`,"Content-Type": "application/json",},body: JSON.stringify({name: "Egg Shells",sku: "ABC123",description: "Premium egg shells for baking",}),});const product = await res.json();
res = httpx.post("https://api.3plguys.com/v0/inventory/products",json={"name": "Egg Shells", "sku": "ABC123", "description": "Premium egg shells for baking"},headers={"Authorization": f"Bearer {token}"},)product = res.json()
{"name": "Egg Shells","sku": "ABC123","description": "Premium egg shells for baking"}
{"id": "1","name": "Egg Shells","sku": "ABC123","description": "Premium egg shells for baking","createdAt": "2025-01-15T08:30:00.000Z","updatedAt": "2025-01-15T08:30:00.000Z","deletedAt": null}
SKU is immutable
Update Product
Request Body
| Parameter | Type | Description |
|---|---|---|
name* | string | Product name (minimum 2 characters) |
description | string | Optional product description |
{"name": "Egg Shells (Large)","description": "Updated description"}
{"id": "1","name": "Egg Shells (Large)","sku": "ABC123","description": "Updated description","createdAt": "2025-01-15T08:30:00.000Z","updatedAt": "2025-03-04T10:15:00.000Z","deletedAt": null}
Delete Product
Soft-deletes a product. The product must have zero stock across all warehouses. Deleted products are excluded from list results unless includeDeleted=true is passed.
{"id": "1","name": "Egg Shells","sku": "ABC123","description": "Premium egg shells for baking","createdAt": "2025-01-15T08:30:00.000Z","updatedAt": "2025-03-04T12:00:00.000Z","deletedAt": "2025-03-04T12:00:00.000Z"}
Restore Product
Restores a previously deleted product, making it active again.
{"id": "1","name": "Egg Shells","sku": "ABC123","description": "Premium egg shells for baking","createdAt": "2025-01-15T08:30:00.000Z","updatedAt": "2025-03-04T12:05:00.000Z","deletedAt": null}
Product History
Returns a paginated list of change events for a product, including creation, updates, deletes, restores, and stock changes. Only publicly visible entries are returned.
Query Parameters
| Parameter | Type | Description |
|---|---|---|
skip | number | Number of records to skip (default: 0) |
take | number | Number of records to return (default: 10, max: 50) |
curl "https://api.3plguys.com/v0/inventory/products/1/history?take=10" \-H "Authorization: Bearer <token>"
const res = await fetch(`https://api.3plguys.com/v0/inventory/products/${productId}/history?take=10`,{ headers: { Authorization: `Bearer ${token}` } });const history = await res.json();
res = httpx.get(f"https://api.3plguys.com/v0/inventory/products/{product_id}/history",params={"take": 10},headers={"Authorization": f"Bearer {token}"},)history = res.json()
[{"id": "15","type": "customer","description": "Updated product Egg Shells (ABC123)","createdAt": "2026-03-04T10:15:00.000Z"},{"id": "12","type": "admin","description": "Updated carton count '10' changed to '15' for '10-Pack Case' carton type.","createdAt": "2026-03-02T08:00:00.000Z"},{"id": "1","type": "customer","description": "Created new product Egg Shells (ABC123)","createdAt": "2025-01-15T08:30:00.000Z"}]
Response Fields
| Parameter | Type | Description |
|---|---|---|
id* | string | History entry ID |
type* | string | Who made the change: system, customer, or admin |
description* | string | Human-readable description of what changed |
createdAt* | ISO 8601 | When the change occurred |
Error Responses
400SKU is already in use in your inventoryReturned when creating a product with a SKU that already exists in your organization.
400Cannot delete a product that still has stockReturned when attempting to delete a product that has cartons in any warehouse.
404Product not foundThe product ID does not exist or does not belong to your organization.