Standard shipping APIs give you a tracking barcode, but they don't tell your packers which box to choose or how to fit the items inside.
Leaving box selection to intuition leads to inconsistency. Packers might choose oversized boxes, inflating dimensional weight costs, or spend too much time testing different configurations.
This guide demonstrates how to use the BinSolver Python SDK to select the optimal shipping container and immediately generate a ZPL (Zebra Programming Language) label containing the packing list and instructions.
The Guesswork Problem
Without computed packing instructions, three main issues arise at the packing station:
- Oversized cartons: Excess volume increases shipping fees.
- Transit damage: Poorly packed items are more likely to shift and break.
- Throughput bottlenecks: Trial-and-error packing slows down fulfillment.
Generating ZPL Labels
BinSolver can generate printer-ready code alongside the packing solution. By adding label_format="zpl" to the request, the API returns a ZPL string compatible with Zebra thermal printers.
Implementation
This script defines inventory, creates an order, and saves the resulting ZPL labels to disk.
import os
from binsolver import BinSolver, PackRequest, Item, Bin
# Initialize the client
client = BinSolver(api_key="your_api_key_here")
# 1. Define your available box inventory
bins = [
Bin(id="small-box", w=10, h=8, d=6, max_weight=50, cost=0.50),
Bin(id="medium-box", w=12, h=10, d=8, max_weight=70, cost=0.75),
Bin(id="large-box", w=18, h=12, d=12, max_weight=100, cost=1.20)
]
# 2. The order items to pack
items = [
Item(id="widget-A", w=4, h=4, d=4, quantity=2, weight=1.5),
Item(id="long-part-B", w=8, h=2, d=2, quantity=1, weight=2.0)
]
# 3. Create request with ZPL label format
request = PackRequest(
items=items,
bins=bins,
objective="minCost",
label_format="zpl" # <--- Request ZPL output
)
print("Sending request to BinSolver API...")
try:
response = client.pack(request)
print(f"Success! Packed into {response.stats.bins_used} bin(s).")
for i, b in enumerate(response.bins):
print(f"--- Bin #{i+1} ({b.template_id}) ---")
print(f"Utilization: {b.utilization:.2%}")
# Save the ZPL code to a file
if b.label:
filename = f"label_bin_{i+1}.zpl"
with open(filename, "w") as f:
f.write(b.label)
print(f"ZPL Label saved to: {filename}")
print(f" (Preview content: {b.label[:30]}...)")
except Exception as e:
print(f"Error: {e}") The Output
The response includes a label field with the raw ZPL code:
^XA
^FO50,50^ADN,36,20^FDbin-1^FS
^FO50,100^BCN,100,Y,N,N^FDbin-1^FS
^FO50,250^ADN,18,10^FDTpl: small-box^FS
^FO50,300^ADN,18,10^FDItems: 3^FS
^FO50,350^ADN,18,10^FDWeight: 5.00^FS
^FO50,400^GB700,0,2^FS
^FO50,420^ADN,18,10^FDContents:^FS
^FO50,450^ADN,18,10^FD2 x widget-A^FS
^FO50,480^ADN,18,10^FD1 x long-part-B^FS
^XZThis label provides the packer with:
- Bin Template: The exact box size to use.
- Contents List: A checklist of items for this specific box.
- Weight: Calculated total weight for postage.
Testing ZPL
If you don't have a thermal printer, you can visualize the output by pasting the ZPL code into the Labelary Online Viewer.
Next Steps
You can extend this automation by triggering label generation via webhooks when an order enters your ERP, or by using the palletization feature to generate labels for LTL shipments.
Start optimizing fulfillment
Get your API key to start generating packing slips.