TCS Innovations Logo

API Reference

v2.1.0 • RESTful Architecture • JSON Encoded

Introduction

The TCS-i API is organized around REST. Our API has predictable resource-oriented URLs, accepts JSON-encoded request bodies, returns JSON-encoded responses, and uses standard HTTP response codes, authentication, and verbs.

Base URL: All API requests should be made to our primary integration gateway: https://api.tcs-innovations.com

Authentication

The TCS-i API uses API keys to authenticate requests. You can view and manage your API keys in your Customer Dashboard after subscribing via the Google Cloud Marketplace.

Authentication to the API is performed via the x-api-key HTTP header. All API requests must be made over HTTPS.

// Example Authentication Header
curl -X POST https://api.tcs-innovations.com/pack \
  -H "Content-Type: application/json" \
  -H "x-api-key: your_production_api_key_here"

POST

/pack

Computes a highly optimized 3D packing solution (cartonization) based on your provided inventory items, available bins, and specific objective targets.

Request Body

metadataoptionalobject

Custom metadata dictionary to be passed along with the packing request.

itemsrequiredarray of objects

The list of products to be packed. See the Item Data Model for property requirements.

binsoptional*array of objects

Required for standard packing. Can be omitted if objective is minimise_bounding_box.

objectiveoptionalstring

Defaults to minimise_bins. See Objectives model for full list.

constraintsoptionalobject

Defines physics rules: rotation logic, fragility limits, center of gravity checks, and forbidden adjacencies.

cost_modeloptionalobject

Used when objective is set to minimise_total_cost. Defines shipping base rates, per-kg rates, and DIM divisors to evaluate the most cost-effective packaging.

// POST /pack Payload Example
{
  "objective": "minimise_total_cost",
  "items": [
    { "id": "I-001", "length": 2.0, "width": 4.0, "height": 4.0, "weight": 1.5, "label": "electronics", "is_cylinder": false },
    { "id": "I-002", "length": 5.0, "width": 5.0, "height": 2.0, "weight": 0.5, "label": "accessories", "is_cylinder": true }
  ],
  "bins": [
    { "id": "B-001", "length": 10.0, "width": 10.0, "height": 10.0, "is_envelope": false, "fixed_cost": 2.0, "tare_weight": 0.2, "quantity": 2 }
  ],
  "constraints": {
    "rotation": true,
    "fragility": ["I-001"],
    "weight_distribution": {
      "max_per_layer": 10.0,
      "footprint": 5.0,
      "center_of_gravity": true,
      "min_support_ratio": 0.8
    },
    "forbidden_adjacency": [["electronics", "liquids"]],
    "priority": ["I-001"]
  },
  "cost_model": {
    "ship_base": 0.6,
    "ship_rate_per_kg": 1.1,
    "dim_divisor": 5000.0,
    "dunnage_cost_per_volume": 0.05
  }
}
// Response Example
{
  "solution": {
    "num_bins_used": 1,
    "bins": [
      {
        "id": "B-001",
        "length": 10.0, "width": 10.0, "height": 10.0,
        "items": [
          {
            "id": "I-001",
            "origin_dims": [2.0, 4.0, 4.0],
            "rotation_instruction": "perm(0, 1, 2)",
            "rotated_dims": [2.0, 4.0, 4.0],
            "position": [0.0, 0.0, 0.0],
            "is_cylinder": false
          },
          {
            "id": "I-002",
            "origin_dims": [5.0, 5.0, 2.0],
            "rotation_instruction": "perm(0, 2, 1)",
            "rotated_dims": [5.0, 2.0, 5.0],
            "position": [2.0, 0.0, 0.0],
            "is_cylinder": true
          }
        ]
      }
    ],
    "packed_item_ids": ["I-001", "I-002"],
    "unpacked_item_ids": []
  }
}

Packing Data Models

Objective Parameter

