Skip to Content
Welcome to Zendera Knowledge Hub

Atoms API

v1

Manage and visualize hierarchical product relationships. Atoms represent the actual physical items in orders and their parent-child relationships.

Interactive API Explorer

Loading API Documentation...

Authentication

Authorization: apikey YOUR_API_KEY_HERE

Base URLs

  • Production: https://app.zenderatms.com/api/
  • Staging: https://staging.zenderatms.com/api/

Endpoints

Get Atom Tree

Retrieve the complete hierarchical structure of products for an order.

GET /v1/atoms/{orderId}/tree

Parameters:

  • orderId (path): Zendera order ID

Example Request:

curl "https://app.zenderatms.com/api/v1/atoms/12345/tree" \ -H "Authorization: apikey YOUR_API_KEY"

Response:

{ "atoms": [ { "id": 1001, "type": "colli", "name": "Pallet", "description": "Standard pallet", "quantity": 1, "length": 120.0, "width": 80.0, "height": 180.0, "weight": 50.0, "internalProductNumber": "PALLET_001", "internalOrderProductNumber": "OP_001", "barcodeId": "PALLET_BARCODE_001", "barcodeType": "CODE128", "parentId": null, "children": [ { "id": 1002, "type": "trade item", "name": "Product A", "quantity": 10, "weight": 20.0, "internalProductNumber": "PROD_A_001", "parentId": 1001, "children": [], "statuses": [ { "status": "PENDING_ORDER_PRODUCT_ORDER_LOCATION_STATUS", "type": "PICKUP", "isScanned": false }, { "status": "PENDING_ORDER_PRODUCT_ORDER_LOCATION_STATUS", "type": "DELIVERY", "isScanned": false } ] } ], "statuses": [ { "status": "PENDING_ORDER_PRODUCT_ORDER_LOCATION_STATUS", "type": "PICKUP", "isScanned": false } ], "skills": [ { "id": 123, "type": "REQUIRED", "name": "Forklift", "description": "Requires forklift handling" } ], "groups": [ { "id": 456, "name": "Fragile Items", "description": "Handle with care" } ], "units": [ { "id": 789, "quantity": 1, "unitId": 1, "name": "Pallet", "description": "Standard EUR pallet" } ] } ] }

Update Atom Hierarchy

Modify the parent-child relationships between atoms.

PATCH /v1/atoms/{orderId}/tree

Parameters:

  • orderId (path): Zendera order ID

Request Body:

{ "id": 1002, "parentId": 1001 }

This moves atom with ID 1002 to become a child of atom 1001.

Example Request:

curl -X PATCH "https://app.zenderatms.com/api/v1/atoms/12345/tree" \ -H "Authorization: apikey YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "id": 1002, "parentId": 1001 }'

Response:

{ "atoms": [ // Updated atom tree structure ] }

Atom Fields Explained

Core Atom Properties

  • id: Zendera internal atom ID
  • type: Atom type ("colli" or "trade item")
  • name: Product name
  • description: Product description
  • quantity: Number of items
  • parentId: Parent atom ID (null for root items)

Physical Properties

  • length, width, height: Dimensions in cm
  • weight: Weight in kg

Identification

  • internalProductNumber: Your product identifier
  • internalOrderProductNumber: Unique order product identifier
  • barcodeId: Barcode for scanning
  • barcodeType: Type of barcode (CODE128, EAN13, etc.)

Warehouse Management

  • pickupWarehouseLocation: Pickup warehouse identifier
  • deliveryWarehouseLocation: Delivery warehouse identifier

Status Tracking

  • statuses: Array of status per location type (PICKUP/DELIVERY)
  • isScanned: Whether the item has been scanned

Skills & Requirements

  • skills: Array of required/prohibited skills for handling
  • groups: Classification groups
  • units: Custom measurement units

Atom Hierarchy Patterns

Simple Container

Pallet (colli) ├── Product A (trade item) × 10 └── Product B (trade item) × 5

Nested Containers

Pallet (colli) ├── Box 1 (colli) │ ├── Product A (trade item) × 5 │ └── Product B (trade item) × 3 └── Box 2 (colli) ├── Product C (trade item) × 2 └── Product D (trade item) × 8

Mixed Structure

Order ├── Loose Item (trade item) × 1 ├── Pallet 1 (colli) │ └── Products (trade item) × 20 └── Pallet 2 (colli) ├── Box A (colli) │ └── Small Items (trade item) × 50 └── Large Item (trade item) × 3

Status Values

Location Status Options

  • NOT_READY_ORDER_PRODUCT_LOCATION_STATUS: Product not ready for this location
  • PENDING_ORDER_PRODUCT_ORDER_LOCATION_STATUS: Awaiting processing at location
  • COMPLETE_ORDER_PRODUCT_ORDER_LOCATION_STATUS: Processing complete at location
  • REMOVED_ORDER_PRODUCT_ORDER_LOCATION_STATUS: Product removed/cancelled

Location Types

  • PICKUP: Status at pickup location
  • DELIVERY: Status at delivery location

Use Cases

Hierarchy Visualization

Use the atom tree to build visual representations of product hierarchies:

async function visualizeOrderHierarchy(orderId) { const response = await fetch(`${API_BASE}/v1/atoms/${orderId}/tree`, { headers: { Authorization: `apikey ${API_KEY}` }, }); const data = await response.json(); function renderAtom(atom, level = 0) { const indent = ' '.repeat(level); console.log(`${indent}${atom.name} (${atom.type}) - Qty: ${atom.quantity}`); if (atom.children) { atom.children.forEach(child => renderAtom(child, level + 1)); } } data.atoms.forEach(atom => renderAtom(atom)); }

Container Management

Move products between containers:

async function moveProductToContainer(orderId, productAtomId, containerAtomId) { const response = await fetch(`${API_BASE}/v1/atoms/${orderId}/tree`, { method: 'PATCH', headers: { Authorization: `apikey ${API_KEY}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ id: productAtomId, parentId: containerAtomId, }), }); const updatedTree = await response.json(); console.log('Hierarchy updated:', updatedTree); return updatedTree; }

Status Tracking

Monitor scanning and completion status:

async function getProductStatus(orderId, productExternalId) { const response = await fetch(`${API_BASE}/v1/atoms/${orderId}/tree`, { headers: { Authorization: `apikey ${API_KEY}` }, }); const data = await response.json(); function findProduct(atoms, externalId) { for (const atom of atoms) { if (atom.internalProductNumber === externalId) { return atom; } if (atom.children) { const found = findProduct(atom.children, externalId); if (found) return found; } } return null; } const product = findProduct(data.atoms, productExternalId); if (product && product.statuses) { const statusReport = {}; product.statuses.forEach(status => { statusReport[status.type] = { status: status.status, isScanned: status.isScanned, }; }); return statusReport; } return null; }

Warehouse Location Tracking

Track products across warehouse locations:

async function getWarehouseLocations(orderId) { const response = await fetch(`${API_BASE}/v1/atoms/${orderId}/tree`, { headers: { Authorization: `apikey ${API_KEY}` }, }); const data = await response.json(); function collectLocations(atoms, locations = {}) { atoms.forEach(atom => { if (atom.pickupWarehouseLocation) { locations.pickup = locations.pickup || []; locations.pickup.push({ atomId: atom.id, productName: atom.name, location: atom.pickupWarehouseLocation, }); } if (atom.deliveryWarehouseLocation) { locations.delivery = locations.delivery || []; locations.delivery.push({ atomId: atom.id, productName: atom.name, location: atom.deliveryWarehouseLocation, }); } if (atom.children) { collectLocations(atom.children, locations); } }); return locations; } return collectLocations(data.atoms); }

Best Practices

1. Use for Visualization Only

The Atoms API is primarily for viewing and understanding product hierarchies. Use the Product Upsert API for modifying products.

2. Cache Atom Trees

Atom trees can be large. Cache the response when possible and only refresh when needed:

class AtomTreeCache { constructor() { this.cache = new Map(); this.cacheTimeout = 5 * 60 * 1000; // 5 minutes } async getAtomTree(orderId) { const cached = this.cache.get(orderId); if (cached && Date.now() - cached.timestamp < this.cacheTimeout) { return cached.data; } const data = await this.fetchAtomTree(orderId); this.cache.set(orderId, { data, timestamp: Date.now(), }); return data; } }

3. Handle Large Hierarchies

For orders with many products, consider pagination or filtering:

async function getAtomSummary(orderId) { const data = await getAtomTree(orderId); const summary = { totalAtoms: 0, colliCount: 0, tradeItemCount: 0, maxDepth: 0, }; function analyzeAtom(atom, depth = 0) { summary.totalAtoms++; summary.maxDepth = Math.max(summary.maxDepth, depth); if (atom.type === 'colli') { summary.colliCount++; } else { summary.tradeItemCount++; } if (atom.children) { atom.children.forEach(child => analyzeAtom(child, depth + 1)); } } data.atoms.forEach(atom => analyzeAtom(atom)); return summary; }

4. Integration with Other APIs

Combine with Order Summary and Product Upsert APIs for complete workflows:

async function completeOrderManagement(orderExternalId) { // 1. Get order details const orderSummary = await getOrderSummary(orderExternalId); const orderId = orderSummary.order.orderId; // 2. View product hierarchy const atomTree = await getAtomTree(orderId); // 3. Update products if needed await upsertProducts({ update: [ /* updates */ ], updateConfig: { hierarchicalMode: true }, }); // 4. View updated hierarchy const updatedTree = await getAtomTree(orderId); return { orderSummary, originalTree: atomTree, updatedTree, }; }

Error Handling

Common error scenarios:

  • ORDER_NOT_FOUND: Order ID doesn’t exist
  • INVALID_ATOM_ID: Atom ID in PATCH request doesn’t exist
  • CIRCULAR_REFERENCE: Attempting to create circular parent-child relationships
  • INVALID_HIERARCHY: Invalid parent-child relationship (e.g., trade item as parent of colli)
Last updated on