For AI Coding Assistants

AI Integration Prompt

Copy-paste this comprehensive prompt into ChatGPT, Claude Code, Cursor, or any AI coding assistant to quickly integrate with the Perseuss API.

Perseuss API Integration Prompt617 lines
Markdown Source
# 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
Rendered Preview

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

EnvironmentURLAPI Key
Productionhttps://v2.cartonizationapi.com/post-cartonizationYour API key
Demo Playgroundhttps://cartonizationapi.com/api/demo/cartonizeWebsite-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

    FieldTypeRequiredDefaultDescription
    itemsItem[]Yes-Array of items to pack
    allowed_binsBin[]Yes-Array of available bin/box types
    objective_functionstringNo"min_bin_volume"Optimization objective
    max_number_of_binsintegerNoAutoMaximum bins to use
    max_runtime_secondsnumberNo30Max solver runtime
    item_to_item_incompatibilitystring[][]No[]Item pairs that can't share a bin
    bin_to_items_incompatibilityobjectNo{}Map of bin_id to incompatible item_ids

    Item Object

    FieldTypeRequiredDefaultDescription
    item_idstringYes-Unique item identifier
    lengthnumberYes-Item length
    widthnumberYes-Item width
    heightnumberYes-Item height
    weightnumberYes-Item weight
    quantityintegerYes-Number of this item to pack
    item_typestringNo"solid""solid" or "squishable"
    allowed_orientationsstring[]NoAllAllowed rotation orientations

    Bin Object

    FieldTypeRequiredDefaultDescription
    bin_idstringYes-Unique bin identifier
    lengthnumberYes-Bin length
    widthnumberYes-Bin width
    heightnumberYes-Bin height
    bin_typestringNo"carton_box""carton_box", "mailer", or "pallet"
    max_weightnumberNo1000000Maximum weight capacity
    max_fill_ratenumberNo1.0Maximum fill rate (0.0-1.0)
    bin_costnumberNo0.0Cost of using this bin
    bin_weightnumberNo0.0Empty bin weight
    max_heightnumberNo-Maximum stack height for pallets (replaces height)
    min_support_rationumberNo1.0Minimum bottom-surface support ratio for pallet items (0-1)

    Objective Functions

    ValueDescription
    "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

    CodeMeaningUse Case
    LWHOriginal (Length-Width-Height up)Default
    WLHRotated 90° on vertical axis
    HLWHeight becomes lengthLaying flat
    HWLHeight becomes widthLaying flat
    LHWLength stays, swap W/HOn side
    WHLWidth stays, swap L/HOn side

    Keep upright: ["LWH", "WLH"] - only rotate around vertical axis

    Item Types

    TypeDescriptionBehavior
    solidRigid items (boxes, electronics)Fixed dimensions, rotation only
    squishableFlexible items (clothing, plush)Can deform while preserving volume

    Bin Types

    TypeDescriptionBehavior
    carton_boxRigid containersFixed dimensions
    mailerFlexible containers (poly mailers)Can reshape while preserving surface area
    palletOpen-top platformsUses max_height for stack limit, supports min_support_ratio

    Response Schema

    Success Response (200)

    FieldTypeDescription
    statusstring"success"
    request_idstringUnique request ID for debugging
    runtime_msnumberTime spent in the optimization solver (ms)
    total_runtime_msnumberTotal API request time (ms)
    packed_binsPackedBin[]Array of packed bins with items

    PackedBin Object

    FieldTypeDescription
    bin_idstringID of the bin type used
    bin_typestring"carton_box", "mailer", or "pallet"
    input_dimensionsDimensionsOriginal bin dimensions from the request
    output_dimensionsDimensionsEffective bin dimensions used by the solver
    volume_utilizationnumberVolume utilization (0.0 - 1.0)
    total_weightnumberTotal weight of bin + items
    visualization_idstringID used to load the interactive 3D visualization
    pallet_metricsPalletMetricsPallet-specific metrics (only present for pallet bins)
    item_placementsItemPlacement[]Detailed solver item placements

    ItemPlacement Object

    FieldTypeDescription
    item_idstringID of the item
    output_dimensionsDimensionsPlaced item dimensions
    min_coordinates[x, y, z]Minimum occupied coordinates
    max_coordinates[x, y, z]Maximum occupied coordinates
    was_deformedbooleanTrue if squishable item was deformed

    Code Examples

    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

    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

    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

    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)

    {
      "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)

    {
      "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

    {
      "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

    {
      "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)

    {
      "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)

    {
      "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)

    {
      "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

    {
      "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

    {
      "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)

    {
      "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)

    {
      "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)

    {
      "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

    {
      "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)

    {"status_code": 401, "error_message": "Invalid or missing API key"}

    Demo Playground Access

    {"error": "Missing demo session verification"}

    Solver Failure

    {"status": "fail", "request_id": "abc123", "packed_bins": [], "error": "Could not find valid packing"}

    Important Notes

  • Units are implicit - Use consistent units across all dimensions and weights
  • Visualization IDs - Each packed bin includes a visualization_id for 3D viewing
  • Squishable items - Items with item_type: "squishable" can compress while preserving volume. Check was_deformed: true
  • Mailer bins - Bins with bin_type: "mailer" can reshape. Output dimensions may differ from input
  • Pallet bins - Bins with bin_type: "pallet" use max_height instead of height. Response includes pallet_metrics with stack height utilization
  • 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
  • ChatGPT

    Paste this prompt at the start of your conversation. ChatGPT will understand the API and help you write integration code.

    Claude Code / Cursor

    Paste this prompt and Claude will understand the API structure and help you integrate directly in your codebase.

    GitHub Copilot

    Add this as a comment block in your code file. Copilot will use it as context for suggestions.

    Custom GPTs / Agents

    Use this as system instructions for custom AI agents that need to work with the Perseuss API.