minimise_bins(Default) Packs all items into the absolute fewest number of provided bins.
minimise_unused_spaceSelects bins that leave the least empty volume (reduces dunnage).
maximise_itemsAttempts to fit as many items as possible into limited bins.
minimise_bin_costsOptimizes packing to minimize total bin material cost (`fixed_cost`).
minimise_total_costRequires cost_model object. Optimizes for cheapest shipping + material spend.
minimise_bounding_boxSynthesizes a custom bin to discover the absolute smallest cubic volume possible.
minimise_missing_heightGiven fixed base (length/width), find the minimum required height.

Constraints Object

rotationbooleanDefault true. Allows the engine to rotate items in 3D space.
fragilityarray of strArray of Item IDs. The engine will mathematically guarantee no other items are stacked on top of these.
weight_distributionobjectControls structural weight limits. Requires item weight. Subfields:
  • max_per_layer (float): limits total weight per horizontal layer.
  • footprint (float): limits vertical load per footprint/cell.
  • center_of_gravity (boolean): enforces stable center-of-gravity support.
  • min_support_ratio (float): requires a minimum supported base area fraction (0 to 1).
forbidden_adjacencyarray of arrPairs of Item labels that cannot touch. e.g. [["Food", "Chemicals"]]
priorityarray of strList of Item IDs that should be packed first if bin capacity is limited.
max_bin_limitintegerHard limit on the maximum number of bins the engine is allowed to use.

Cost Model Object

ship_basefloatBase shipping cost per used bin.
ship_rate_per_kgfloatCourier cost applied per kg (uses item weights + bin tare weight).
dim_divisorfloatDimensional weight divisor (e.g. 4000 or 5000). Set to 0 to disable DIM logic.
dunnage_cost_per_volumefloatPenalty cost applied per unit of unused volume space inside a packed bin.

Item Object

id *stringUnique identifier (e.g., SKU).
namestringOptional human-readable name for the item.
length/width/height *float > 0Physical dimensions of the item.
weightfloat >= 0Required if weight_distribution constraints apply.
labelstringCategory label used for forbidden_adjacency routing.
is_cylinderbooleanTriggers complex geometry nesting logic for circular items.
is_flexiblebooleanIndicates if the item is flexible/malleable.
can_use_envelopebooleanAllows the item to be packed into mailing envelopes/bags.

Bin Object

idstringUnique box/mailer ID.
namestringOptional human-readable name for the bin.
length/width/heightfloat > 0Internal dimensions of the packing container.
is_envelopebooleanIf true, algorithm treats L/W as flat malleable mailer dimensions.
fixed_costfloat >= 0Material cost, targeted by minimise_bin_costs.
tare_weightfloat >= 0Empty weight of the bin itself. Used in cost models.
quantityint >= 1Inventory limitation for this specific box size.

POST

/batch

Intelligently group pending orders into optimized picking batches. The macro-batching engine evaluates item locations, distance matrices, and order SLAs to generate the most efficient groupings, maximizing picker throughput while preventing SLA breaches.

Request Body

active_poolrequiredarray of BatchOrder

The current active pool of orders to evaluate for release.

candidate_poolrequiredarray of BatchOrder

Additional orders that can be pulled into the active pool to optimize routing.

distance_matrixrequiredobject

A 2D dictionary mapping location IDs to other location IDs with their respective travel distances.

pack_station_idrequiredstring

The destination ID where the batched items will be dropped off for packing.

target_release_countoptionalinteger

The target number of orders to release in this batch. Defaults to 500.

sla_weight / age_weightoptionalfloat

Tuning parameters for the optimization algorithm. `sla_weight` (default 2.0) determines distance sacrifice for SLA, `age_weight` (default 0.1) prevents black-hole scenarios.

// POST /batch Request Example
{
  "pack_station_id": "PACK-ZONE-A",
  "target_release_count": 2,
  "sla_weight": 2.5,
  "active_pool": [
    {
      "order_id": "ORD-5541",
      "total_volume": 12.5,
      "sla_priority": 4,
      "age_minutes": 45.0,
      "items": [
        { "item_id": "IPHONE-15", "location_id": "A-04-02" }
      ]
    }
  ],
  "candidate_pool": [
    {
      "order_id": "ORD-5542",
      "total_volume": 5.0,
      "sla_priority": 2,
      "age_minutes": 10.0,
      "items": [
        { "item_id": "AIRPODS", "location_id": "A-04-05" }
      ]
    }
  ],
  "distance_matrix": {
    "A-04-02": { "A-04-05": 3.5, "PACK-ZONE-A": 40.0 },
    "A-04-05": { "A-04-02": 3.5, "PACK-ZONE-A": 38.0 }
  }
}
// Response Example
{
  "released_order_ids": [
    "ORD-5541",
    "ORD-5542"
  ],
  "route_footprint": [
    "A-04-02",
    "A-04-05",
    "PACK-ZONE-A"
  ]
}

