Examples
Validated request and response samples for the Sawvant cutting optimization API.
Every request below validates against the OpenAPI spec.
All dimensions are in millimetres. Optimization is asynchronous: POST /v1/optimize
answers 202 with a job_id, and you read the result from GET /v1/jobs/{id}.
Basic optimization
Two part types on one sheet type with unlimited stock.
curl -X POST https://api.sawvant.com/v1/optimize \
-H "X-API-Key: sk_your_key" \
-H "Content-Type: application/json" \
-d '{
"parts": [
{ "id": "shelf", "length": 600, "width": 400, "quantity": 8, "grain": "none" },
{ "id": "bracket", "length": 300, "width": 200, "quantity": 4, "grain": "none" }
],
"sheets": [
{ "id": "mdf-18", "length": 2440, "width": 1220, "quantity": 0, "grain": "none" }
],
"machine": { "blade_thickness": 3.2, "max_levels": 3, "cut_direction": "default" }
}'The result summary:
{
"total_sheets": 1,
"yield_percent": 72.56,
"waste_percent": 27.44,
"waste_area": 816800,
"sheets_used": [
{ "sheet_id": "mdf-18", "quantity": 1, "yield_percent": 72.56 }
]
}Grain direction and edge banding
A furniture panel run on veneered board. grain: "length" pins the part to the
sheet grain so it cannot be rotated. edge_banding adds material per side
before packing, so the placement dimensions you get back already include the
banding. trim_margins removes an unusable border from each sheet edge.
curl -X POST https://api.sawvant.com/v1/optimize \
-H "X-API-Key: sk_your_key" \
-H "Content-Type: application/json" \
-d '{
"parts": [
{
"id": "door-front", "length": 700, "width": 396, "quantity": 6,
"grain": "length",
"edge_banding": { "top": 2, "bottom": 2, "left": 2, "right": 2 }
},
{ "id": "side-panel", "length": 720, "width": 500, "quantity": 4, "grain": "length" }
],
"sheets": [
{
"id": "oak-veneer-18", "length": 2800, "width": 2070, "quantity": 0,
"grain": "length",
"trim_margins": { "top": 10, "bottom": 10, "left": 10, "right": 10 },
"article_number": "OAK-18-2800"
}
],
"machine": { "blade_thickness": 4.4, "max_levels": 3, "cut_direction": "rip" }
}'article_number is passed straight through to sheets_used, so you can map
consumption back to your own SKUs:
{
"total_sheets": 1,
"yield_percent": 54.91,
"sheets_used": [
{
"sheet_id": "oak-veneer-18",
"article_number": "OAK-18-2800",
"quantity": 1,
"yield_percent": 54.0
}
]
}Grain values are none, length, width and free_same. Use free_same when
parts may rotate as long as they all end up in the same orientation.
cut_direction is default, rip or cross.
Cost calculation
Add cost_tariffs to get a cost breakdown alongside the plan. Cost and
production metrics are Pro features.
curl -X POST https://api.sawvant.com/v1/optimize \
-H "X-API-Key: sk_your_key" \
-H "Content-Type: application/json" \
-d '{
"parts": [
{ "id": "shelf", "length": 600, "width": 400, "quantity": 16, "grain": "none" },
{ "id": "divider", "length": 380, "width": 250, "quantity": 12, "grain": "none" }
],
"sheets": [
{ "id": "mdf-18", "length": 2440, "width": 1220, "quantity": 0, "grain": "none" }
],
"machine": { "blade_thickness": 3.2, "max_levels": 3, "cut_direction": "default" },
"cost_tariffs": {
"setup_cost": 15,
"cost_per_meter": 0.12,
"cost_per_rotation": 0.05,
"cost_per_stack": 0.5,
"cost_per_cycle": 0.8
}
}'The result carries metrics and cost next to the usual summary and layouts:
{
"metrics": {
"total_cut_length": 47120,
"total_cuts": 56,
"total_rotations": 6,
"total_stacks": 2,
"cut_cycles": 2
},
"cost": {
"setup_cost": 15,
"cutting_cost": 5.6544,
"stacking_cost": 1,
"rotation_cost": 0.3,
"cycle_cost": 1.6,
"total_cost": 23.5544
}
}total_cut_length is in millimetres, so cutting_cost is
total_cut_length / 1000 * cost_per_meter. Tariffs you leave out count as
zero.
Reading placements
Every layout holds the placements for one sheet pattern. quantity is how many
identical sheets use that pattern.
{
"sheet_id": "mdf-18",
"quantity": 1,
"placements": [
{
"part_id": "shelf",
"sheet_id": "mdf-18",
"x": 0,
"y": 0,
"width": 600,
"height": 400,
"rotated": false,
"grain": "none"
},
{
"part_id": "shelf",
"sheet_id": "mdf-18",
"x": 603.2,
"y": 0,
"width": 600,
"height": 400,
"rotated": false,
"grain": "none"
}
]
}x and y are measured from the top-left of the usable area, after trim
margins. The 3.2 mm gap between the two placements above is the blade kerf.
width and height include edge banding when you set it.