Copy-paste this comprehensive prompt into ChatGPT, Claude Code, Cursor, or any AI coding assistant to quickly integrate with the Perseuss API.
# Perseuss Cartonization API - Complete Integration Guide
You are integrating with the **Perseuss Cartonization API**, a 3D bin-packing/cartonization service that optimizes how items are packed into boxes, mailers, and other containers.
## API Overview
| Environment | URL | API Key |
|-------------|-----|---------|
| Production | `https://v2.cartonizationapi.com/post-cartonization` | Your API key |
| Demo Playground | `https://cartonizationapi.com/api/demo/cartonize` | Website-managed demo session |
- **Method:** POST
- **Content-Type:** application/json
## Authentication
```
Authorization: Bearer YOUR_API_KEY
```
**Environment + API Key Rules:**
- Use the production endpoint for integrations with your own API key.
- Use the website playground for demo traffic; the site proxies requests with a signed demo session.
---
## Request Schema
### Top-Level Request Object
| Field | Type | Required | Default | Description |
|-------|------|----------|---------|-------------|
| `items` | `Item[]` | **Yes** | - | Array of items to pack |
| `allowed_bins` | `Bin[]` | **Yes** | - | Array of available bin/box types |
| `objective_function` | `string` | No | `"min_bin_volume"` | Optimization objective |
| `max_number_of_bins` | `integer` | No | Auto | Maximum bins to use |
| `max_runtime_seconds` | `number` | No | `30` | Max solver runtime |
| `item_to_item_incompatibility` | `string[][]` | No | `[]` | Item pairs that can't share a bin |
| `bin_to_items_incompatibility` | `object` | No | `{}` | Map of bin_id to incompatible item_ids |
### Item Object
| Field | Type | Required | Default | Description |
|-------|------|----------|---------|-------------|
| `item_id` | `string` | **Yes** | - | Unique item identifier |
| `length` | `number` | **Yes** | - | Item length |
| `width` | `number` | **Yes** | - | Item width |
| `height` | `number` | **Yes** | - | Item height |
| `weight` | `number` | **Yes** | - | Item weight |
| `quantity` | `integer` | **Yes** | - | Number of this item to pack |
| `item_type` | `string` | No | `"solid"` | `"solid"` or `"squishable"` |
| `allowed_orientations` | `string[]` | No | All | Allowed rotation orientations |
### Bin Object
| Field | Type | Required | Default | Description |
|-------|------|----------|---------|-------------|
| `bin_id` | `string` | **Yes** | - | Unique bin identifier |
| `length` | `number` | **Yes** | - | Bin length |
| `width` | `number` | **Yes** | - | Bin width |
| `height` | `number` | **Yes** | - | Bin height |
| `bin_type` | `string` | No | `"carton_box"` | `"carton_box"`, `"mailer"`, or `"pallet"` |
| `max_weight` | `number` | No | `1000000` | Maximum weight capacity |
| `max_fill_rate` | `number` | No | `1.0` | Maximum fill rate (0.0-1.0) |
| `bin_cost` | `number` | No | `0.0` | Cost of using this bin |
| `bin_weight` | `number` | No | `0.0` | Empty bin weight |
| `max_height` | `number` | No | - | Maximum stack height for pallets (replaces height) |
| `min_support_ratio` | `number` | No | `1.0` | Minimum bottom-surface support ratio for pallet items (0-1) |
### Objective Functions
| Value | Description |
|-------|-------------|
| `"min_bin_volume"` | Minimize total volume of used bins (default) |
| `"min_bin_count"` | Minimize number of bins used |
| `"min_bin_cost"` | Minimize total cost of used bins |
### Orientation Codes
| Code | Meaning | Use Case |
|------|---------|----------|
| `LWH` | Original (Length-Width-Height up) | Default |
| `WLH` | Rotated 90° on vertical axis | |
| `HLW` | Height becomes length | Laying flat |
| `HWL` | Height becomes width | Laying flat |
| `LHW` | Length stays, swap W/H | On side |
| `WHL` | Width stays, swap L/H | On side |
**Keep upright:** `["LWH", "WLH"]` - only rotate around vertical axis
### Item Types
| Type | Description | Behavior |
|------|-------------|----------|
| `solid` | Rigid items (boxes, electronics) | Fixed dimensions, rotation only |
| `squishable` | Flexible items (clothing, plush) | Can deform while preserving volume |
### Bin Types
| Type | Description | Behavior |
|------|-------------|----------|
| `carton_box` | Rigid containers | Fixed dimensions |
| `mailer` | Flexible containers (poly mailers) | Can reshape while preserving surface area |
| `pallet` | Open-top platforms | Uses max_height for stack limit, supports min_support_ratio |
---
## Response Schema
### Success Response (200)
| Field | Type | Description |
|-------|------|-------------|
| `status` | `string` | `"success"` |
| `request_id` | `string` | Unique request ID for debugging |
| `runtime_ms` | `number` | Time spent in the optimization solver (ms) |
| `total_runtime_ms` | `number` | Total API request time (ms) |
| `packed_bins` | `PackedBin[]` | Array of packed bins with items |
### PackedBin Object
| Field | Type | Description |
|-------|------|-------------|
| `bin_id` | `string` | ID of the bin type used |
| `bin_type` | `string` | `"carton_box"`, `"mailer"`, or `"pallet"` |
| `input_dimensions` | `Dimensions` | Original bin dimensions from the request |
| `output_dimensions` | `Dimensions` | Effective bin dimensions used by the solver |
| `volume_utilization` | `number` | Volume utilization (0.0 - 1.0) |
| `total_weight` | `number` | Total weight of bin + items |
| `visualization_id` | `string` | ID used to load the interactive 3D visualization |
| `pallet_metrics` | `PalletMetrics` | Pallet-specific metrics (only present for pallet bins) |
| `item_placements` | `ItemPlacement[]` | Detailed solver item placements |
### ItemPlacement Object
| Field | Type | Description |
|-------|------|-------------|
| `item_id` | `string` | ID of the item |
| `output_dimensions` | `Dimensions` | Placed item dimensions |
| `min_coordinates` | `[x, y, z]` | Minimum occupied coordinates |
| `max_coordinates` | `[x, y, z]` | Maximum occupied coordinates |
| `was_deformed` | `boolean` | True if squishable item was deformed |
---
## Code Examples
### Python
```python
import requests
API_URL = "https://v2.cartonizationapi.com/post-cartonization"
API_KEY = "YOUR_API_KEY"
def cartonize(items, bins, objective="min_bin_count"):
payload = {
"max_runtime_seconds": 30,
"objective_function": objective,
"allowed_bins": bins,
"items": items
}
response = requests.post(
API_URL,
json=payload,
headers={
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}
)
return response.json()
# Example usage
bins = [
{"bin_id": "box_12x12x12", "length": 12, "width": 12, "height": 12, "bin_cost": 1.00}
]
items = [
{"item_id": "product_a", "quantity": 5, "length": 6, "width": 4, "height": 3, "weight": 2}
]
result = cartonize(items, bins)
if result["status"] == "success":
print(f"Packed into {len(result['packed_bins'])} bins")
for bin in result["packed_bins"]:
print(f" {bin['bin_id']}: {len(bin['item_placements'])} items, {bin['volume_utilization']*100:.1f}% full")
print(f" Visualization ID: {bin['visualization_id']}")
```
### Java
```java
import java.net.http.*;
import java.net.URI;
public class PerseussClient {
private static final String API_URL = "https://v2.cartonizationapi.com/post-cartonization";
private final String apiKey;
private final HttpClient client;
public PerseussClient(String apiKey) {
this.apiKey = apiKey;
this.client = HttpClient.newHttpClient();
}
public String cartonize(String jsonPayload) throws Exception {
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(API_URL))
.header("Authorization", "Bearer " + apiKey)
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(jsonPayload))
.build();
HttpResponse<String> response = client.send(request,
HttpResponse.BodyHandlers.ofString());
return response.body();
}
public static void main(String[] args) throws Exception {
PerseussClient client = new PerseussClient("YOUR_API_KEY");
String payload = """
{
"max_runtime_seconds": 30,
"objective_function": "min_bin_count",
"allowed_bins": [
{"bin_id": "box_12x12x12", "length": 12, "width": 12, "height": 12}
],
"items": [
{"item_id": "product_a", "quantity": 5, "length": 6, "width": 4, "height": 3, "weight": 2}
]
}
""";
String result = client.cartonize(payload);
System.out.println(result);
}
}
```
### cURL
```bash
curl -X POST "https://v2.cartonizationapi.com/post-cartonization" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"max_runtime_seconds": 30,
"objective_function": "min_bin_count",
"allowed_bins": [
{"bin_id": "box_12x12x12", "length": 12, "width": 12, "height": 12, "bin_cost": 1.00}
],
"items": [
{"item_id": "product_a", "quantity": 5, "length": 6, "width": 4, "height": 3, "weight": 2}
]
}'
```
### TypeScript/JavaScript
```typescript
interface CartonizationRequest {
items: Item[];
allowed_bins: Bin[];
objective_function?: 'min_bin_volume' | 'min_bin_count' | 'min_bin_cost';
max_number_of_bins?: number;
max_runtime_seconds?: number;
item_to_item_incompatibility?: string[][];
bin_to_items_incompatibility?: Record<string, string[]>;
}
interface Item {
item_id: string;
length: number;
width: number;
height: number;
weight: number;
quantity: number;
item_type?: 'solid' | 'squishable';
allowed_orientations?: ('LWH' | 'LHW' | 'WLH' | 'WHL' | 'HLW' | 'HWL')[];
}
interface Bin {
bin_id: string;
length: number;
width: number;
height: number;
max_weight?: number;
max_fill_rate?: number;
bin_cost?: number;
bin_weight?: number;
bin_type?: 'carton_box' | 'mailer' | 'pallet';
max_height?: number;
min_support_ratio?: number;
}
const API_URL = "https://v2.cartonizationapi.com/post-cartonization";
async function cartonize(request: CartonizationRequest, apiKey: string) {
const response = await fetch(API_URL, {
method: "POST",
headers: {
"Authorization": `Bearer ${apiKey}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
max_runtime_seconds: 30,
...request,
}),
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
return response.json();
}
// Example usage
const result = await cartonize({
items: [
{ item_id: "product_a", quantity: 5, length: 6, width: 4, height: 3, weight: 2 }
],
allowed_bins: [
{ bin_id: "box_12x12x12", length: 12, width: 12, height: 12, bin_cost: 1.0 }
],
objective_function: "min_bin_count",
}, "YOUR_API_KEY");
console.log(`Packed into ${result.packed_bins.length} bins`);
```
---
## Common Use Cases & Examples
### 1. Basic Packing (Single Bin Type)
```json
{
"max_runtime_seconds": 30,
"allowed_bins": [
{"bin_id": "standard_12x12x12", "length": 12, "width": 12, "height": 12}
],
"items": [
{"item_id": "hardcover_book", "quantity": 5, "length": 8, "width": 6, "height": 2, "weight": 24},
{"item_id": "spiral_notebook", "quantity": 3, "length": 10, "width": 7, "height": 1, "weight": 8}
]
}
```
### 2. Multiple Bin Sizes (Cost Optimization)
```json
{
"max_runtime_seconds": 30,
"objective_function": "min_bin_cost",
"allowed_bins": [
{"bin_id": "small", "length": 8, "width": 8, "height": 8, "bin_cost": 0.50},
{"bin_id": "medium", "length": 12, "width": 12, "height": 12, "bin_cost": 1.00},
{"bin_id": "large", "length": 18, "width": 18, "height": 18, "bin_cost": 2.00}
],
"items": [
{"item_id": "widget_small", "quantity": 10, "length": 5, "width": 5, "height": 5, "weight": 32},
{"item_id": "widget_large", "quantity": 5, "length": 7, "width": 7, "height": 7, "weight": 48}
]
}
```
### 3. Minimize Number of Bins
```json
{
"max_runtime_seconds": 30,
"objective_function": "min_bin_count",
"allowed_bins": [
{"bin_id": "small_bin", "length": 10, "width": 10, "height": 10, "bin_cost": 0.50},
{"bin_id": "large_bin", "length": 20, "width": 20, "height": 20, "bin_cost": 2.00}
],
"items": [
{"item_id": "gadget", "quantity": 12, "length": 8, "width": 8, "height": 8, "weight": 16}
]
}
```
### 4. Weight-Limited Bins
```json
{
"max_runtime_seconds": 30,
"objective_function": "min_bin_count",
"allowed_bins": [
{"bin_id": "reinforced_box", "length": 15, "width": 15, "height": 15, "max_weight": 50.0, "bin_cost": 1.50}
],
"items": [
{"item_id": "metal_part", "quantity": 8, "length": 6, "width": 6, "height": 6, "weight": 12},
{"item_id": "steel_bracket", "quantity": 10, "length": 4, "width": 4, "height": 2, "weight": 5}
]
}
```
### 5. Fragile Items (Partial Fill for Cushioning)
```json
{
"max_runtime_seconds": 30,
"allowed_bins": [
{"bin_id": "cushioned_box", "length": 16, "width": 16, "height": 16, "max_fill_rate": 0.60}
],
"items": [
{"item_id": "wine_bottle", "quantity": 6, "length": 4, "width": 4, "height": 12, "weight": 3}
]
}
```
### 6. Keep Items Upright (Vases, Bottles)
```json
{
"max_runtime_seconds": 30,
"allowed_bins": [
{"bin_id": "tall_box", "length": 12, "width": 12, "height": 20}
],
"items": [
{"item_id": "ceramic_vase", "quantity": 4, "length": 5, "width": 5, "height": 15, "weight": 3, "allowed_orientations": ["LWH", "WLH"]}
]
}
```
### 7. Keep Items Flat (Pizzas, Artwork)
```json
{
"max_runtime_seconds": 30,
"allowed_bins": [
{"bin_id": "flat_carrier", "length": 20, "width": 20, "height": 12}
],
"items": [
{"item_id": "frozen_pizza", "quantity": 6, "length": 14, "width": 14, "height": 2, "weight": 2.5, "allowed_orientations": ["LWH", "WLH"]}
]
}
```
### 8. Squishable Clothing in Poly Mailers
```json
{
"max_runtime_seconds": 30,
"objective_function": "min_bin_count",
"allowed_bins": [
{"bin_id": "poly-mailer", "bin_type": "mailer", "length": 15, "width": 15, "height": 4, "bin_cost": 0.5}
],
"items": [
{"item_id": "cotton-tshirt", "item_type": "squishable", "quantity": 3, "length": 12, "width": 10, "height": 2, "weight": 0.4}
]
}
```
### 9. Mixed Solid & Squishable Items
```json
{
"max_runtime_seconds": 30,
"objective_function": "min_bin_count",
"allowed_bins": [
{"bin_id": "shipping-box", "length": 18, "width": 14, "height": 12, "bin_cost": 1.50}
],
"items": [
{"item_id": "hardcover-book", "item_type": "solid", "quantity": 2, "length": 9, "width": 6, "height": 2, "weight": 2},
{"item_id": "cotton-tshirt", "item_type": "squishable", "quantity": 4, "length": 10, "width": 8, "height": 2, "weight": 0.4}
]
}
```
### 10. Incompatible Items (Hazmat/Separation)
```json
{
"max_runtime_seconds": 30,
"objective_function": "min_bin_count",
"allowed_bins": [
{"bin_id": "storage_box", "length": 20, "width": 20, "height": 20}
],
"items": [
{"item_id": "bleach", "quantity": 3, "length": 4, "width": 4, "height": 10, "weight": 4},
{"item_id": "ammonia", "quantity": 3, "length": 4, "width": 4, "height": 10, "weight": 4},
{"item_id": "dish_soap", "quantity": 5, "length": 3, "width": 3, "height": 8, "weight": 1}
],
"item_to_item_incompatibility": [["bleach", "ammonia"]]
}
```
### 11. Bin Restrictions (Cold Chain)
```json
{
"max_runtime_seconds": 30,
"objective_function": "min_bin_cost",
"allowed_bins": [
{"bin_id": "insulated", "length": 15, "width": 15, "height": 15, "bin_cost": 2.50},
{"bin_id": "standard", "length": 15, "width": 15, "height": 15, "bin_cost": 0.75}
],
"items": [
{"item_id": "frozen_meal", "quantity": 4, "length": 8, "width": 6, "height": 3, "weight": 1.5},
{"item_id": "canned_soup", "quantity": 6, "length": 4, "width": 4, "height": 5, "weight": 1.25}
],
"bin_to_items_incompatibility": {"standard": ["frozen_meal"]}
}
```
### 12. E-commerce Fulfillment (Full Example)
```json
{
"max_runtime_seconds": 30,
"objective_function": "min_bin_cost",
"allowed_bins": [
{"bin_id": "poly_mailer_small", "bin_type": "mailer", "length": 10, "width": 8, "height": 4, "max_weight": 5.0, "bin_cost": 0.35},
{"bin_id": "poly_mailer_medium", "bin_type": "mailer", "length": 14, "width": 10, "height": 6, "max_weight": 15.0, "bin_cost": 0.65},
{"bin_id": "corrugated_large", "bin_type": "carton_box", "length": 18, "width": 14, "height": 10, "max_weight": 30.0, "bin_cost": 1.25}
],
"items": [
{"item_id": "phone_case", "item_type": "solid", "quantity": 2, "length": 6, "width": 4, "height": 1, "weight": 0.2},
{"item_id": "tshirt_folded", "item_type": "squishable", "quantity": 3, "length": 10, "width": 8, "height": 1, "weight": 0.4},
{"item_id": "water_bottle", "item_type": "solid", "quantity": 2, "length": 3, "width": 3, "height": 10, "weight": 0.75, "allowed_orientations": ["LWH", "WLH", "HLW", "HWL"]}
]
}
```
---
## Example Response
```json
{
"status": "success",
"request_id": "xK9mN2pQr4",
"runtime_ms": 1523.45,
"total_runtime_ms": 1687.32,
"packed_bins": [
{
"bin_index": 0,
"bin_id": "box-medium",
"bin_type": "carton_box",
"input_dimensions": {"length": 30, "width": 25, "height": 20},
"output_dimensions": {"length": 30, "width": 25, "height": 20},
"volume_utilization": 0.72,
"total_weight": 8.5,
"visualization_id": "abc123",
"item_placements": [
{
"item_index": 0,
"item_id": "widget-001",
"output_dimensions": {"length": 10, "width": 8, "height": 6},
"min_coordinates": [0, 0, 0],
"max_coordinates": [10, 8, 6],
"was_deformed": false
},
{
"item_index": 1,
"item_id": "sweater-blue",
"output_dimensions": {"length": 10, "width": 8, "height": 6},
"min_coordinates": [1, 10, 0],
"max_coordinates": [11, 18, 6],
"was_deformed": true
}
]
}
]
}
```
---
## Error Handling
### Authentication Error (401)
```json
{"status_code": 401, "error_message": "Invalid or missing API key"}
```
### Demo Playground Access
```json
{"error": "Missing demo session verification"}
```
### Solver Failure
```json
{"status": "fail", "request_id": "abc123", "packed_bins": [], "error": "Could not find valid packing"}
```
---
## Important Notes
1. **Units are implicit** - Use consistent units across all dimensions and weights
2. **Visualization IDs** - Each packed bin includes a `visualization_id` for 3D viewing
3. **Squishable items** - Items with `item_type: "squishable"` can compress while preserving volume. Check `was_deformed: true`
4. **Mailer bins** - Bins with `bin_type: "mailer"` can reshape. Output dimensions may differ from input
5. **Pallet bins** - Bins with `bin_type: "pallet"` use `max_height` instead of `height`. Response includes `pallet_metrics` with stack height utilization
6. **Coordinate system** - Origin `[0,0,0]` is at the bin corner; placements expose min/max coordinates
---
## Resources
- **API Playground:** https://cartonizationapi.com/sandbox
- **Documentation:** https://cartonizationapi.com/docs
- **Book a Demo:** https://calendly.com/try-perseuss/30min
You are integrating with the Perseuss Cartonization API, a 3D bin-packing/cartonization service that optimizes how items are packed into boxes, mailers, and other containers.
| Environment | URL | API Key |
|---|---|---|
| Production | https://v2.cartonizationapi.com/post-cartonization | Your API key |
| Demo Playground | https://cartonizationapi.com/api/demo/cartonize | Website-managed demo session |
Authorization: Bearer YOUR_API_KEYEnvironment + API Key Rules:
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
items | Item[] | Yes | - | Array of items to pack |
allowed_bins | Bin[] | Yes | - | Array of available bin/box types |
objective_function | string | No | "min_bin_volume" | Optimization objective |
max_number_of_bins | integer | No | Auto | Maximum bins to use |
max_runtime_seconds | number | No | 30 | Max solver runtime |
item_to_item_incompatibility | string[][] | No | [] | Item pairs that can't share a bin |
bin_to_items_incompatibility | object | No | {} | Map of bin_id to incompatible item_ids |
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
item_id | string | Yes | - | Unique item identifier |
length | number | Yes | - | Item length |
width | number | Yes | - | Item width |
height | number | Yes | - | Item height |
weight | number | Yes | - | Item weight |
quantity | integer | Yes | - | Number of this item to pack |
item_type | string | No | "solid" | "solid" or "squishable" |
allowed_orientations | string[] | No | All | Allowed rotation orientations |
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
bin_id | string | Yes | - | Unique bin identifier |
length | number | Yes | - | Bin length |
width | number | Yes | - | Bin width |
height | number | Yes | - | Bin height |
bin_type | string | No | "carton_box" | "carton_box", "mailer", or "pallet" |
max_weight | number | No | 1000000 | Maximum weight capacity |
max_fill_rate | number | No | 1.0 | Maximum fill rate (0.0-1.0) |
bin_cost | number | No | 0.0 | Cost of using this bin |
bin_weight | number | No | 0.0 | Empty bin weight |
max_height | number | No | - | Maximum stack height for pallets (replaces height) |
min_support_ratio | number | No | 1.0 | Minimum bottom-surface support ratio for pallet items (0-1) |
| Value | Description |
|---|---|
"min_bin_volume" | Minimize total volume of used bins (default) |
"min_bin_count" | Minimize number of bins used |
"min_bin_cost" | Minimize total cost of used bins |
| Code | Meaning | Use Case |
|---|---|---|
LWH | Original (Length-Width-Height up) | Default |
WLH | Rotated 90° on vertical axis | |
HLW | Height becomes length | Laying flat |
HWL | Height becomes width | Laying flat |
LHW | Length stays, swap W/H | On side |
WHL | Width stays, swap L/H | On side |
Keep upright: ["LWH", "WLH"] - only rotate around vertical axis
| Type | Description | Behavior |
|---|---|---|
solid | Rigid items (boxes, electronics) | Fixed dimensions, rotation only |
squishable | Flexible items (clothing, plush) | Can deform while preserving volume |
| Type | Description | Behavior |
|---|---|---|
carton_box | Rigid containers | Fixed dimensions |
mailer | Flexible containers (poly mailers) | Can reshape while preserving surface area |
pallet | Open-top platforms | Uses max_height for stack limit, supports min_support_ratio |
| Field | Type | Description |
|---|---|---|
status | string | "success" |
request_id | string | Unique request ID for debugging |
runtime_ms | number | Time spent in the optimization solver (ms) |
total_runtime_ms | number | Total API request time (ms) |
packed_bins | PackedBin[] | Array of packed bins with items |
| Field | Type | Description |
|---|---|---|
bin_id | string | ID of the bin type used |
bin_type | string | "carton_box", "mailer", or "pallet" |
input_dimensions | Dimensions | Original bin dimensions from the request |
output_dimensions | Dimensions | Effective bin dimensions used by the solver |
volume_utilization | number | Volume utilization (0.0 - 1.0) |
total_weight | number | Total weight of bin + items |
visualization_id | string | ID used to load the interactive 3D visualization |
pallet_metrics | PalletMetrics | Pallet-specific metrics (only present for pallet bins) |
item_placements | ItemPlacement[] | Detailed solver item placements |
| Field | Type | Description |
|---|---|---|
item_id | string | ID of the item |
output_dimensions | Dimensions | Placed item dimensions |
min_coordinates | [x, y, z] | Minimum occupied coordinates |
max_coordinates | [x, y, z] | Maximum occupied coordinates |
was_deformed | boolean | True if squishable item was deformed |
import requests
API_URL = "https://v2.cartonizationapi.com/post-cartonization"
API_KEY = "YOUR_API_KEY"
def cartonize(items, bins, objective="min_bin_count"):
payload = {
"max_runtime_seconds": 30,
"objective_function": objective,
"allowed_bins": bins,
"items": items
}
response = requests.post(
API_URL,
json=payload,
headers={
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}
)
return response.json()
# Example usage
bins = [
{"bin_id": "box_12x12x12", "length": 12, "width": 12, "height": 12, "bin_cost": 1.00}
]
items = [
{"item_id": "product_a", "quantity": 5, "length": 6, "width": 4, "height": 3, "weight": 2}
]
result = cartonize(items, bins)
if result["status"] == "success":
print(f"Packed into {len(result['packed_bins'])} bins")
for bin in result["packed_bins"]:
print(f" {bin['bin_id']}: {len(bin['item_placements'])} items, {bin['volume_utilization']*100:.1f}% full")
print(f" Visualization ID: {bin['visualization_id']}")import java.net.http.*;
import java.net.URI;
public class PerseussClient {
private static final String API_URL = "https://v2.cartonizationapi.com/post-cartonization";
private final String apiKey;
private final HttpClient client;
public PerseussClient(String apiKey) {
this.apiKey = apiKey;
this.client = HttpClient.newHttpClient();
}
public String cartonize(String jsonPayload) throws Exception {
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(API_URL))
.header("Authorization", "Bearer " + apiKey)
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(jsonPayload))
.build();
HttpResponse<String> response = client.send(request,
HttpResponse.BodyHandlers.ofString());
return response.body();
}
public static void main(String[] args) throws Exception {
PerseussClient client = new PerseussClient("YOUR_API_KEY");
String payload = """
{
"max_runtime_seconds": 30,
"objective_function": "min_bin_count",
"allowed_bins": [
{"bin_id": "box_12x12x12", "length": 12, "width": 12, "height": 12}
],
"items": [
{"item_id": "product_a", "quantity": 5, "length": 6, "width": 4, "height": 3, "weight": 2}
]
}
""";
String result = client.cartonize(payload);
System.out.println(result);
}
}curl -X POST "https://v2.cartonizationapi.com/post-cartonization" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"max_runtime_seconds": 30,
"objective_function": "min_bin_count",
"allowed_bins": [
{"bin_id": "box_12x12x12", "length": 12, "width": 12, "height": 12, "bin_cost": 1.00}
],
"items": [
{"item_id": "product_a", "quantity": 5, "length": 6, "width": 4, "height": 3, "weight": 2}
]
}'interface CartonizationRequest {
items: Item[];
allowed_bins: Bin[];
objective_function?: 'min_bin_volume' | 'min_bin_count' | 'min_bin_cost';
max_number_of_bins?: number;
max_runtime_seconds?: number;
item_to_item_incompatibility?: string[][];
bin_to_items_incompatibility?: Record<string, string[]>;
}
interface Item {
item_id: string;
length: number;
width: number;
height: number;
weight: number;
quantity: number;
item_type?: 'solid' | 'squishable';
allowed_orientations?: ('LWH' | 'LHW' | 'WLH' | 'WHL' | 'HLW' | 'HWL')[];
}
interface Bin {
bin_id: string;
length: number;
width: number;
height: number;
max_weight?: number;
max_fill_rate?: number;
bin_cost?: number;
bin_weight?: number;
bin_type?: 'carton_box' | 'mailer' | 'pallet';
max_height?: number;
min_support_ratio?: number;
}
const API_URL = "https://v2.cartonizationapi.com/post-cartonization";
async function cartonize(request: CartonizationRequest, apiKey: string) {
const response = await fetch(API_URL, {
method: "POST",
headers: {
"Authorization": `Bearer ${apiKey}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
max_runtime_seconds: 30,
...request,
}),
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
return response.json();
}
// Example usage
const result = await cartonize({
items: [
{ item_id: "product_a", quantity: 5, length: 6, width: 4, height: 3, weight: 2 }
],
allowed_bins: [
{ bin_id: "box_12x12x12", length: 12, width: 12, height: 12, bin_cost: 1.0 }
],
objective_function: "min_bin_count",
}, "YOUR_API_KEY");
console.log(`Packed into ${result.packed_bins.length} bins`);{
"max_runtime_seconds": 30,
"allowed_bins": [
{"bin_id": "standard_12x12x12", "length": 12, "width": 12, "height": 12}
],
"items": [
{"item_id": "hardcover_book", "quantity": 5, "length": 8, "width": 6, "height": 2, "weight": 24},
{"item_id": "spiral_notebook", "quantity": 3, "length": 10, "width": 7, "height": 1, "weight": 8}
]
}{
"max_runtime_seconds": 30,
"objective_function": "min_bin_cost",
"allowed_bins": [
{"bin_id": "small", "length": 8, "width": 8, "height": 8, "bin_cost": 0.50},
{"bin_id": "medium", "length": 12, "width": 12, "height": 12, "bin_cost": 1.00},
{"bin_id": "large", "length": 18, "width": 18, "height": 18, "bin_cost": 2.00}
],
"items": [
{"item_id": "widget_small", "quantity": 10, "length": 5, "width": 5, "height": 5, "weight": 32},
{"item_id": "widget_large", "quantity": 5, "length": 7, "width": 7, "height": 7, "weight": 48}
]
}{
"max_runtime_seconds": 30,
"objective_function": "min_bin_count",
"allowed_bins": [
{"bin_id": "small_bin", "length": 10, "width": 10, "height": 10, "bin_cost": 0.50},
{"bin_id": "large_bin", "length": 20, "width": 20, "height": 20, "bin_cost": 2.00}
],
"items": [
{"item_id": "gadget", "quantity": 12, "length": 8, "width": 8, "height": 8, "weight": 16}
]
}{
"max_runtime_seconds": 30,
"objective_function": "min_bin_count",
"allowed_bins": [
{"bin_id": "reinforced_box", "length": 15, "width": 15, "height": 15, "max_weight": 50.0, "bin_cost": 1.50}
],
"items": [
{"item_id": "metal_part", "quantity": 8, "length": 6, "width": 6, "height": 6, "weight": 12},
{"item_id": "steel_bracket", "quantity": 10, "length": 4, "width": 4, "height": 2, "weight": 5}
]
}{
"max_runtime_seconds": 30,
"allowed_bins": [
{"bin_id": "cushioned_box", "length": 16, "width": 16, "height": 16, "max_fill_rate": 0.60}
],
"items": [
{"item_id": "wine_bottle", "quantity": 6, "length": 4, "width": 4, "height": 12, "weight": 3}
]
}{
"max_runtime_seconds": 30,
"allowed_bins": [
{"bin_id": "tall_box", "length": 12, "width": 12, "height": 20}
],
"items": [
{"item_id": "ceramic_vase", "quantity": 4, "length": 5, "width": 5, "height": 15, "weight": 3, "allowed_orientations": ["LWH", "WLH"]}
]
}{
"max_runtime_seconds": 30,
"allowed_bins": [
{"bin_id": "flat_carrier", "length": 20, "width": 20, "height": 12}
],
"items": [
{"item_id": "frozen_pizza", "quantity": 6, "length": 14, "width": 14, "height": 2, "weight": 2.5, "allowed_orientations": ["LWH", "WLH"]}
]
}{
"max_runtime_seconds": 30,
"objective_function": "min_bin_count",
"allowed_bins": [
{"bin_id": "poly-mailer", "bin_type": "mailer", "length": 15, "width": 15, "height": 4, "bin_cost": 0.5}
],
"items": [
{"item_id": "cotton-tshirt", "item_type": "squishable", "quantity": 3, "length": 12, "width": 10, "height": 2, "weight": 0.4}
]
}{
"max_runtime_seconds": 30,
"objective_function": "min_bin_count",
"allowed_bins": [
{"bin_id": "shipping-box", "length": 18, "width": 14, "height": 12, "bin_cost": 1.50}
],
"items": [
{"item_id": "hardcover-book", "item_type": "solid", "quantity": 2, "length": 9, "width": 6, "height": 2, "weight": 2},
{"item_id": "cotton-tshirt", "item_type": "squishable", "quantity": 4, "length": 10, "width": 8, "height": 2, "weight": 0.4}
]
}{
"max_runtime_seconds": 30,
"objective_function": "min_bin_count",
"allowed_bins": [
{"bin_id": "storage_box", "length": 20, "width": 20, "height": 20}
],
"items": [
{"item_id": "bleach", "quantity": 3, "length": 4, "width": 4, "height": 10, "weight": 4},
{"item_id": "ammonia", "quantity": 3, "length": 4, "width": 4, "height": 10, "weight": 4},
{"item_id": "dish_soap", "quantity": 5, "length": 3, "width": 3, "height": 8, "weight": 1}
],
"item_to_item_incompatibility": [["bleach", "ammonia"]]
}{
"max_runtime_seconds": 30,
"objective_function": "min_bin_cost",
"allowed_bins": [
{"bin_id": "insulated", "length": 15, "width": 15, "height": 15, "bin_cost": 2.50},
{"bin_id": "standard", "length": 15, "width": 15, "height": 15, "bin_cost": 0.75}
],
"items": [
{"item_id": "frozen_meal", "quantity": 4, "length": 8, "width": 6, "height": 3, "weight": 1.5},
{"item_id": "canned_soup", "quantity": 6, "length": 4, "width": 4, "height": 5, "weight": 1.25}
],
"bin_to_items_incompatibility": {"standard": ["frozen_meal"]}
}{
"max_runtime_seconds": 30,
"objective_function": "min_bin_cost",
"allowed_bins": [
{"bin_id": "poly_mailer_small", "bin_type": "mailer", "length": 10, "width": 8, "height": 4, "max_weight": 5.0, "bin_cost": 0.35},
{"bin_id": "poly_mailer_medium", "bin_type": "mailer", "length": 14, "width": 10, "height": 6, "max_weight": 15.0, "bin_cost": 0.65},
{"bin_id": "corrugated_large", "bin_type": "carton_box", "length": 18, "width": 14, "height": 10, "max_weight": 30.0, "bin_cost": 1.25}
],
"items": [
{"item_id": "phone_case", "item_type": "solid", "quantity": 2, "length": 6, "width": 4, "height": 1, "weight": 0.2},
{"item_id": "tshirt_folded", "item_type": "squishable", "quantity": 3, "length": 10, "width": 8, "height": 1, "weight": 0.4},
{"item_id": "water_bottle", "item_type": "solid", "quantity": 2, "length": 3, "width": 3, "height": 10, "weight": 0.75, "allowed_orientations": ["LWH", "WLH", "HLW", "HWL"]}
]
}{
"status": "success",
"request_id": "xK9mN2pQr4",
"runtime_ms": 1523.45,
"total_runtime_ms": 1687.32,
"packed_bins": [
{
"bin_index": 0,
"bin_id": "box-medium",
"bin_type": "carton_box",
"input_dimensions": {"length": 30, "width": 25, "height": 20},
"output_dimensions": {"length": 30, "width": 25, "height": 20},
"volume_utilization": 0.72,
"total_weight": 8.5,
"visualization_id": "abc123",
"item_placements": [
{
"item_index": 0,
"item_id": "widget-001",
"output_dimensions": {"length": 10, "width": 8, "height": 6},
"min_coordinates": [0, 0, 0],
"max_coordinates": [10, 8, 6],
"was_deformed": false
},
{
"item_index": 1,
"item_id": "sweater-blue",
"output_dimensions": {"length": 10, "width": 8, "height": 6},
"min_coordinates": [1, 10, 0],
"max_coordinates": [11, 18, 6],
"was_deformed": true
}
]
}
]
}{"status_code": 401, "error_message": "Invalid or missing API key"}{"error": "Missing demo session verification"}{"status": "fail", "request_id": "abc123", "packed_bins": [], "error": "Could not find valid packing"}visualization_id for 3D viewingitem_type: "squishable" can compress while preserving volume. Check was_deformed: truebin_type: "mailer" can reshape. Output dimensions may differ from inputbin_type: "pallet" use max_height instead of height. Response includes pallet_metrics with stack height utilization[0,0,0] is at the bin corner; placements expose min/max coordinatesPaste this prompt at the start of your conversation. ChatGPT will understand the API and help you write integration code.
Paste this prompt and Claude will understand the API structure and help you integrate directly in your codebase.
Add this as a comment block in your code file. Copilot will use it as context for suggestions.
Use this as system instructions for custom AI agents that need to work with the Perseuss API.