Prize Structure
How It Works
Play the Game & Get Your API Key
Play the truck loading game and score ≥50% packing density. Your API key will be displayed on the end screen — copy it and save it. No separate sign-up needed.
Play Now →Build Your Agent
Use the REST API to send placements and receive game state. One box at a time, full state returned. No simulator provided - build your own.
Top the Leaderboard
Your agent plays random sequences. Minimum 25 games to qualify. Top 5 on the public leaderboard advance to the private evaluation — 50 held-out sequences, each played exactly once. #1 wins.
Scoring
Your score is packing density — the fraction of usable truck volume you fill with boxes.
// Density formula
density = sum(box_volumes) / (max_x_reached × truck_width × truck_height)How You Win
The competition has two phases. The public leaderboard determines who advances. The private evaluation determines who wins.
Public Leaderboard
Play as many games as you want (up to 50/day in compete mode). Each game draws from the same box pool, but the sequence order is randomly shuffled — every game is different. Your leaderboard rank is the interquartile mean (IQM) of your most recent 50 compete games — the average of the middle 50%, dropping your best and worst outliers.
Private Evaluation
The top 5 from the public leaderboard play 50 held-out sequences that no one has seen before. These sequences are pre-generated and frozen — every finalist plays the exact same 50 sequences in the same order. Each sequence can be played exactly once per API key. If your agent crashes, disconnects, or causes a collapse mid-sequence, that score stands. No retries.
Your final score is the interquartile mean (IQM) across all 50 private sequences — the middle 50% of your scores, averaged. You must achieve ≥70% IQM density to qualify for the prize. Note: there are no robot reachability constraints, visibility concerns, or observation noise in this round — it is pure packing. #1 with ≥70% wins $50,000.
Validation
Before any prize is awarded, top submissions are validated:
Rules
Questions? Reach us at foresight-api-challenge@dexterity.ai
Overview
The Foresight Packing Challenge API is a REST service where your agent packs boxes into a truck, one at a time. You receive a box, choose where to place it (position + orientation), and get back the full post-placement state including physics-settled positions.
Modes
Truck Segment Dimensions
Endpoints
Start a new game session. Returns the truck config and first box.
Request Body
| Field | Type | Description |
|---|---|---|
| api_key* | string | Your API key |
| mode | string | Defaults to "compete". Use "dev" for testing |
Response
| Field | Type | Description |
|---|---|---|
| game_id | string | Unique game session ID |
| truck | object | Dimensions in meters: { depth, width, height } |
| current_box | object | First box: { id, dimensions, weight } |
| boxes_remaining | int | Number of boxes left in the queue |
| mode | string | Confirmed game mode |
Place the current box in the truck. Returns the updated state with physics-settled positions.
Request Body
| Field | Type | Description |
|---|---|---|
| game_id* | string | From the /start response |
| box_id* | string | Must match current_box.id |
| position* | [x, y, z] | Center position in meters |
| orientation_wxyz* | [w, x, y, z] | Rotation quaternion (auto-normalized) |
Response
| Field | Type | Description |
|---|---|---|
| status | string | "ok" or "terminated" |
| placed_boxes | array | All placed boxes with post-settle positions and orientations |
| current_box | object | null | Next box to place, or null if game over |
| boxes_remaining | int | Boxes left in the queue |
| density | float | Current packing density (your score) |
| game_status | string | "in_progress" or "completed" |
| termination_reason | string | null | Why the game ended (if it did) |
id matches current_box.id. You cannot skip or reorder boxes.Get the current state of a game. Useful for debugging or resuming after a crash.
Response
| Field | Type | Description |
|---|---|---|
| game_id | string | The game session ID |
| game_status | string | "in_progress" or "completed" |
| mode | string | "dev" or "compete" |
| boxes_placed | int | Number of boxes placed so far |
| boxes_remaining | int | Boxes left in the queue |
| density | float | Current packing density |
| placed_boxes | array | All placed boxes with current positions |
| current_box | object | null | Next box to place |
End a game early. Your score is the density at time of stopping.
Request Body
| Field | Type | Description |
|---|---|---|
| game_id* | string | The game session to stop |
| api_key* | string | Your API key |
Retrieve all your games and a summary of your stats. Requires your API key.
Query Parameters
| Field | Type | Description |
|---|---|---|
| api_key* | string | Your API key |
| mode | string | Filter by "dev" or "compete" |
| status | string | Filter by "in_progress" or "completed" |
Response
| Field | Type | Description |
|---|---|---|
| api_key | string | Your API key |
| display_name | string | null | Your display name |
| summary | object | Aggregate stats: total/completed/in-progress game counts, avg & best compete density, games today, daily limit |
| games | array | All matching games (newest first), each with game_id, mode, status, density, boxes_placed, total_boxes, termination_reason, timestamps |
Health check. Returns {"status": "ok"}.
Coordinate System
The truck uses a right-handed coordinate system with the origin at the front-bottom-left corner.
Z (up, height: 2.75m)
^
|
|
+---------> Y (width: 2.6m)
/
/
v X (depth: 2.0m, loading direction)| Axis | Direction | Range |
|---|---|---|
| X | Depth (loading direction, front → back) | 0 → 2.0 m |
| Y | Width (left → right) | 0 → 2.6 m |
| Z | Height (floor → ceiling) | 0 → 2.75 m |
Position
The position field is the center of the box. To place a box flush on the floor in the front-left corner:
// Box dimensions: [length, width, height] = [0.4, 0.3, 0.2]
"position": [0.2, 0.15, 0.1] // half-extents from originOrientation
Quaternion in [w, x, y, z] format. Common rotations:
| Rotation | Quaternion | Effect |
|---|---|---|
| Identity | [1, 0, 0, 0] | No rotation |
| 90° around Z | [0.707, 0, 0, 0.707] | Swap length ↔ width |
| 90° around Y | [0.707, 0, 0.707, 0] | Swap length ↔ height |
| 90° around X | [0.707, 0.707, 0, 0] | Swap width ↔ height |
Tips for Building Your Agent
Start with dev mode
Use "mode": "dev" while building. Boxes land exactly where you place them — no physics surprises. Switch to "compete" when you're ready to test against real physics and get on the leaderboard.
Use placed_boxes for planning
Every /place response includes the full placed_boxes array with post-physics positions. In compete mode, boxes may shift from where you placed them. Use the settled positions to compute valid placement locations for the next box.
Think about stability
Placing boxes without support underneath will cause them to fall and potentially topple the stack. If 3 or more boxes displace by more than 10cm, the game terminates with unstable.
Optimize rotations
Each box can be placed in 6 orientations (3 axes × 2 flips that matter). Trying all valid rotations for each box is a key optimization. A box that doesn't fit one way might fit perfectly rotated.
Rate limits
Interactive docs
Swagger UI is available at /docs for interactive API exploration.
Happy packing. We'll see you on the leaderboard.