API reference
Product
https://v2.cartage.ai/p/v2/product reads (GET) and creates (POST) products.
A product is an item you ship: its SKU, how it is packaged for freight, and its freight class. A commodity line's productId points at one.
Authentication, the create envelope, error format and shared objects are in Shared rules.
GET /p/v2/product
Read one product by id. sku and name are not unique, so id is the only lookup.
| Parameter | Required | Description |
|---|---|---|
orgId |
Yes | Your organization ID |
id |
Yes | Product id, for example a commodity line's productId |
curl "https://v2.cartage.ai/p/v2/product?orgId=<yourOrgId>&id=<productId>" \
-H "X-API-Key: <yourApiKey>"
Returns the product (see Schema).
POST /p/v2/product
Create one product.
Required fields
| Field | Required | If missing |
|---|---|---|
name |
Always | 422 PRODUCT_NAME |
Full dimensions on every packagingConfigurations[] entry: length, width, height (each above zero) and their three units |
Only when you send packagingConfigurations and the product is active (status is active or left out) |
422 PRODUCT_PACKAGING_DIMENSIONS |
Smallest valid product: { "name": "Oat Flour 25kg" }.
packagingConfigurations is optional. If you do not know the dimensions yet, leave the packaging entry out or send status: "inactive". Do not guess.
Example
curl -X POST "https://v2.cartage.ai/p/v2/product" \
-H "X-API-Key: <yourApiKey>" \
-H "Content-Type: application/json" \
-d '{
"orgId": "<yourOrgId>",
"product": {
"name": "Oat Flour 25kg",
"sku": "OF-25",
"packagingConfigurations": [
{
"name": "pallet",
"packagingType": "pallet",
"unitsPerPackage": 40,
"dimensions": { "length": 48, "width": 40, "height": 50, "lengthUnit": "in", "widthUnit": "in", "heightUnit": "in" },
"weight": { "value": 2250, "unit": "lbs" },
"freightClass": "65"
}
]
}
}'
{
"status": "CREATED",
"product": { "id": "prd_123", "name": "Oat Flour 25kg", "sku": "OF-25", "…": "…" }
}
Errors
| Status | Code | Meaning and fix |
|---|---|---|
| 400 | — | Missing orgId or id on GET. On POST, a wrong type, an unknown enum value, or a field not in the Schema. issues[] names each one. |
| 401 | — | Missing or invalid API key |
| 404 | PRODUCT_NOT_FOUND |
No product with that id in your organization |
| 422 | REQUIRED_FIELDS_MISSING |
A required field is missing. Each issues[] entry carries one of the codes in Required fields and lists every missing path under fields. |
Schema
Optional unless marked Required. id, orgId, createdAt, updatedAt and activityLog are returned on every product and cannot be sent.
| Field | Type | Description |
|---|---|---|
name |
string | Required. Product name |
sku |
string | Your SKU. Not checked for uniqueness. |
status |
enum | active (default) | inactive | discontinued |
description |
string | Description |
categories |
string[] | Your own category labels |
unitCost / unitPrice |
Money | Cost and sell price per unit |
quantity |
number | Units on hand |
reorderPoint / reorderQuantity |
number | Replenishment thresholds |
addressBookId |
string | Where the product is stocked |
relatedProductIds |
string[] | Related products |
packagingConfigurations |
object[] | The ways this product ships. See below. |
palletGeometry |
object | Per-supplier pallet facts. See below. |
notes |
string | Free-form notes |
fileIds |
string[] | Attached files, such as spec sheets |
A product that ships only one way can instead carry dimensions, weight, packagingType, unitsPerPackage, isStackable, freightClass and nmfcCode at the top level.
Packaging configurations
One entry per way the product ships (palletized, loose carton, drum). Freight class is per entry because the same product can class differently palletized and loose.
| Field | Type | Description |
|---|---|---|
dimensions |
Dimensions | Required on an active product. Outer size of one handling unit |
name |
string | Label, such as pallet or single carton |
packagingType |
enum | pallet | box | carton | crate | drum | bag | roll | other |
unitsPerPackage |
number | Units in one handling unit |
weight |
Weight | Weight of one handling unit |
isStackable |
boolean | Whether handling units stack |
freightClass / nmfcCode |
string | Freight class and NMFC code |
Pallet geometry
How one supplier packs this product. Cartage learns it from your documents; send it to correct it.
| Field | Type | Description |
|---|---|---|
vendor |
string | Supplier name as written on your documents |
supplierId |
string | The supplier's vendor id |
unitFormat |
enum | BAG | PAIL | DRUM | TOTE | CASE | BOX | JUG |
kgPerUnit |
number | Kilograms per unit |
unitsPerPallet |
number | Units on a full pallet |
palletLoadKg |
number | Kilograms on a full pallet |
typicalPalletCount |
number | Typical pallets per order |
sampleCount / lastSeenAt |
number / string | How many documents the numbers came from, and when last seen |
notes |
string | Notes |