CubeMaster API Integration Guide

Using JavaScript/Node.js with Axios and Fetch API

To use the CubeMaster API, you need an API key (TokenID) for authentication. Here's how to get started:

  1. Visit the CubeMaster website: https://cubemaster.net.
  2. Locate the "Sign In" option (typically found in the top-right corner).
  3. Fill out the registration form with your details (e.g., name, email, password, company information).
  4. After signing up, log in to your account dashboard.
  5. Navigate to the "Settings" - "Integration" section to generate your API key (TokenID).
  6. Generate an API key. Once generated, you’ll receive a unique TokenID (e.g., abc123xyz789). Copy this key and store it securely, as it will be used in the HTTP headers of your API requests.
  7. Copy the TokenID and store it securely.

Note: The TokenID will be used in the HTTP headers of your POST request for authentication.

A RESTful API (Representational State Transfer) is a way for applications to communicate over the internet using standard HTTP methods. Here’s a quick breakdown:

  • HTTP Methods:
    • GET: Retrieve data (e.g., fetch load details).
    • POST: Send data to create something (e.g., build a load in CubeMaster).
    • PUT: Update existing data.
    • DELETE: Remove data.
  • Endpoints: URLs like https://api.cubemaster.net/loads where you send requests.
  • JSON: Data is exchanged in JSON format, a lightweight, human-readable structure.
  • Headers: Extra info sent with requests, like your TokenID for authentication.
  • Status Codes: Responses include codes like 200 (success), 400 (bad request), or 401 (unauthorized).

In this guide, we’ll use the POST method to send cargo and container data to the /loads endpoint and get a load plan back.

Prepare your Node.js project to make API calls:

  1. Initialize a Project: Run npm init -y in your terminal to create a package.json.
  2. Install Dependencies:
    • For Axios: npm install axios
    • For environment variables: npm install dotenv
    • Fetch API is built into Node.js (since v18), so no extra install is needed.
  3. Create a File: Make a file named index.js for your code.
  4. Setup .env: Add your API key as shown in Step 1.

Example package.json:

{
    "name": "cubemaster-api",
    "version": "1.0.0",
    "main": "index.js",
    "dependencies": {
        "axios": "^1.6.0",
        "dotenv": "^16.0.0"
    }
}

Assume your customer’s legacy database stores order/shipment data. You’ll need to extract this data (e.g., via SQL or an API) and map it to the CubeMaster request format.

Example Legacy Data (Pseudo-SQL):

SELECT item_code, length, width, height, weight, quantity 
FROM orders 
WHERE order_id = '12345';

Sample Legacy Data:

const legacyData = [
    { item_code: "ITEM001", length: 72, width: 30, height: 75, weight: 1002.45, quantity: 16 },
    { item_code: "ITEM002", length: 27.31, width: 37.5, height: 76.67, weight: 521.45, quantity: 28 }
];

Mapping to CubeMaster Format:

const cargoes = legacyData.map(item => ({
    Name: item.item_code,
    Length: item.length,
    Width: item.width,
    Height: item.height,
    Weight: item.weight,
    Qty: item.quantity,
    OrientationsAllowed: "OrientationsAll",
    TurnAllowedOnFloor: false,
    ColorKnownName: "Brown" // Add default or dynamic color
}));

This mapped data will be used in the API request in the next step.

Send the request to https://api.cubemaster.net/loads with authentication using the TokenID in headers.

Axios Example:
require('dotenv').config();
const axios = require('axios');

const apiUrl = 'https://api.cubemaster.net/loads';
const token = process.env.API_TOKEN;

const requestData = {
    "Title": "New Mixed Truck Load",
    "Description": "Hello Web API",
    "Cargoes": [
        {"Name": "ITEM001", "Length": 72, "Width": 30, "Height": 75, "Weight": 1002.45, "OrientationsAllowed": "OrientationsAll", "TurnAllowedOnFloor": false, "Qty": 16, "ColorKnownName": "Brown"},
        {"Name": "ITEM002", "Length": 27.31, "Width": 37.5, "Height": 76.67, "Weight": 521.45, "OrientationsAllowed": "OrientationsAll", "TurnAllowedOnFloor": false, "Qty": 28, "ColorKnownName": "Aqua"},
        {"Name": "SKU0005", "Length": 27.31, "Width": 9.5, "Height": 75.67, "Weight": 501.45, "OrientationsAllowed": "OrientationsAll", "TurnAllowedOnFloor": true, "Qty": 24, "ColorKnownName": "Beige"},
        {"Name": "SKU0005", "Qty": 23},
        {"Name": "SKU0008", "Qty": 34}
    ],
    "Containers": [
        {"VehicleType": "Dry", "Name": "53FT-Intermodal", "Length": 630, "Width": 98, "Height": 106, "ColorKnownName": "Blue"}
    ],
    "Rules": {
        "IsWeightLimited": true,
        "IsSequenceUsed": false,
        "FillDirection": "FrontToRear",
        "CalculationType": "MixLoad"
    }
};

axios.post(apiUrl, requestData, {
    headers: {
        'TokenID': token,
        'Content-Type': 'application/json'
    }
})
.then(response => {
    console.log('Success:', response.data);
})
.catch(error => {
    console.error('Error:', error.response ? error.response.data : error.message);
});
Fetch API Example:
require('dotenv').config();

