Nesting API
The CutOptim nesting API places irregular parts on sheets over plain HTTP. You POST the outlines — as coordinates or as DXF and SVG files — and your sheets as JSON to POST /v1/optimize/nest; the response carries every part’s position and rotation, the sheet count, cut length and pierces, and on request the finished layout as DXF and SVG.
It is the true-shape engine the CutOptim app runs: instant and deterministic by default, with an asynchronous max search when a longer look can save a sheet. Keys are self-serve, prices are public, and POST /v1/validate/nest checks a request for free, without a key.
A real call, drawn from its response
Four part types — an L-bracket, a gusset, a plate with a slot and a flange sent as an SVG file — on one sheet with a clamp zone the parts must avoid. The request below is an excerpt of the real body; the sheet is drawn from the coordinates the engine returned.
{
"parts": [
{ "name": "bracket", "polygon": […], "qty": 12, … },
{ "name": "gusset", "polygon": […], "qty": 14, … },
{ "name": "plate", "polygon": […], "holes": […], "qty": 12, … },
{ "name": "flange", "source": { … }, "qty": 10, … }
],
"stock": [{ "w": 2500, "h": 1250, "exclusions": […], … }],
"options": { "minSeparation": 5, "edgeClearance": 10 }
}- Sheets
- 1
- sheetCount
- Fill
- 56.32%
- density
- Parts placed
- 48 / 48
- placed
- Cut length
- 49,463
- cutLength
- Pierces
- 110
- pierces
Laser-cut steel parts: three sent as coordinates, the flange as an SVG file (source). Every part stays out of the clamp zone (exclusions) and keeps the requested gap (minSeparation).
What the nesting API does
- True-shape nesting of arbitrary polygons with interior holes, interlocking parts into each other’s concave pockets — 6 sheets where the same parts by bounding box need 9.
- Parts as coordinates or as files: put an SVG or DXF document in
parts[].source, or split a multi-part drawing withPOST /v1/import/nest. Nothing is stored. - Rotation per part: a list of allowed angles in
allowedRotations, or "continuous". - Sheets as rectangles or polygons, with exclusion and lower-quality zones (
stock[].exclusions), part spacing (options.minSeparation) and a separate edge clearance (options.edgeClearance). - Several sheet sizes with prices: the engine picks the cheapest combination, and with
options.respectStocka limited supply places must-cut parts (parts[].priority) first. - Material-aware: a part tagged with a material is nested only on sheets of that material.
- Layout files in the response:
include:["svg","dxf"]returns the nested sheets as SVG and as DXF with STOCK, PARTS, HOLES and ZONES layers.
Instant or thorough: lbf and max
The default engine, lbf, answers inside the HTTP request and returns the same layout for the same input every time, so the plan behind a quote is the plan behind the order. Send engine: "max" and the job runs asynchronously: you get a job id and poll GET /v1/jobs/{id}, and the search spends options.timeBudgetMs looking for a layout on fewer sheets. It never returns anything worse than lbf, and it reports deterministic: false because a time-limited search can differ between runs. A job with exclusion zones or polygon sheets is served by lbf, with a warning.
Send coordinates or CAD files
A part is an outline: a polygon in one unit of your choice, with optional holes, and every coordinate in the response comes back in that unit. If your parts live in drawings, send the drawing instead — parts[].source takes an SVG or DXF document and the server reads the outline and its holes with the same parser the CutOptim app uses. A file with many parts goes through POST /v1/import/nest first, which returns one outline per part.
What comes back
Each used sheet lists its placed parts as a rigid transform — name, x, y and rotation — so you rotate your own outline and translate it; nothing is re-approximated. Next to the layout come sheetCount, density, placed and total, cutLength and pierces for machine-time estimates, totalPrice when sheets carry a price, stockUsage per sheet size, and unplaced for anything that did not fit, with the reason in warnings. Ask for include:["svg","dxf"] and the drawings arrive in the same response.
Plans and limits
Studio costs €49 a month for 3,000 requests, Scale €149 a month for 10,000 requests; prices are net. The monthly limit is a hard cap per account with no overage charge, and the remaining quota comes back in a response header and from GET /v1/usage. A free test key lets you build the integration before you pay, and POST /v1/validate/nest checks any request without a key and without using the quota.
What it does not do (yet)
We would rather say it here than in a sales call. The engine nests parts by their outer contour: it does not place small parts inside the holes of larger ones (part-in-part), it does not merge shared edges into one cut (common-line), and it does not write G-code — you get positions, the cut length and pierce count, and DXF or SVG files for your own CAM. It is a web service; there is no library to install.
Call it from your code
The same small request in three languages: two part types, one priced sheet size, a 5 mm gap, and the layout back as SVG and DXF. Replace the key with your own.
curl https://api.cutoptim.com/v1/optimize/nest \
-H "Authorization: Bearer co_live_…" \
-H "Content-Type: application/json" \
-d '{
"parts": [
{ "name": "bracket", "polygon": [[0,0],[300,0],[300,100],[100,100],[100,300],[0,300]], "qty": 12, "allowedRotations": [0,90,180,270] },
{ "name": "plate", "polygon": [[0,0],[240,0],[240,160],[0,160]], "holes": [[[60,65],[180,65],[180,95],[60,95]]], "qty": 8 }
],
"stock": [{ "w": 2500, "h": 1250, "price": 96 }],
"options": { "minSeparation": 5 },
"include": ["svg", "dxf"]
}'import requests
body = {
"parts": [
{ "name": "bracket", "polygon": [[0,0],[300,0],[300,100],[100,100],[100,300],[0,300]], "qty": 12, "allowedRotations": [0,90,180,270] },
{ "name": "plate", "polygon": [[0,0],[240,0],[240,160],[0,160]], "holes": [[[60,65],[180,65],[180,95],[60,95]]], "qty": 8 }
],
"stock": [{ "w": 2500, "h": 1250, "price": 96 }],
"options": { "minSeparation": 5 },
"include": ["svg", "dxf"]
}
r = requests.post("https://api.cutoptim.com/v1/optimize/nest",
headers={"Authorization": "Bearer co_live_…"}, json=body, timeout=30)
plan = r.json()
print(plan["metrics"]["sheetCount"], len(plan["sheets"]))
open("nest.dxf", "w").write(plan["dxf"])const body = {
"parts": [
{ "name": "bracket", "polygon": [[0,0],[300,0],[300,100],[100,100],[100,300],[0,300]], "qty": 12, "allowedRotations": [0,90,180,270] },
{ "name": "plate", "polygon": [[0,0],[240,0],[240,160],[0,160]], "holes": [[[60,65],[180,65],[180,95],[60,95]]], "qty": 8 }
],
"stock": [{ "w": 2500, "h": 1250, "price": 96 }],
"options": { "minSeparation": 5 },
"include": ["svg", "dxf"]
};
const r = await fetch("https://api.cutoptim.com/v1/optimize/nest", {
method: "POST",
headers: { "Authorization": "Bearer co_live_…", "Content-Type": "application/json" },
body: JSON.stringify(body),
});
const plan = await r.json();
console.log(plan.metrics.sheetCount, plan.sheets.length);By industry
The same endpoint, explained for two trades:
True-shape nesting of irregular polygons, with exclusion zones.
True-shape nesting onto plate for laser, plasma or waterjet.
FAQ
Is there a free nesting API?
POST /v1/validate/nest checks any request without a key and without using a quota. Production traffic runs on a paid plan with a fixed monthly price.Can I send DXF or SVG files instead of coordinates?
parts[].source and the server reads the outline and its holes out of it. A file that holds many parts goes through POST /v1/import/nest, which returns one outline per part. Files are processed in memory and not stored.Is the nesting API synchronous or asynchronous?
engine: "max" runs as a background job you poll with GET /v1/jobs/{id}; it spends options.timeBudgetMs searching for fewer sheets and never returns a worse layout than lbf.Does it support part-in-part nesting?
Does it do common-line cutting or produce G-code?
How is the nesting API priced?
Will the same request always return the same layout?
deterministic: false in the response.