Skip to main content
← CutOptim Engine APINesting API · POST /v1/optimize/nest

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.

Request (excerpt) · POST /v1/optimize/nest
{
  "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 }
}
Response, drawn from sheets[].parts
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 with POST /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.respectStock a 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
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"]
  }'
Python
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"])
JavaScript
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:

FAQ

Is there a free nesting API?
You can build and test the whole integration for free: a test key costs nothing, and 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?
Yes. Put the drawing in 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?
Both. The default lbf engine answers inside the request, deterministically. 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?
Not yet. Parts are nested by their outer contour, so a small part is not placed inside the hole of a larger one. It is on our roadmap; until then, a layout with large cut-outs leaves that area empty.
Does it do common-line cutting or produce G-code?
No. The response gives every part’s position and rotation, the cut length and the number of pierces, and the layout as DXF or SVG, which your CAM or machine software turns into a cutting program.
How is the nesting API priced?
By plan, not by part count: Studio is €49 a month for 3,000 requests and Scale is €149 a month for 10,000 requests, net. The limit is a hard monthly cap per account with no overage charge.
Will the same request always return the same layout?
With the default lbf engine, yes — the same input returns the same output, so you can cache and compare results. The asynchronous max search is time-limited and says so with deterministic: false in the response.

Benchmarks · Engine API reference →