Products API
v1List your organization's product catalogue and look up products by internal product number — the IDs you need for order import, product upsert, and cargo carrier linking.
A product is a catalogue item in Zendera — the thing being transported. Several other APIs take a numeric productId (product upsert, cargo carrier linking) or match on your internal_product_number; these two read endpoints are how an integration resolves them.
Where this fits in your operation
- Reconcile your article master against Zendera: list all products and compare
internal_product_numberagainst your ERP’s article numbers. - Resolve IDs before other calls: look up the numeric
productIdfor an article before linking it as a cargo carrier. - Check transport attributes: read dimensions and weight to validate what your order import will be planned against.
Interactive API Explorer
Loading API Documentation...
Authentication
Authorization: apikey YOUR_API_KEY_HEREBase URLs
- Production:
https://app.zenderatms.com/api/ - Staging:
https://staging.zenderatms.com/api/
List all products
GET /v1/products
Returns every product in your organization (no pagination):
[
{
"id": 4242,
"organization_id": 1,
"name": "eur pallet",
"description": "Standard EUR pallet",
"internal_product_number": "PROD-PALLET-EUR",
"barcode_id": "7038010001234",
"barcode_type": "EAN13",
"length": 1.2,
"width": 0.8,
"height": 0.15,
"weight": 25.0,
"created_at": "2024-01-15T10:00:00Z",
"updated_at": "2024-01-15T10:00:00Z"
}
]If your organization has no products, the response is 204 No Content with an empty body — not an empty array.
Eager-loading related data
Add a loads query parameter (comma-separated, or repeated) to include relationships. Values are the relationship names in PascalCase, and nested relations are joined with a dot:
GET /v1/products?loads=ProductUnits.Unit,ProductSkills.Skillloads value | Adds to the response |
|---|---|
Groups | Product groups (groups[]). |
Groups.GroupTypes | Group types nested under each group. |
ProductSkills | Required/prohibited skills (skills[], each with skill_type of required or prohibited). |
ProductSkills.Skill | The full skill record nested as skill on each entry. |
ProductUnits | Unit links and quantities (units[]). |
ProductUnits.Unit | The full unit record nested as unit on each entry. |
IncompatibleProducts | Products that must not travel together (incompatible_products[]). |
IncompatibleProducts.IncompatibleProduct | The full incompatible product nested on each entry. |
Unrecognised values are silently ignored. The same parameter works on lookup.
Look up one product by internal number
GET /v1/products/lookup?internal_product_number=PROD-PALLET-EUR
Returns the single matching product (same shape as above), or 204 No Content if there is no exact match. The lookup is an exact match on internal_product_number — not the barcode.
Common gotchas
204, not404/empty array. Both endpoints answer204 No Contentwhen nothing matches. Treat 204 as “no result”, not as an error.- snake_case JSON. These are v1 endpoints:
internal_product_number,barcode_id,created_at. The v2/v3 order APIs use camelCase. - Lookup is by internal number, not barcode. There is no barcode lookup in the integration API, even though products carry
barcode_id. - Names are stored lowercase. Product names are normalised to lowercase on creation — match case-insensitively on your side.
- Organization-scoped. You only ever see your own organization’s products.
Related documentation
- Product Upsert — add or update products on an existing order
- Cargo Carrier Accounting — link a product as a returnable cargo carrier