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/SVG/DXF; optional cutLayers/markLayers; returns storageRef, contour and markLayers

POST
/api/v1/frames

Custom-size frame — widthCm, heightCm, profileMm; 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": 25, "bandMm": 15, "pieceBarcode": true, "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, band and piece barcode. The same fields (wrapMm, bandMm, pieceBarcode, barcodeWidthMm, barcodeHeightMm, barcodePadMm) can be sent in the body — they override the recipe without touching shop settings. Per piece: barcodeText; no text, no barcode.

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