Optimize timber
optimize_woodMetered: one Engine API call. Cut timber parts grouped by cross-section from matching stock lengths. Timber optimization (cross-section-aware 1D). Cut lengths from bars that have a CROSS-SECTION. Unlike /v1/optimize/1d, where every bar can serve every part, a 50×150 part can only come out of 50×150 stock — so the job is split by cross-section, each section is matched to its own stock and solved separately, and the response carries both per-section and job-wide totals.
Fanning the same job out into several /v1/optimize/1d calls is not equivalent: it costs one call per section against your quota, moves the stock matching to your code, and cannot distinguish "no material of this section" from "did not fit" — which this endpoint reports separately as unmatched and unplaced.
sw and sh may be given in either order: 50×100 and 100×50 are the same bar turned over and are matched as one section. The response reports the normalised short/long form.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| parts | Yes | ||
| stock | Yes | At most 50 rows. Since every cross-section needs at least one stock row, this is also the practical ceiling on cross-sections in a single job; a wider catalogue should be split into several requests. | |
| engine | No | As in 1D, `max` is not offered here (a **400** before a call is charged). `balanced` resolves to the same packer as `heuristic`: within a section a timber job is a length problem, and free nesting has nothing to offer it. The value is accepted, echoed back, and a warning states which packer actually ran. | heuristic |
| include | No | Three kinds of token. NARROWING (`cutPlan`, `offcuts`): omit the field entirely to get both; a present array keeps only the narrowing tokens it lists (an empty array drops both). ADDITIVE EXPORT (`svg`, `csv`, `dxf`): each adds an inline export STRING to the response (`svg` a standalone 2D layout — 2D only, a warning is returned for 1D/wood; `dxf` an R12/AC1009 drawing; `csv` a cut list, RFC 4180 quoted (a part name with a comma or a quote stays one field) and formula-injection-guarded (a name beginning with `=`, `+`, `-`, `@`, TAB or CR is prefixed with an apostrophe so a spreadsheet reads it as text, not a formula — CWE-1236). 2D DATA (`labels`, `planHash`, `pdf`, `labelsPdf`): `labels` adds per-piece label data (`labels[]`, see `Label2D`), `planHash` a 64-hex fingerprint of the plan (the same plan always gives the same hash), `pdf` the cutting-plan PDF and `labelsPdf` the label PDF, both base64-encoded and drawn by the same code as the CutOptim app. These four are 2D only: a 1D or wood request returns a `warnings` entry instead. `pdf` renders at most 500 parts (total quantity); a larger 2D request with `pdf` is a 413 `too_large` with `details.path: "include"`. Export and data tokens do not affect narrowing, so `["svg"]` adds svg and — listing no narrowing token — drops cutPlan/offcuts; use `["cutPlan","offcuts","svg"]` to keep everything. | |
| options | No | Identical to `Options1D` — a cross-section changes what fits, not how a bar is cut. |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| csv | No | ||
| dxf | No | ||
| engine | Yes | ||
| timing | Yes | ||
| cutPlan | No | ||
| metrics | Yes | ||
| sections | Yes | ||
| unplaced | Yes | ||
| warnings | Yes | ||
| unmatched | Yes | ||
| deterministic | Yes | ||
| engineVersion | Yes | ||
| contractVersion | Yes |