const apiUrl = 'https://api.cubemaster.net/loads';
const token = process.env.API_TOKEN;

const requestData = {
    "Title": "New Mixed Truck Load",
    "Description": "Hello Web API",
    "Cargoes": [
        {"Name": "ITEM001", "Length": 72, "Width": 30, "Height": 75, "Weight": 1002.45, "OrientationsAllowed": "OrientationsAll", "TurnAllowedOnFloor": false, "Qty": 16, "ColorKnownName": "Brown"},
        {"Name": "ITEM002", "Length": 27.31, "Width": 37.5, "Height": 76.67, "Weight": 521.45, "OrientationsAllowed": "OrientationsAll", "TurnAllowedOnFloor": false, "Qty": 28, "ColorKnownName": "Aqua"},
        {"Name": "SKU0005", "Length": 27.31, "Width": 9.5, "Height": 75.67, "Weight": 501.45, "OrientationsAllowed": "OrientationsAll", "TurnAllowedOnFloor": true, "Qty": 24, "ColorKnownName": "Beige"},
        {"Name": "SKU0005", "Qty": 23},
        {"Name": "SKU0008", "Qty": 34}
    ],
    "Containers": [
        {"VehicleType": "Dry", "Name": "53FT-Intermodal", "Length": 630, "Width": 98, "Height": 106, "ColorKnownName": "Blue"}
    ],
    "Rules": {
        "IsWeightLimited": true,
        "IsSequenceUsed": false,
        "FillDirection": "FrontToRear",
        "CalculationType": "MixLoad"
    }
};

fetch(apiUrl, {
    method: 'POST',
    headers: {
        'TokenID': token,
        'Content-Type': 'application/json'
    },
    body: JSON.stringify(requestData)
})
.then(response => response.json())
.then(data => {
    console.log('Success:', data);
})
.catch(error => {
    console.error('Error:', error);
});

Request JSON: This matches the structure you provided, defining cargoes, containers, and rules.

The API returns a detailed JSON response. Here’s how to process it:

Axios Response Handling:
.then(response => {
    const data = response.data;
    if (data.status === 'succeed') {
        console.log('Load Built Successfully:', data.message);
        console.log('Calculation Time:', data.document.calculationTimeInSeconds, 'seconds');
        console.log('Total Pieces Loaded:', data.loadSummary.piecesLoaded);
        console.log('Volume Utilization:', data.filledContainers[0].loadSummary.volumeUtilization, '%');
        console.log('3D Diagram:', data.filledContainers[0].graphics.images.path3DDiagram);
    } else {
        console.error('Calculation Error:', data.calculationError);
    }
})
.catch(error => {
    console.error('Request Failed:', error.response?.data?.message || error.message);
});
Fetch Response Handling:
.then(data => {
    if (data.status === 'succeed') {
        console.log('Load Built Successfully:', data.message);
        console.log('Calculation Time:', data.document.calculationTimeInSeconds, 'seconds');
        console.log('Total Pieces Loaded:', data.loadSummary.piecesLoaded);
        console.log('Volume Utilization:', data.filledContainers[0].loadSummary.volumeUtilization, '%');
        console.log('3D Diagram:', data.filledContainers[0].graphics.images.path3DDiagram);
    } else {
        console.error('Calculation Error:', data.calculationError);
    }
})
.catch(error => {
    console.error('Request Failed:', error);
});

Response JSON (Sample):

{
    "status": "succeed",
    "message": "Engine created. 5 cargoes. 1 empty containers. Calculation started. Calculation ended. The load built successfully. The load saved to the cloud database.",
    "calculationError": "InvalidCargoSize",
    "document": {
        "title": "New Mixed Truck Load",
        "description": "Hello Web API",
        "calculationTimeInSeconds": 0.6152743,
        "createdBy": "CHANG@LOGEN.CO.KR",
        "createdAt": "2023-02-11T01:17:01.7392204+09:00"
    },
    "loadSummary": {
        "cargoesLoaded": 68,
        "piecesLoaded": 68,
        "volumeLoaded": 5261723.4606,
        "weightLoaded": 42674.59999999999
    },
    "filledContainers": [
        {
            "name": "#1 53FT-Intermodal",
            "loadSummary": {
                "volumeUtilization": 80.39990374424703,
                "weightLoaded": 42674.59999999999
            },
            "graphics": {
                "images": {
                    "path3DDiagram": "https://api.cubemaster.net/runtimes/b28413ca_51ed_44c9_b92e_13147363fd61.PNG"
                }
            }
        }
    ]
}

Use this data to display load details, utilization stats, or link to diagrams in your UI.

Ensure your API integration works smoothly by monitoring and debugging:

  • Console Logging: Add console.log statements to inspect request data and responses.
  • Error Handling: Check for errors in the catch block (e.g., 401 Unauthorized if TokenID is wrong).
  • Network Tools: Use browser DevTools (Network tab) or Postman to test the API manually.
  • Logging Library: Use winston or debug for production-grade logging:
    const winston = require('winston');
    const logger = winston.createLogger({
        level: 'info',
        format: winston.format.json(),
        transports: [new winston.transports.File({ filename: 'api.log' })]
    });
    
    logger.info('API Request Sent:', requestData);
    logger.error('API Error:', error.response?.data);
    
  • Validate Response: Check data.status and data.calculationError to handle partial failures.

Run your script with node index.js and review logs or console output for issues.