Cartons
scope: inventoryCreate and manage carton definitions. A carton describes a box configuration — its contents (which products and how many), physical dimensions, and weight. Contents, dimensions, and weight are set at creation and cannot be changed afterwards. Only the carton name can be updated.
Where cartons fit in
Cartons are the physical packaging unit. Each carton type defines a box containing a set quantity of one product, with specific dimensions and weight.
Endpoints
/v0/inventory/cartonsList all cartons with search, filter, and sort
/v0/inventory/cartons/:idGet a single carton by ID
/v0/inventory/cartons/:id/historyGet change history for a carton
/v0/inventory/cartonsCreate a new carton
/v0/inventory/cartons/:idUpdate a carton (name only)
/v0/inventory/cartons/:idDelete a carton (soft-delete, must have 0 stock)
/v0/inventory/cartons/:id/restoreRestore a previously deleted carton
List Cartons
Returns a paginated list of cartons. By default, deleted cartons are excluded.
Query Parameters
| Parameter | Type | Description |
|---|---|---|
search | string | Partial match on carton name, product name, or SKU |
productId | string | Filter by product ID |
includeDeleted | boolean | Include soft-deleted cartons (default: false) |
sortBy | string | Sort field: name, 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/cartons?search=10-pack" \-H "Authorization: Bearer <token>"
const res = await fetch("https://api.3plguys.com/v0/inventory/cartons?search=10-pack",{ headers: { Authorization: `Bearer ${token}` } });const cartons = await res.json();
[{"id": "1","name": "10-Pack Case","contents": [{"productId": "1","productName": "Egg Shells","sku": "ABC123","quantity": 10}],"dimensions": { "length": 12, "width": 10, "height": 8, "units": "inch" },"weight": { "amount": 5, "units": "pound" },"createdAt": "2025-01-15T08:30:00.000Z","updatedAt": "2025-02-20T14:00:00.000Z","deletedAt": null}]
Get Carton
Retrieve a single carton by its ID. Returns 404 if the carton does not exist or belongs to another organization.
{"id": "1","name": "10-Pack Case","contents": [{"productId": "1","productName": "Egg Shells","sku": "ABC123","quantity": 10}],"dimensions": { "length": 12, "width": 10, "height": 8, "units": "inch" },"weight": { "amount": 5, "units": "pound" },"createdAt": "2025-01-15T08:30:00.000Z","updatedAt": "2025-02-20T14:00:00.000Z","deletedAt": null}
Create Carton
Request Body
| Parameter | Type | Description |
|---|---|---|
name | string | Carton name (auto-generated if omitted) |
contents* | array | Products in this carton (currently limited to 1 item) |
contents[].productId* | string | Product ID |
contents[].quantity* | number | Units of this product per carton (min: 1) |
dimensions* | object | Physical dimensions of the carton |
dimensions.length* | number | Length |
dimensions.width* | number | Width |
dimensions.height* | number | Height |
dimensions.units* | string | Unit of measurement (e.g. inch, millimeter) |
weight* | object | Weight of the carton |
weight.amount* | number | Weight value |
weight.units* | string | Unit of measurement (e.g. pound, gram) |
curl -X POST "https://api.3plguys.com/v0/inventory/cartons" \-H "Authorization: Bearer <token>" \-H "Content-Type: application/json" \-d '{"name": "10-Pack Case","contents": [{ "productId": "1", "quantity": 10 }],"dimensions": { "length": 12, "width": 10, "height": 8, "units": "inch" },"weight": { "amount": 5, "units": "pound" }}'
const res = await fetch("https://api.3plguys.com/v0/inventory/cartons", {method: "POST",headers: {Authorization: `Bearer ${token}`,"Content-Type": "application/json",},body: JSON.stringify({name: "10-Pack Case",contents: [{ productId: "1", quantity: 10 }],dimensions: { length: 12, width: 10, height: 8, units: "inch" },weight: { amount: 5, units: "pound" },}),});const carton = await res.json();
{"name": "10-Pack Case","contents": [{ "productId": "1", "quantity": 10 }],"dimensions": { "length": 12, "width": 10, "height": 8, "units": "inch" },"weight": { "amount": 5, "units": "pound" }}
{"id": "3","name": "10-Pack Case","contents": [{"productId": "1","productName": "Egg Shells","sku": "ABC123","quantity": 10}],"dimensions": { "length": 12, "width": 10, "height": 8, "units": "inch" },"weight": { "amount": 5, "units": "pound" },"createdAt": "2025-03-04T10:00:00.000Z","updatedAt": "2025-03-04T10:00:00.000Z","deletedAt": null}
Immutable after creation
PUT.Update Carton
Only the carton name can be updated.
Request Body
| Parameter | Type | Description |
|---|---|---|
name* | string | New carton name (min 2 chars) |
{"name": "10-Pack Shipping Case"}
Delete Carton
Soft-deletes a carton. The carton must have zero stock across all warehouses. Deleted cartons are excluded from list results unless includeDeleted=true is passed.
{"id": "3","name": "10-Pack Shipping Case","contents": [ ... ],"dimensions": { ... },"weight": { ... },"createdAt": "2025-03-04T10:00:00.000Z","updatedAt": "2025-03-04T12:00:00.000Z","deletedAt": "2025-03-04T12:00:00.000Z"}
Restore Carton
Restores a previously deleted carton, making it active again.
{"id": "3","name": "10-Pack Shipping Case",..."deletedAt": null}
Carton History
Returns a paginated list of change events for a carton, including creation, name changes, stock count updates, deletes, and restores. 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/cartons/1/history?take=10" \-H "Authorization: Bearer <token>"
const res = await fetch(`https://api.3plguys.com/v0/inventory/cartons/${cartonId}/history?take=10`,{ headers: { Authorization: `Bearer ${token}` } });const history = await res.json();
res = httpx.get(f"https://api.3plguys.com/v0/inventory/cartons/{carton_id}/history",params={"take": 10},headers={"Authorization": f"Bearer {token}"},)history = res.json()
[{"id": "20","type": "admin","description": "Updated carton count '10' changed to '15' for '10-Pack Case' carton type.","createdAt": "2026-03-02T08:00:00.000Z"},{"id": "5","type": "customer","description": "Created carton type \"10-Pack Case\" (10 units per carton)","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
400Only one product per carton is supported at this timeEach carton type can only contain one product. Provide a single item in the contents array.
400Product not foundThe product ID in contents does not exist or does not belong to your organization.
400Cannot delete a carton that still has stockReturned when attempting to delete a carton that has inventory in any warehouse.
404Carton not foundThe carton ID does not exist or does not belong to your organization.