Batching Data Models

BatchOrder Object (Request)

order_id *stringYour internal unique identifier for the customer order.
items *array of BatchItemList of individual products that need to be picked for this order.
total_volume *floatTotal physical volume size of the order's items.
sla_priorityintegerSLA rating from 1 (Low) to 5 (Urgent). Default is 1.
age_minutesfloatTime elapsed in queue. Used to trigger black-hole effect priorities.

BatchItem Object (Request)

item_id *stringThe identifier (SKU) for the product.
location_id *stringThe physical warehouse bin/aisle location. Used heavily for route optimization.

MacroBatchResponse Object (Returned in Response)

released_order_idsarray of stringsList of the optimal order IDs selected to be released into a batch.
route_footprintarray of stringsSequential list of location IDs outlining the expected physical route the picker will take.

POST

/pick

Transforms a grouped batch of orders into a highly optimized physical routing path. The algorithm considers warehouse topology, one-way aisles, and start/end positions to minimize picker travel distance and provide a sequenced step-by-step picking list.

Request Body

warehouse_idrequiredstring

The unique identifier of the fulfillment center where the picking will take place.

batch_idrequiredstring

The ID of the grouped batch (generated via the /batch endpoint) that needs to be routed.

starting_locationoptionalstring

The physical ID of where the picker begins their route (e.g., "ZONE-A-ENTRY").

ending_locationoptionalstring

The physical ID of where the picker must drop off the completed batch (e.g., "PACK-STATION-1").

cart_capacityoptionalinteger

The maximum number of discrete items the picking cart can physically hold.

// POST /pick Request Example
{
  "warehouse_id": "wh_uk_london_01",
  "batch_id": "bat_8x7d6c5b4a",
  "starting_location": "ZONE-A-ENTRY",
  "ending_location": "PACK-STATION-1",
  "cart_capacity": 40
}
// Response Example
{
  "route_id": "rt_9988776655",
  "batch_id": "bat_8x7d6c5b4a",
  "estimated_time_seconds": 420,
  "total_distance_meters": 115.5,
  "pick_path": [
    {
      "step_sequence": 1,
      "location_id": "A-04-02",
      "action": "pick",
      "items": [
        { "sku": "IPHONE-15-PRO", "quantity": 1, "order_ref": "ORD-5541" }
      ]
    },
    {
      "step_sequence": 2,
      "location_id": "A-04-05",
      "action": "pick",
      "items": [
        { "sku": "AIRPODS-PRO", "quantity": 2, "order_ref": "ORD-5542" }
      ]
    },
    {
      "step_sequence": 3,
      "location_id": "PACK-STATION-1",
      "action": "dropoff",
      "items": []
    }
  ]
}

Picking Data Models

Pick Path Step Object (Returned in Response)

step_sequenceintegerThe numerical order in which the picker should visit this location.
location_idstringThe physical warehouse bin, aisle, or station to navigate to.
actionstringInstruction for the picker: "pick" or "dropoff".
itemsarray of Task ObjectsThe list of items to interact with at this specific location.

Task Object (Returned in Response)

skustringThe specific Stock Keeping Unit to pull from the shelf.
quantityintegerThe number of units of this SKU to pick.
order_refstringThe order this item is assigned to, allowing sorting directly into order-specific cart slots.

POST

/ship

Rate-shops across your connected carrier network in real-time. By leveraging the exact 3D dimensions (DIM weight) and actual weight of your parcels, the engine instantly selects the lowest-cost shipping label that meets your requested delivery SLA.

Request Body

