api v1

Wire nesting into your own system

The same engine as the app. The API is on the yearly plan. Authorisation with a key, export always through the queue — no request blocks while a PDF is being generated.

Authorisation

Bearer
curl https://rolcut.com/api/v1/me \ -H "Authorization: Bearer nv2_…"

You generate the key in the API keys section of the panel. We show the secret once.

The full round trip

4 steps
1. POST /api/v1/uploads → storageRef 2. POST /api/v1/preview → pages, fits 3. POST /api/v1/jobs → jobId 4. GET /api/v1/jobs/:id → print + cut

You can skip step 2 — the job works out the layout on its own.

endpoints

Everything that is in v1

GET
/api/v1/me

Organisation, plan, presets, usage this month

POST
/api/v1/uploads

Multipart with a files field — JPEG/PNG/TIFF/WebP/PDF/SVG/DXF; PDF = first page, TrimBox; optional cutLayers/markLayers; returns storageRef, contour and markLayers

POST
/api/v1/frames

Custom-size plate or window — widthCm, heightCm, kind=window|plate, clips; same response shape as upload

POST
/api/v1/preview

Layout without the PDFs: sheets, material costs, rejects with a suggested size

POST
/api/v1/jobs

Export job — jobName, recipeId, items with qty, placement optional

GET
/api/v1/jobs

Job history for the organisation

GET
/api/v1/jobs/:id

Status and references to the results

GET
/api/v1/files?ref=…

Download print.pdf, cut.pdf or cut.dxf

Print run in a single item

qty
{ "items": [ { "id": "a1", "storageRef": "s3://…", "widthCm": 60, "heightCm": 80, "qty": 24 } ] }

We fetch and embed the file once, whatever the print run. When a piece does not fit on the sheet, preview returns the largest size that still fits in the rejected field.

Recipe and material costs

recipeId
{ "jobName": "Smith / shop window", "recipeId": "…", "wrapMm": 30, "bandMm": 15, "borderMm": 0, "frameProfileMm": 30, "stapleMaxMm": 100, "printDpiMax": 180, "pieceBarcode": true, "colorSpace": "cmyk", "cmykProfile": "pso-coated-v3", "items": [ { "id": "a1", "storageRef": "s3://…", "widthCm": 70, "heightCm": 100, "qty": 4, "barcodeText": "250800123" } ] } // preview response "usage": { "mediaAreaM2": 8.74, "itemAreaM2": 7.2, "wastePct": 17.6, "linearM": 5.5, "costTotal": 34.96, "costPerPiece": 2.91 }

A recipe supplies the sheet, the pack and the cutter, and carries the cost per metre, bleed, wrap, stretcher rail, face border (borderMm, borderFill: empty|mirror|color, borderColor), knife corners, piece barcode, stretcher guides (frameProfileMm, stapleMaxMm), a pixel ceiling (printDpiMax, default 180 — downsample only, 0 = off) and print.pdf colour space (colorSpace: rgb|cmyk, cmykProfile: pso-coated-v3|fogra39|…). The same fields (wrapMm, bandMm, borderMm, borderFill, borderColor, cornerCut, cornerChamferMm, cornerRadiusMm, frameProfileMm, stapleMaxMm, printDpiMax, pieceBarcode, barcodeWidthMm, barcodeHeightMm, barcodePadMm, colorSpace, cmykProfile) can be sent in the body — they override the recipe without touching shop settings. Per piece: barcodeText; no text, no barcode. cornerCut: none|chamfer|round|both; chamfer is the 45° knife-line length (default 50 mm), round is R 25 mm; both = chamfer, then fillet. frameProfileMm (default 30) is the fold line on the stretcher profile; when wrap > 0 we raise wrap to the profile. stapleMaxMm (default 100) is the max staple gap in the clip-frame rhythm. Both are print.pdf only, when wrap/rail is on. PDF-in: first page, size from TrimBox.

Nesting by shape

trueShape
// uploads response "contour": [ [ [0.5, 0.02], [0.61, 0.35], [0.97, 0.36], … ] ] { "trueShape": true, "items": [ { "id": "a1", "storageRef": "s3://…", "widthCm": 40, "heightCm": 40, "qty": 24, "contour": [ … ] } ] }

Upload returns the silhouette (alpha, SVG or DXF) as a list of rings normalised to the file's rectangle (0..1, y down). Pass it back in contour on preview and jobs, and the pieces interlock and reach the cutter with a contour cut line instead of a rectangle. Files without transparency stay rectangles. Without this field the pack preset decides, and rotation then widens to 0 | 90 | 180 | 270.

Limits

The number of concurrent jobs and the number of files per job depend on your plan. Going over returns a 429 or a 402 with a readable message.

Isolation

Every file lands under the orgs/{orgId}/ prefix. A key from another organisation will not see your data.

Configuration

In the body you pass sheetId, packId and plotterId. Without them the shop's default presets apply.

Need a key?

Setting up an account takes a minute, and the key is in the panel straight away.

Create an account