Recipes
Recipe — cut a job nest
Take a job nest's sheets to the cutting machine over the API: DXF or SVG per sheet, a zip of them all, and the JSON nest plan an integration reads sheets from.
A job nest lays a backlog of sheet-metal parts out on shared sheets. This recipe takes those sheets to the machine over the API — and the sheet a single calculation's own price laid its part out on the same way — so a CAM system, an MES or an agent can do it without the dashboard.
Every export reads parts:read. Nothing here changes a calculation's
price or a job nest's result: an export is a read of what was stored.
1. Export a job nest's sheets
GET /nest-runs/{run_id}/export writes the sheets of every solved material
and thickness of the job nest. Each distinct layout is one sheet; the
manifest and the plan say how many identical sheets it stands for.
| Query | Values | What you get |
|---|---|---|
format |
dxf (default), svg, json |
DXF or SVG per sheet, or the JSON nest plan |
sheet |
all (default), or one key <group>:<index> |
every sheet — a zip (DXF/SVG) or the whole plan (JSON) — or that one sheet's file |
exploded |
false (default), true |
DXF only: plain closed polylines in place, no block references |
revision |
omitted (the active revision), or a number | the sheets as laid out in that revision of every material and thickness — 1 is the job nest's own layout; every adjustment posted through POST /nest-runs/{run_id}/groups/{group_id}/revisions is the next |
# every sheet as DXF: a zip with plan.json and manifest.csv
curl -o nest.zip \
"https://api.arcnm.io/api/v1/nest-runs/$RUN_ID/export?format=dxf" \
-H "X-API-Key: $ARCNM_API_KEY"
# one sheet, for a machine that reads no blocks
curl -o sheet-0-0.dxf \
"https://api.arcnm.io/api/v1/nest-runs/$RUN_ID/export?format=dxf&sheet=0:0&exploded=true" \
-H "X-API-Key: $ARCNM_API_KEY"
import requests
resp = requests.get(
f"https://api.arcnm.io/api/v1/nest-runs/{run_id}/export",
params={"format": "json"},
headers={"X-API-Key": "YOUR_API_KEY"},
)
resp.raise_for_status()
plan = resp.json()
for sheet in plan["sheets"]:
print(sheet["key"], sheet["repeat"], "x", sheet["container"]["key"], sheet["count"], "parts")
const resp = await fetch(
`https://api.arcnm.io/api/v1/nest-runs/${runId}/export?format=svg&sheet=0:0`,
{ headers: { "X-API-Key": process.env.ARCNM_API_KEY! } },
)
const svg = await resp.text()
The file name travels in Content-Disposition
(nest-run-<run id>-sheet-<group>-<index>.dxf, nest-run-<run id>-dxf.zip,
an exploded DXF nest-run-<run id>-dxf-exploded.zip,
nest-run-<run id>-plan.json). A job nest that is still running exports
what is solved so far; one with nothing solved yet answers
nest_run_nothing_to_export (409), a sheet key it has not
nest_run_sheet_not_found (404) — see Errors.
2. Export a calculation's own sheet
GET /calculations/{calculation_id}/sheet-nest/export writes the sheet the
calculation's own price laid its part out on — the part alone, as many
copies as its price put on one sheet. It takes format and exploded as
above; there is one sheet, so no sheet and no zip. A calculation that
stored no sheet layout answers sheet_layout_not_found (404).
3. The DXF
- R2010,
$INSUNITS4: every coordinate is a millimetre. The sheet's origin is a corner, x along the sheet's length, y across its width. - Layers:
SHEET(the sheet's rectangle),MARGIN(the usable area, dashed),REMNANT(the reusable rest the sheet leaves, when it does),CUT_OUTER(outer contours),CUT_INNER(holes),LABEL(the part reference and order reference at each copy, and the sheet's title). - One block per part, one insert per copy. The block
PART_P1holds the part's contour and holes as closed lightweight polylines in the part's own frame. EachINSERTplaces one copy: a mirrored copy is reflected across the part's own x axis (yscale−1), then turned counter-clockwise byrotation, then set atinsert. exploded=truewrites each copy's contours as closed polylines in place, all in the world coordinate system, and no blocks — for a cutting system that does not read block references, or reads a reflected one in its own coordinate system.- What the drawing says about itself: the header's custom properties
(
NEST_RUN_IDorNEST_CALCULATION_ID,NEST_SHEET,NEST_SHEETS_TO_CUT,NEST_MATERIAL,NEST_GAUGE_MM,NEST_CONTAINER,NEST_SHEET_MM,NEST_PARTS,NEST_UTILISATION,NEST_TOLERANCE) and a title above the sheet state the same. - Tolerance: contours are within 0.2 mm of the unfolded flat pattern; arcs are polylines. Check a contour against the part's drawing before the first cut, as you would any nest.
4. The SVG
The same geometry, viewBox in millimetres, y up inside the sheet group
(a translate and scale(1 -1)), each DXF layer a <g> of that class.
Every outer contour carries data-part, data-line and data-order, so a
viewer can name what it shows.
5. The JSON nest plan (schema v1)
The plan is the export as data: what the DXF draws, readable by an integration that lays the parts out itself or checks a file.
{
"v": 1,
"units": "mm",
"source": {"kind": "run", "run_id": "…", "environment_id": "…", "created_at": "…", "finished_at": "…"},
"tolerance": {"contour_mm": 0.2, "arcs": "polylines", "note": "Contours within 0.2 mm of the unfolded flat pattern; arcs as polylines."},
"parts": [
{
"ref": "P1",
"name": "bracket",
"line_id": "…",
"calculation_id": "…",
"order_ref": "4711",
"quantity": 12,
"placed": 12,
"net_area_mm2": 21840.5,
"outline": [[0, 0], [300, 0], [300, 120], [0, 120]],
"holes": [[[40, 40], [80, 40], [80, 80], [40, 80]]]
}
],
"sheets": [
{
"key": "0:0",
"index": 0,
"group": 0,
"repeat": 2,
"container": {"kind": "format", "key": "3000 x 1500", "length_mm": 3000, "width_mm": 1500},
"material": "S235JR",
"gauge_mm": 3,
"margin_mm": 10,
"spacing_mm": 5,
"count": 17,
"utilisation": 0.71,
"remnant": {"x_mm": 2100, "y_mm": 0, "length_mm": 900, "width_mm": 1500},
"placements": [
{"part": "P1", "line_id": "…", "order_ref": "4711", "x": 10, "y": 10, "rot_deg": 90, "mirrored": false}
]
}
]
}
| Field | Meaning |
|---|---|
v, units |
The schema version (1) and the unit of every length (mm). |
source |
What the plan is of: kind run (with run_id, environment_id, created_at, finished_at) or calculation (with calculation_id). |
tolerance |
What the contours are good to. |
parts[] |
One per job-nest line (or the one part): ref names it in placements and in the DXF block PART_<ref>; outline runs counter-clockwise, each ring of holes clockwise, in the part's own frame; quantity copies ordered, placed on the sheets; line_id re-enters a quote as nest_item_id. |
sheets[] |
key names the sheet in sheet= and in file names (<group>:<index>; 0 for a calculation's sheet); group the material and thickness it belongs to; repeat identical sheets it stands for; container what it is cut from (format or remnant, the key you stated, its size); material, gauge_mm; margin_mm and spacing_mm every copy keeps; count copies on the sheet; utilisation their net area over the sheet's; remnant the reusable rest, when one is left. |
placements[] |
One per copy: part, and where it sits — mirrored across its own x axis first when mirrored, then turned rot_deg counter-clockwise about its origin, then set at (x, y). |
A placement's contour on the sheet is therefore, for each point (px, py) of
the part's outline: flip py when mirrored, rotate by rot_deg, add
(x, y). That is exactly the DXF insert's transform.
6. Labels for the rests
Once the job nest is released (PATCH /nest-runs/{run_id} with
counts_toward_savings: true), the reusable rests its sheets leave are
remnants of the environment. Print their rack labels in one go:
curl -o rests.svg \
"https://api.arcnm.io/api/v1/nest-runs/$RUN_ID/remnant-labels?lang=de" \
-H "X-API-Key: $ARCNM_API_KEY"
One SVG, one label per rest, sized in millimetres (100 × 50 mm each) —
print at 100 %. Each label carries the size, thickness, material, pieces,
origin and date, and a Code 128 barcode of the piece's code, the first
12 hex digits of its id. A single piece's label is
GET /remnants/{remnant_id}/label. When the piece comes off the rack, the
scanner's reading finds it again in any state:
curl "https://api.arcnm.io/api/v1/remnants/by-code/3F9A0C12B7D4" \
-H "X-API-Key: $ARCNM_API_KEY"
404 nest_run_no_rests says the job nest put nothing into stock — not
released yet, no reusable rest, or an environment that does not credit
remnants (then a release books no stock at all).
7. From an agent
The MCP tools arcnm_nest_run_export and arcnm_sheet_nest_export answer
the plan inline for format="json" (past 256 KB, without the contours) and,
for DXF and SVG, each sheet's download link — the same routes as above, to
fetch with the API key. See MCP for agents.