shipment_refoptionalstring

Your internal order or shipment ID. Passed back in the response and on webhooks.

destination_addressrequiredAddress Object

The final delivery destination for the shipment.

origin_addressoptionalAddress Object

Overrides the default fulfillment center address configured in your dashboard.

parcelsrequiredarray of Parcel Objects

List of packages in this shipment, including dimensions and physical weights.

delivery_slaoptionalstring or integer

Filters rates to match the promised SLA (e.g., "next_day" or an exact integer like 3). Defaults to standard.

weight_unitoptionalstring

Global unit for weights. Accepts "kg" or "lb". Defaults to kg.

dim_unitoptionalstring

Global unit for dimensions. Accepts "cm" or "in". Defaults to cm.

carrier_accountsoptionalarray of strings

Limits the algorithm to query specific pre-configured carrier accounts (e.g., "acc_dpd_uk").

// POST /ship Request Example
{
  "shipment_ref": "ORD-88192-A",
  "destination_address": {
    "name": "John Doe",
    "street1": "10 Downing Street",
    "city": "London",
    "state": "Greater London",
    "postcode": "SW1A 2AA",
    "country": "GB"
  },
  "origin_address": {
    "name": "London Hub",
    "street1": "Unit 4, Prologis Park",
    "city": "London",
    "state": "Greater London",
    "postcode": "UB7 9FN",
    "country": "GB"
  },
  "parcels": [
    {
      "length": 30.0,
      "width": 25.0,
      "height": 20.0,
      "weight": 3.2,
      "declared_value": 45.00
    }
  ],
  "delivery_sla": "next_day",
  "carrier_accounts": ["acc_dpd_uk", "acc_rmail"]
}
// Response Example
{
  "shipment_id": "shp_9x8f7a6b5c4d3e2f1",
  "shipment_ref": "ORD-88192-A",
  "status": "label_created",
  "selected_rate": {
    "carrier": "DPD",
    "service": "DPD Next Day Parcel",
    "cost": 4.50,
    "currency": "GBP",
    "estimated_delivery_date": "2026-03-09T18:00:00Z"
  },
  "tracking_number": "15502938492",
  "tracking_url": "https://track.dpd.co.uk/15502938492",
  "label_format": "zpl",
  "label_base64": "XlhB..."
}

Shipping Data Models

Parcel Object

length *floatExternal length of the packed box (cm or in).
width *floatExternal width of the packed box (cm or in).
height *floatExternal height of the packed box (cm or in).
weight *floatTotal physical scale weight of the parcel (kg or lb).
declared_valuefloatMonetary value for international customs or carrier insurance.

Address Object

name *stringRecipient's full name or company name.
street1 *stringPrimary street address (e.g., "10 Downing Street").
city *stringCity or town.
statestringState, province, or region (e.g., "Greater London", "CA").
postcode *stringPostal or ZIP code. Crucial for exact transit matrix matching.
country *stringISO 3166-1 alpha-2 country code (e.g., "GB", "US").

Rate Object (Returned in Response)

carrierstringThe carrier that provided the winning rate (e.g., "DPD").
servicestringThe specific service level purchased (e.g., "DPD Next Day Parcel").
costfloatThe final negotiated cost for this shipment.
currencystringISO 4217 currency code (e.g., "GBP", "USD").
estimated_delivery_datestringISO 8601 timestamp representing the carrier's delivery commitment.

POST

/slot

Sub-200ms Dynamic Slotting Engine with Smart Cascade & Fast-Track. Intercepts inbound WMS dock scans in real-time. Calculates global SKU velocity against rolling hourly picks to dynamically route items to the Golden, Silver, or Dead Zones.

Request Body

skurequiredSlotSKU Object

Details about the incoming item, including its rolling hourly pick history for velocity calculation.

warehouse_contextrequiredSlotWarehouseContext Object

Thresholds for zone classifications and multi-bin drain support rules.

bin_optionsrequiredSlotBinOptions Object

The current home bin (if any) and available empty bins for the engine to consider.

// POST /slot Payload Example
{
  "sku": {
    "sku_id": "SKU-992-BLK",
    "quantity_to_move": 120,
    "unit_volume": 1.5,
    "rolling_hourly_picks": [10, 15, 8, 45]
  },
  "warehouse_context": {
    "golden_zone_velocity_threshold_per_hour": 30.0,
    "silver_zone_velocity_threshold_per_hour": 15.0,
    "multi_bin_drain_supported": true
  },
  "bin_options": {
    "current_home_bin": {
      "bin_id": "RES-09-02",
      "zone": "Dead Zone",
      "available_volume": 100.0,
      "current_quantity_left": 50
    },
    "empty_bins": [
      {
        "bin_id": "A-04-12",
        "zone": "Silver Zone",
        "available_volume": 500.0,
        "current_quantity_left": 0
      }
    ]
  }
}
// Response Example
{
  "meta": {
    "decision_code": "UPGRADE_CONSOLIDATE",
    "status": 200
  },
  "allocations": [
    {
      "bin_id": "A-04-12",
      "role": "new_primary",
      "action": "putaway",
      "inbound_putaway_qty": 120,
      "sweep_in_qty": 50,
      "sweep_out_qty": 0,
      "total_expected_qty": 170
    },
    {
      "bin_id": "RES-09-02",
      "role": "old_home",
      "action": "sweep_out",
      "inbound_putaway_qty": 0,
      "sweep_in_qty": 0,
      "sweep_out_qty": 50,
      "total_expected_qty": 0
    }
  ],
  "telemetry": {
    "trend_classification": "FAST_TRACK_SILVER",
    "calculated_hourly_rate": 22.6,
    "golden_threshold_applied": 30.0
  }
}

Slotting Data Models

SlotSKU Object (Request)

sku_idstringUnique identifier for the incoming item.
quantity_to_moveintegerNumber of units arriving at the dock.
unit_volumefloatThe cubic volume of a single unit of this SKU.
rolling_hourly_picksarray of integersChronological array of picks per hour used to compute sustained vs. immediate velocity rates.

SlotWarehouseContext Object (Request)

golden_zone_velocity_threshold_per_hourfloatMinimum hourly picks required to classify an item into the high-priority Golden Zone.
silver_zone_velocity_threshold_per_hourfloatMinimum hourly picks required for the Silver Zone.
multi_bin_drain_supportedbooleanIf true, allows system to support "systemic drain" downgrades instead of forcing physical sweep-outs.

SlotBin & SlotBinOptions Objects (Request)

bin_idstringIdentifier for the physical bin location.
zonestringMust match "Golden Zone", "Silver Zone", or "Dead Zone".
available_volumefloatRemaining physical space in the bin.
current_quantity_leftintegerAmount of the SKU currently existing in this bin (Defaults to 0 for empty bins).

SlotMeta Object (Returned in Response)

decision_codestringResulting logic path (e.g., "MAINTAIN_TOPUP", "UPGRADE_CONSOLIDATE", "DOWNGRADE_SWEEP").
statusintegerHTTP-style status code representing success (200) or failure (400 if no bins fit).

SlotAllocation Object (Returned in Response)

bin_idstringThe optimal WMS physical location for this action.
rolestringIndicates if the bin is "primary", "new_primary", or "old_home".
actionstringTask directive (e.g., "putaway", "sweep_out", "systemic_drain").
inbound_putaway_qtyintegerAmount of new inbound stock to route to this bin.
sweep_in_qty / sweep_out_qtyintegerUnits moved between an old home bin and a new primary bin during consolidation.
total_expected_qtyintegerExpected total inventory in this bin after the directed actions are completed.

SlotTelemetry Object (Returned in Response)

trend_classificationstringSystem evaluation of pick velocity (e.g., "FAST_TRACK_SILVER", "VIRAL_SPIKE").
calculated_hourly_ratefloatThe sustained average picks-per-hour calculated by the engine based on recent data.
golden_threshold_appliedfloatThe context threshold value utilized during this calculation.

Telemetry & Preferences

We use essential cookies to secure your session and analytics to optimize performance. Read our Privacy Policy.

Analytics Tracking
Personalized Content
Targeted Ads