Przejdź do głównej treści
Na tej stronie▾

Engine API

Jeśli po prostu tniesz płyty, ta strona nie jest Ci potrzebna. Optymalizator w CutOptim robi już wszystko to, co jest tu opisane. Engine API to ten sam silnik, tylko bez ekranu — na wypadek, gdy inne oprogramowanie potrzebuje planów cięcia bez tego, żeby ktoś otwierał aplikację.

Wszystko, co CutOptim robi w Twojej przeglądarce, zaczyna się od jednego obliczenia: mając te elementy i ten materiał bazowy, jak najlepiej je pociąć? Engine API udostępnia dokładnie to obliczenie przez internet, więc pytanie może zadać inny program i sam otrzymać odpowiedź — bez przeglądarki, bez klikania, bez nikogo zalogowanego.

I to cała idea. To nie nowy optymalizator, nie lepszy optymalizator i nie większy plan. To ten sam silnik, dostępny dla oprogramowania zamiast dla człowieka.


Czy to jest dla mnie?

Dla zdecydowanej większości użytkowników CutOptim uczciwa odpowiedź brzmi nie. Jeśli Twój dzień pracy polega na otwarciu CutOptim, wpisaniu elementów i materiału bazowego oraz wydrukowaniu albo wyeksportowaniu planu, to aplikacja jest produktem, a ta strona jest dla Ciebie bez znaczenia.

Engine API jest dla jednej sytuacji: plany cięcia mają pojawiać się wewnątrz oprogramowania, z którego już korzystasz, bez tego, żeby ktokolwiek wchodził na CutOptim. W praktyce oznacza to jedną z dwóch osób:

  • Już korzystasz z oprogramowania, w którym plan cięcia powinien się znaleźć. System ERP prowadzący Twoje zamówienia, narzędzie ofertowe wyceniające zlecenia albo oprogramowanie samej maszyny. Zamiast operatora przepisującego tę samą listę elementów do CutOptim, ten program pyta silnik bezpośrednio i pokazuje plan tam, gdzie praca już się dzieje.
  • Ktoś buduje dla Ciebie oprogramowanie. Własny programista, lokalna firma informatyczna albo dostawca Twojej maszyny. Engine API jest tym, do czego się oni podłączają.

Korzystanie z Engine API oznacza, że ktoś pisze do niego oprogramowanie. Nie ma tu interfejsu, nie ma arkusza do wypełnienia i nie ma czego instalować — to usługa dla programów, a pracę wykonuje ten, kto pisze ten program. Jeśli po Twojej stronie nikt nie pisze kodu, to aplikacja jest tym, czego szukasz.

Jeśli nie masz pewności, po której stronie tej granicy jesteś, oto dobry test: czy plan mógłby pojawić się bez tego, żeby ktokolwiek o niego poprosił? Jeśli tak, API ma dla Ciebie znaczenie. Jeśli o powstaniu planu cięcia zawsze decyduje człowiek, aplikacja jest już właściwym narzędziem.


Co robi

Twoje oprogramowanie przesyła te same dwie rzeczy, które wpisałbyś w aplikacji — listę elementów i listę materiału bazowego — w formacie JSON. Silnik odsyła pełną odpowiedź:

  • Cały układ. Każdy element umieszczony na konkretnej płycie lub pręcie, wraz z informacją, czy został obrócony.
  • Plan cięcia. Nie tylko obrazek z prostokątami: rzeczywista gilotynowa sekwencja cięcia, po kolei, tak żeby plan dało się wykonać na pile panelowej.
  • Liczby. Ile płyt albo prętów zajmie zlecenie, procentowe wykorzystanie materiału, ile potrzeba cięć oraz łączna cena zużytego materiału. Przy płytach otrzymujesz też dwie uczciwe miary liczby cięć — linie cięcia, które scalają cięcia korzystające z jednego ustawienia prowadnicy, oraz przejścia piły, które liczą każde przejście — a do tego łączną długość cięcia.
  • Opcjonalnie rysunek. Poproś o include: ["svg","csv","dxf"], a odpowiedź poniesie też układ jako gotowy plik — samodzielny rysunek 2D SVG, plik DXF R12/AC1009 albo listę cięć CSV — w treści JSON, bez magazynowania i bez drugiego wywołania. (SVG dotyczy tylko 2D.) W żądaniach 2D można też poprosić o labels (dane etykiet dla każdej części), planHash (odcisk planu), pdf (PDF planu cięcia) i labelsPdf (PDF z etykietami) — PDF-y zakodowane w base64, rysowane tym samym kodem co w aplikacji.
  • Twoje własne identyfikatory, zwrócone. Dołącz obiekt meta — numer artykułu, pozycję zamówienia, referencję klienta — do dowolnego elementu lub wiersza materiału bazowego, a wróci on niezmieniony przy każdym rozmieszczonym kawałku i każdej płycie lub pręcie, dzięki czemu plan pokrywa się z Twoim własnym systemem. To właśnie tego pola należy użyć, gdy chcesz wysłać wszystkie swoje płyty, oznaczyć każdą własnym kodem i odczytać z odpowiedzi, którą płytę wybrał optymalizator — wpisz kod w stock[].meta, a wróci on w sheets[].meta. Nigdy nie wpływa to na rozmieszczenie. Do identyfikacji nie używaj pola material: material to twardy podział — element wycinany jest wyłącznie z materiału bazowego o tym samym materiale — więc wypełnienie pola material we wszystkich wierszach materiału bazowego przy pozostawieniu elementów bez tego pola sprawia, że każdy element wraca jako unmatched, a wynik jest pusty.

Tryby optymalizacji są cztery, wszystkie odpowiadają aplikacji — jeden dla płyt 2D, jeden dla materiału 1D liniowego (pręty, profile, rury), jeden dla drewna, którego materiał ma przekrój, oraz nesting z rzeczywistych kształtów (POST /v1/optimize/nest), który układa dowolne wielokąty do cięcia laserowego, plazmowego i strumieniem wody (tryb Nesting aplikacji). Każdy endpoint optymalizacji ma też bezpłatny endpoint walidacji, który sprawdza zapytanie bez jego rozwiązywania (patrz niżej).

Endpointy

Bazowy URL to https://api.cutoptim.com. Endpointy optymalizacji i zużycia przenoszą klucz w nagłówku Authorization: Bearer <key>; endpointy walidacji i zdrowia nie wymagają klucza.

Endpoint Co robi
POST /v1/optimize/2d optymalizacja cięcia płyt 2D
POST /v1/optimize/1d optymalizacja 1D / liniowa — pręty, profile, rury
POST /v1/optimize/wood Optymalizacja drewna — 1D z dopasowaniem przekroju
POST /v1/optimize/nest Nesting kształtów rzeczywistych — nieregularne wielokąty do cięcia laserem, plazmą i strumieniem wody
POST /v1/validate/2d · /1d · /wood · /nest Walidacja zapytania bez rozwiązywania — bezpłatnie, bez klucza, bez limitu
GET /v1/jobs/{id} Odpytaj asynchroniczne zadanie silnika max — wyłącznie własne zadania, bez limitu
POST /v1/import/nest Odczytuje obrysy elementów z pliku SVG lub DXF — wymaga klucza, nie zużywa limitu
GET /v1/usage zużycie i limit KONTA w bieżącym miesiącu (wszystkie klucze dzielą jeden)
GET /v1/health sprawdzenie dostępności — nie wymaga klucza

Większość wywołań od razu zwraca gotowy wynik. Jedynym wyjątkiem jest asynchroniczny silnik max (patrz Trzy silniki poniżej): zgłoszenie max zwraca identyfikator zadania, a Ty odpytujesz GET /v1/jobs/{id}, aż plan będzie gotowy.

Endpointy walidacji przyjmują tę samą treść co odpowiadający im endpoint optymalizacji i sprawdzają ją bez uruchamiania obliczeń: błędnie sformułowane zapytanie wraca jako 400 z nazwą dokładnie tego pola, które jest nie tak, a poprawne zwraca valid: true wraz z ostrzeżeniami o wykonalności (na przykład o elemencie, który nie pasuje do żadnego materiału bazowego). Nic nie kosztują i nie wymagają klucza, więc możesz walidować swoje ładunki podczas budowania integracji — jeszcze zanim będziesz mieć klucz — i potwierdzić, że zapytanie nie zostanie odrzucone, bez zużywania jednego z miesięcznych wywołań.

Kierunek usłojenia w płytach

Sklejka i płyty fornirowane mają usłojenie, a widoczny element trzeba wyciąć tak, by biegło we właściwą stronę. W POST /v1/optimize/2d wyślij grain w pozycji materiału — "w" lub "h", czyli bok płyty, wzdłuż którego biegnie usłojenie — oraz grain w elemencie, czyli bok elementu, wzdłuż którego usłojenie ma biec. Każdy taki element jest układany z usłojeniem zgodnym z usłojeniem jego płyty: obrócony o 90°, jeśli tego wymaga (rotated: true przy rozmieszczeniu, jak przy każdym obrocie), a rotatable jest dla niego ignorowane. Element bez grain nadal obraca się swobodnie, także na pozycji materiału bez grain (MDF, melamina); element Z grain zachowuje również na takiej pozycji orientację, jaką nadają mu pozycje z usłojeniem — płyty z usłojeniem i gładkie rozdziela material. Element, który zmieściłby się tylko obrócony o 90° wbrew usłojeniu, trafia do unplaced w wysłanym rozmiarze, wiersz w warnings go wymienia, a POST /v1/validate/2d zgłasza to, zanim zużyje się wywołanie.

Pozycje materiału, których usłojenie biegnie w różnych kierunkach, mogą być w jednym zapytaniu — na przykład 2440 × 1220 z "w" i 1220 × 2440 z "h" — a każda płyta wraca w orientacji własnej pozycji, z grain zwróconym w sheets[]. Przy material element jest trzymany przy usłojeniu tylko wtedy, gdy jego własny materiał ma płytę z usłojeniem. grain elementu bez materiału z usłojeniem w zapytaniu nie ma wpływu, a linia w warnings o tym informuje. options.trim i wymuszone options.firstCut obowiązują na każdej płycie w orientacji jej własnej pozycji materiału, także w pozycji, której usłojenie biegnie w drugą stronę. Tryb Kierunek usłojenia w aplikacji CutOptim uruchamia ten sam kod. (Od 2026-10-02.)

Dopasowanie słojów w płytach (zestawy)

Kierunek usłojenia pilnuje, by słoje każdego elementu biegły we właściwą stronę. Niektóre fronty wymagają więcej: front szuflady nad dwojgiem drzwi, którego rysunek słojów przechodzi z jednego elementu na drugi, jakby te trzy wciąż były jedną płytą. W POST /v1/optimize/2d nadaj tym wierszom elementów id i nazwij je w matchedSets:

{
  "parts": [
    { "id": "DF", "name": "Drawer front", "w": 48.125, "h": 6 },
    { "id": "DOOR", "name": "Door", "w": 24, "h": 30, "qty": 2 },
    { "name": "Shelf", "w": 22.5, "h": 11.25, "qty": 4 }
  ],
  "stock": [{ "w": 96, "h": 48, "qty": 2, "grain": "w" }],
  "options": { "kerf": 0.125 },
  "matchedSets": [
    { "id": "base-1", "name": "Base cabinet fronts", "grain": "w",
      "layout": { "dir": "rows", "lines": [["DF"], ["DOOR", "DOOR"]] } }
  ]
}
  • Czym jest zestaw. layout.lines wylicza członków według parts[].id. Przy dir: "rows" każda linia to rząd członków obok siebie, a rzędy układają się od góry do dołu, więc [["DF"], ["DOOR", "DOOR"]] to front szuflady nad dwojgiem drzwi; przy "cols" każda linia to kolumna, a kolumny stoją obok siebie. Element może wystąpić w jednym zestawie więcej niż raz (Drzwi, Drzwi), ale może należeć tylko do jednego zestawu. qty (domyślnie 1) to liczba potrzebnych egzemplarzy — trzy jednakowe szafki to qty: 3 — a własne qty elementów musi pokrywać każdy egzemplarz. Zestaw ma co najmniej 2 i najwyżej 24 członków, a jedno zapytanie przyjmuje najwyżej 50 zestawów.
  • Jak jest cięty. Zestaw przechodzi przez optymalizator jako jeden prostokąt — blok — i wraca jako jego członkowie, w odstępie dokładnie jednego rzazu, z jednego kawałka płyty. grain zestawu ("w" lub "h", wzdłuż szerokości albo wysokości bloku) decyduje o kierunku każdego członka; własne grain członka nie jest w zestawie używane, a ostrzeżenie wymienia każdego członka, którego nadpisuje. Bez grain zestawu blok może się obrócić, gdy każdy członek jest rotatable. installGap to szczelina między członkami na szafce (domyślnie: rzaz); na płycie nadal stoją w odstępie jednego rzazu.
  • Co wraca. Każdy umieszczony członek niesie matchedSet: id zestawu, który instance oraz jego position w kolejności czytania na froncie szafki — z góry na dół, od lewej do prawej, od 1 — a także hint, na przykład "left" albo "right", tam gdzie to jednoznaczne. Odpowiedź dodaje zbiorcze matchedSets, po jednym wpisie na zestaw: jego letter (A, B … w kolejności zapytania), ile egzemplarzy wycięto jako jeden blok (asBlock), podzielono lub zostawiono bez miejsca, rozmiar bloku i warnings zestawu. Gdy blok nie mieści się na żadnej płycie, onMiss: "split" (domyślnie) umieszcza członków pojedynczo z ostrzeżeniem, a onMiss: "unplaced" wypisuje ich w unplaced.
  • Ostrzeżenia, nie błędy. Wymiar, który się nie zgadza, to ostrzeżenie przy zestawie, a nie odmowa. Każdy wiersz zaczyna się od swojego kodu — align: (linie nie są równe), gap: (rzaz jest szerszy niż installGap), grain:, split:, unplaced:, unmatched: (brak materiału bazowego z materiałem zestawu), priority: i grainGroup: — a align i gap są oceniane z dokładnością 1/64 Twojej jednostki albo ćwierć rzazu, zależnie od tego, co mniejsze. Zestaw, którego nie da się w ogóle ułożyć — identyfikator członka, którego nie ma żaden element, identyfikator użyty w dwóch elementach, mniej niż dwóch członków, za mało elementów na qty — to 400 wskazujące dokładne pole, zanim wywołanie zostanie naliczone.
  • parts[].id można bezpiecznie wysyłać. Sprawdzany jest tylko identyfikator, do którego odwołuje się zestaw (niepusty drukowalny ciąg do 64 znaków albo liczba całkowita, w dokładnie jednym elemencie). Każdy inny id jest ignorowany, cokolwiek zawiera, więc numery artykułów z Twojego ERP mogą zostać w wierszach. Dla zapytania bez zestawów nic się nie zmienia: funkcję włącza wyłącznie niepusta tablica matchedSets — brak pola, null, [] lub dowolna wartość niebędąca tablicą jest obsługiwana dokładnie jak dotąd.
  • Eksporty. Przy zestawach csv dostaje na końcu kolumny Set i Position, svg drukuje kod pozycji (A1, A2 …) w etykietach elementów i rysuje ramkę każdego zestawu w osobnej grupie matched-sets — options.setOutlines: false pomija tę grupę — a dxf niesie kod pozycji na warstwie LABELS. pdf i labelsPdf nie oznaczają zestawów: rysują członków jak zwykłe elementy, a warnings o tym informuje; oznaczenia zestawów są w sheets[].parts[].matchedSet, csv i svg.
  • Silniki i endpointy. Silniki heuristic i balanced układają zestawy (balanced nie ocenia priority, więc przy respectStock zestaw może tam stracić swoje miejsce, z ostrzeżeniem priority:). Silnik max odrzuca niepuste matchedSets kodem 400, w którego details.unsupported jest to nazwane, zanim wywołanie zostanie naliczone; puste to zwykłe zlecenie max. matchedSets i parts[].id dotyczą tylko 2D: endpointy 1D, wood i nest je ignorują.
  • grainGroup jest przestarzałe. Nadal jest przyjmowane i działa dokładnie tak jak dotąd: elementy z jednej grupy są trzymane na jednej płycie. Nigdy nie układało ich obok siebie, więc nie daje ciągłych słojów — do tego użyj matchedSets.

Funkcja Dopasowanie słojów w aplikacji CutOptim układa zestawy tym samym rdzeniem.

Dlaczego drewno ma własny endpoint

Materiał liniowy zna jeden wymiar, długość, więc każdy pręt może posłużyć każdemu elementowi. Z drewnem tak nie jest: elementu 50×150 nie da się wyciąć z pręta 50×100, niezależnie od tego, ile długości zostało. Dlatego endpoint drewna przyjmuje oba boki przekroju przy każdym elemencie i każdej pozycji materiału, dzieli zlecenie według przekroju, dopasowuje do każdego przekroju jego własny materiał i zwraca przekroje osobno — każdy z własnymi prętami i własnymi sumami, obok liczb dla całego zlecenia.

Dwa szczegóły warte poznania przed integracją:

  • Oba boki przekroju można podać w dowolnej kolejności. 50×100 i 100×50 to ta sama belka obrócona i trafiają do jednego przekroju. Różnica w tym, jak akurat wprowadzono Twoje dane, nie może więc sprawić, że materiał zniknie.

  • „Brak materiału o tym przekroju” i „nie zmieściło się” są raportowane osobno. Pierwsze to brak materiału, drugie to problem pojemności, a każdy naprawia się inaczej — zmieszane w jednej liście wysłałyby Twojego użytkownika w złe miejsce.

Można to przybliżyć kilkoma własnymi wywołaniami 1d, grupując elementy samodzielnie. Kosztowałoby to jedno zapytanie z Twojego limitu na przekrój zamiast jednego na zlecenie, przeniosłoby dopasowanie materiału do Twojego kodu i dałoby sumę zlecenia, którą musiałbyś złożyć sam — i która niekoniecznie zgadzałaby się z tym, co dla tego samego zlecenia pokazuje aplikacja CutOptim.


Elementy z pliku CAD

Endpoint nestingu przyjmuje nie tylko współrzędne. Element może zamiast nich nieść source — dokument SVG lub DXF — a serwer odczyta z pliku jego obrys wraz z otworami. To ten sam czytnik, którego używa aplikacja, gdy upuścisz rysunek na jej tryb Nesting, więc biblioteki elementów istniejącej już jako pliki CAD nie trzeba najpierw przepisywać na listy współrzędnych.

Plik zastępuje wyłącznie geometrię. Ilość, materiał, dozwolone obroty i Twoje własne metadane pozostają zwykłymi polami wiersza elementu, dokładnie tak jak przy wysyłaniu współrzędnych. Jeden plik opisuje jeden element; gdy pojedynczy rysunek zawiera kilka oddzielnych części, POST /v1/import/nest najpierw dzieli go na gotowe wiersze — a to wywołanie wymaga klucza, lecz nie zużywa żądania z Twojego miesięcznego limitu.

Nic nie jest przechowywane. Plik istnieje wyłącznie jako samo żądanie: jest czytany w pamięci i znika w chwili, gdy odpowiedź zostaje zapisana. Nie zostaje kopia na dysku ani w bazie danych, nic nie trafia do logu i nie ma potem czego usuwać. Z jednostkami postępujemy tak samo — DXF może zadeklarować milimetry lub cale i my zgłaszamy to, co zadeklarował, ale współrzędne nigdy nie są przeliczane, bo żadna wartość w tym API nie niesie jednostki.

Za każdym razem ta sama odpowiedź

Silnik jest deterministyczny: te same dane wejściowe zawsze zwracają ten sam wynik. W algorytmie nie ma żadnej losowości ani zegara.

Brzmi to akademicko, ale to właśnie praktyczny powód, żeby na tym budować. Oznacza bowiem, że wyniki można buforować — jeśli o dokładnie to zlecenie już raz zapytałeś, możesz bezpiecznie użyć wcześniejszej odpowiedzi, zamiast pytać ponownie. Oznacza też, że integrację można testować: plan da się porównać ze znanym, poprawnym wynikiem, a różnica jest wtedy prawdziwą różnicą, a nie szumem. Oprogramowanie, które w poniedziałek podaje klientowi cenę, w piątek podaje tę samą cenę.

Jest jeden opcjonalny wyjątek, i mówi o tym wprost: silnik nestingu max (poniżej) poświęca ustalony budżet czasu na przeszukiwanie, więc to, jak daleko dojdzie, zależy od tego, ile pracy zmieści się w tym czasie. Jego odpowiedzi niosą deterministic: false. Każdy inny silnik — łącznie z domyślnym silnikiem nestingu, lbf — jest deterministyczny.

Bezpieczne ponawianie. Gdy połączenie zostanie zerwane, nie wiadomo, czy żądanie dotarło. Wyślij nagłówek Idempotency-Key — wartość wybraną dla każdego zadania — i ponów z tym samym kluczem: przez 24 godziny to samo żądanie zwraca zapisaną odpowiedź, oznaczoną Idempotency-Replayed: true, i nie jest naliczane drugi raz. Zadanie max też nie trafi do kolejki dwa razy. Publiczny klucz demo ignoruje ten nagłówek. (Od 2026-10-15.)

Webhooki dla zadań asynchronicznych. Zamiast odpytywać GET /v1/jobs/{id}, zarejestruj w panelu endpoint (URL https://) i otrzymaj podpisany POST — job.succeeded albo job.failed — gdy asynchroniczne zadanie max się zakończy. Sprawdź nagłówek CutOptim-Signature otrzymanym sekretem, odpowiedz w ciągu 10 sekund, a plan odczytaj przez GET /v1/jobs/{id}. Nieudane doręczenie jest ponawiane: 8 prób w ciągu 24 godzin. (Od 2026-10-19.)

Oficjalne SDK. Klienty open source dla TypeScript, Pythona i PHP — npm install @cutoptim/engine, pip install cutoptim, composer require cutoptim/engine — z typowanymi żądaniami, ponowieniami, które nigdy nie są liczone podwójnie (każde wywołanie niesie Idempotency-Key), pomocnikiem do czekania na zadania asynchroniczne i weryfikacją webhooków. Kod na GitHubie; szczegóły w przewodniku po SDK (po angielsku).

Serwer MCP dla asystentów AI. Claude Code, Cursor, VS Code i Claude Desktop mogą wywoływać silnik jako narzędzia przez hostowany serwer Model Context Protocol pod adresem https://api.cutoptim.com/mcp, z tym samym kluczem API (Authorization: Bearer …) i z tego samego limitu: jedno wywołanie narzędzia to jedno wywołanie API, a narzędzia validate_* są bezpłatne. Można go też uruchomić lokalnie pakietem npx -y @cutoptim/mcp (klucz w CUTOPTIM_API_KEY), a oficjalny MCP Registry wymienia go jako io.github.cutoptim/engine. Konfiguracje klientów są w przewodniku MCP (po angielsku).


Trzy silniki

API daje wybór silnika. Pierwsze dwa działają synchronicznie, trzeci jest asynchroniczny. Różnica nie polega na jakości — to kompromis między szybkością, tym, czy wynik da się pociąć na pile panelowej, i tym, jak blisko dochodzi do teoretycznego minimum.

  • heuristic jest domyślny i jest tym samym, którego używa aplikacja. Tworzy układy gilotynowe: najwyższe wykorzystanie materiału, każdy układ da się pociąć na pile panelowej i zawsze pełny plan cięcia. Synchroniczny.
  • balanced trzeba włączyć samemu. Korzysta zamiast tego ze swobodnego nestingu, który przy bardzo dużych zleceniach jest zdecydowanie szybszy — zmierzone ~25× szybciej przy zleceniu na 2000 elementów — za cenę nieco niższego wykorzystania materiału. Ważne zastrzeżenie: jego układów często nie da się pociąć od krawędzi do krawędzi, więc dla nich nie zwraca żadnego planu cięcia. Synchroniczny.
  • max trzeba włączyć samemu i dotyczy płyt 2D (a osobno także nestingu kształtów rzeczywistych — patrz niżej). W 2D to przeszukiwanie drzewa po stronie serwera, które osiąga dowiedzione optimum przy znacznie większej liczbie zleceń niż silnik domyślny, a jego układy nadal da się pociąć gilotynowo. Kosztem jest czas: obliczenie max trwa od sekund do minuty, więc nie odpowiada w treści zapytania. Zamiast tego POST /v1/optimize/2d z engine: "max" zwraca identyfikator zadania, a Ty odpytujesz GET /v1/jobs/{id}, aż będzie gotowy. Jest nadal deterministyczny. Sięgnij po niego, gdy przy dużym, wartościowym zleceniu warto poczekać na ostatnich kilka płyt. Modeluje jeden format materiału w pełnym rozmiarze płyty, w nieograniczonej ilości, więc żądanie zawierające dodatkowo drugi format materiału, trim na bok, ograniczony zapas (respectStock), materiały, grupy słojów lub niepuste matchedSets jest odrzucane z góry kodem 400, który nazywa dokładnie to, czego silnik nie potrafi — zanim wywołanie zostanie naliczone. Takie zlecenia kieruj do heuristic, który obsługuje je wszystkie.

Nesting: lbf i max

Nesting kształtów rzeczywistych ma dwa własne silniki. lbf jest domyślny: natychmiastowy, synchroniczny i deterministyczny. max trzeba włączyć samemu i jest asynchroniczny, dokładnie jak max dla 2D — POST /v1/optimize/nest z engine: "max" zwraca identyfikator zadania, a Ty odpytujesz GET /v1/jobs/{id}.

Nesting max najpierw wykonuje przebieg lbf, więc zawsze ma pod ręką ważną odpowiedź. Następnie poświęca budżet czasu (options.timeBudgetMs, domyślnie 60 sekund, od 10 do 180) na szukanie układu z mniejszą liczbą płyt, wypełniając po jednej płycie naraz. Nigdy nie zwraca więcej płyt niż lbf: gdy przeszukiwanie nie znajdzie poprawy, otrzymujesz układ lbf wraz z ostrzeżeniem, które to mówi. Ponieważ przeszukiwanie jest ograniczone czasowo, jego odpowiedzi niosą deterministic: false. Przyjmuje kilka rozmiarów płyt na materiał oraz respectStock i ocenia swój wynik według tej samej zasady co lbf (poniżej): zastępuje plan lbf tylko wtedy, gdy jest lepszy — nigdy tylko dlatego, że ma mniej płyt. Płyta w kształcie wielokąta albo strefy wykluczeń, których jego przeszukiwanie pasmowe nie potrafi modelować, są obsługiwane przez przebieg lbf wewnątrz zadania, z ostrzeżeniem — nigdy nie są odrzucane. Starsza nazwa sparrow jest przyjmowana jako alias max.

Prostokątne elementy dostają dokładną siatkę (od 2026-09-28). lbf wyszukuje pozycje przez próbkowanie, które prawie nigdy nie trafia w siatkę bez żadnego luzu: trzy elementy 500 mm na szerokości płyty 1500 mm przy zerowym odstępie mieszczą się dokładnie, a przeszukiwanie przez próbkowanie rozmieszcza dwa. Dlatego oba silniki próbują też dwóch wariantów i zachowują ten, który wypada najlepiej według tej samej zasady: elementy ograniczone do kątów prostych, na które pozwalają, oraz prostokąty otaczające elementów ułożone dokładnym algorytmem pakowania prostokątów (prostokąty, które się nie nakładają, nie mogą zawierać nakładających się elementów, więc działa to dla dowolnego konturu). Przy remisie — te same płyty, ta sama powierzchnia płyt — wygrywa plan, który wypełnia płyty od przodu do tyłu, a potem ten z mniejszą liczbą elementów obróconych poza kąty proste. Nie trzeba niczego włączać, a wynik może się według rankingu tylko poprawić; plan, który prostokąty sprowadzają do najmniejszej liczby płyt, na jaką pozwala powierzchnia elementów, sprawia też, że max odpowiada od razu, zamiast szukać.

Zlecenie liczące kilkadziesiąt elementów zwykle potrzebuje budżetu około 15 sekund (timeBudgetMs: 15000); zadanie kończy się mniej więcej jedną do dwóch sekund po upływie budżetu, plus czas spędzony w kolejce. Odpytuj GET /v1/jobs/{id} co dwie do trzech sekund — odpytywanie nie zużywa limitu. Żaden budżet nie może obiecać konkretnej liczby płyt.

Nesting: prześwit przy krawędzi, rozmiary płyt i koszt każdej płyty

  • Prześwit przy krawędzi. options.minSeparation to odstęp między elementami, i sam w sobie stosuje się też przy krawędzi płyty. options.edgeClearance ustawia krawędź osobno — na przykład 5 między elementami i 0 albo 10 przy krawędzi. Pomiń go, a krawędź zachowuje minSeparation, dokładnie jak wcześniej. Działa w obu silnikach, wymaga prostokątnych płyt (w i h), a strefy wykluczeń zachowują minSeparation tak jak elementy. Płyta w kształcie wielokąta albo wartość, która nie zostawia miejsca na płycie, jest odrzucana kodem 400, zanim wywołanie zostanie naliczone.
  • Wybór rozmiaru płyty. Gdy materiał ma dwa lub więcej wierszy materiału bazowego, lbf próbuje ich w Twojej kolejności, każdy rozmiar osobno i w kolejności od najtańszego, i zachowuje najlepszy wynik — więc wynik nie zależy już od kolejności, w jakiej podasz wiersze. Ranking to: najwięcej rozmieszczonych elementów obowiązkowych (patrz niżej), potem najwięcej rozmieszczonych elementów, potem najmniejsza łączna powierzchnia płyt (materiał), a na końcu najmniejsza liczba płyt. Z options.minimizeCost ranking opiera się zamiast tego na łącznej cenie (price, albo cost dla wiersza bez ceny) — ale tylko wtedy, gdy każdy wiersz tego materiału ją niesie; w przeciwnym razie wraca do powierzchni i mówi o tym w warnings.
  • Mieszanie rozmiarów. Następnie każda płyta — zaczynając od najsłabiej wypełnionej — jest ponownie nestowana osobno na tańszych lub mniejszych wierszach i zastępowana, gdy cały plan wypada lepiej w rankingu. Dzięki temu rozmiary mogą być mieszane w obrębie jednego materiału: zwykle dwie duże płyty i mniejsza ostatnia, tam gdzie do połowy pusta ostatnia płyta bywała dużą. Z options.respectStock żaden wiersz nie jest użyty częściej niż jego qty. Silnik max stosuje ten sam ranking.
  • Elementy obowiązkowe. parts[].priority: true oznacza element, który musi zostać wycięty. Ma to znaczenie z options.respectStock — ograniczonym zapasem, gdzie nie każdy element może się zmieścić: elementy obowiązkowe są wtedy rozmieszczane jako pierwsze, więc zwykły element nigdy nie zajmuje miejsca na płycie, którego potrzebuje element obowiązkowy, a każdy ranking powyżej stawia wyżej plan, który zachowuje ich więcej, nawet jeśli rozmieszcza mniej elementów łącznie. Oba silniki to respektują (max zachowuje układ lbf, gdy cokolwiek pozostaje nierozmieszczone). Bez respectStock każdy pasujący element i tak zostaje rozmieszczony, więc znacznik niczego nie zmienia. Element obowiązkowy, który nie mieści się na żadnej płycie, nadal jest wymieniony w unplaced. (Od 2026-09-22 — wcześniej silnik nestingu przyjmował to pole, ale je ignorował.)
  • Ograniczony zapas, na który nie wszystko się mieści. Przy options.respectStock, gdy plan wciąż zostawia nierozmieszczone elementy, silnik dodatkowo wypełnia arkusze po kolei prostokątami obejmującymi elementy — każdy tak pełno, jak się da, a element pasujący tylko do jednego rozmiaru arkusza trafia tam najpierw (wysoki bok na jedyny duży arkusz, nie na pasek z odpadu). Ten plan jest przyjmowany tylko wtedy, gdy rozmieszcza więcej elementów (najpierw obowiązkowe) albo zużywa mniej materiału; zlecenie, w którym wszystko się mieści, wraca dokładnie jak dotąd. Respektuje dozwolone obroty każdego elementu, minSeparation i edgeClearance. (Od 2026-10-14.)
  • Ile kosztowała każda płyta. Każda płyta niesie stock — indeks wiersza materiału bazowego z żądania, z którego została wycięta — a odpowiedź dodaje stockUsage: jeden wpis na każdy użyty wiersz materiału bazowego, z liczbą płyt, łączną ceną i gęstością. Jednostką jest wiersz materiału bazowego, nie rozmiar: dwa wiersze o tym samym rozmiarze, ale innej cenie lub meta, to dwa wpisy.
  • Długość cięcia i przebicia. Każda płyta niesie cutLength — sumę obwodów obrysów i otworów rozmieszczonych na niej elementów, w Twojej jednostce — oraz pierces, jedno na każdy zamknięty kontur; metrics sumuje oba. To geometryczna długość konturu: bez cięcia wspólną linią, najazdów/wyjazdów ani mikropołączeń — dokłada je Twój CAM.
  • Wykorzystana powierzchnia, do naliczania opłaty za część arkusza. Każda płyta niesie usedWidth i usedHeight — najdalszy punkt, do którego sięga dowolny rozmieszczony element, licząc od narożnika początkowego płyty, w Twojej jednostce, na rzeczywistej płycie (przy edgeClearance odstęp od krawędzi jest wliczony) — oraz usedArea, ich iloczyn; stockUsage[].usedArea sumuje to dla każdego wiersza materiału bazowego. To liczby, których ERP potrzebuje, by naliczyć opłatę za cięcie poziome (usedHeight × szerokość płyty), cięcie pionowe (usedWidth × wysokość płyty) albo prostokąt otaczający (usedArea) zamiast całego arkusza — reguła naliczania zostaje po Twojej stronie. Aby te liczby były małe, oba silniki domyślnie zagęszczają najsłabiej wypełnioną płytę każdego materiału: jej elementy są ponownie nestowane na tej samej płycie z podzbiorami obrotów, które dopuszcza każdy element — 0/180, 0/90/180/270 i jedna orientacja dla każdej kopii, przecięte z dyskretnym allowedRotations, nigdy nowy kąt — a zachowywany jest układ o najmniejszej wykorzystanej powierzchni. Przy engine: "max" tę płytę układa potem ponownie także samo wyszukiwanie — wzdłuż wysokości płyty, a gdy plan ma tylko jedną płytę, także wzdłuż jej szerokości — i według tej samej reguły zachowuje ciaśniejszy układ. Liczba płyt, ich rozmiary, cena i rozmieszczone elementy nigdy się nie zmieniają; options.compact: false zwraca układ niezagęszczony. Jeśli naliczasz opłatę za pas, a nie za prostokąt otaczający, ustaw odpowiednio options.compactFor: "horizontal" zachowuje układ o najniższym usedHeight (pas na całej szerokości płyty), "vertical" — o najmniejszym usedWidth (pas na całej wysokości płyty); domyślna wartość "box" zachowuje najmniejsze usedArea. Tryby pasowe próbują też każdej kopii obróconej o ćwierć obrotu (90° lub 270°), tam gdzie pozwala na to allowedRotations. To, jak mała staje się wykorzystana powierzchnia, zależy od elementów. (Od 2026-09-22.)

balanced to nie „lepsze wyniki”. Jest szybszy i daje nieco niższe wykorzystanie materiału, a gdy jego układ nie jest gilotynowy, nie ma planu cięcia, który dałoby się podać operatorowi piły. Wybierz go tylko wtedy, gdy przy bardzo dużym zleceniu szybkość liczy się bardziej niż plan gotowy na piłę. Jeśli nie masz pewności, zostań przy domyślnym.


Limity

Każde zapytanie ma swoje granice, więc zlecenie, które wymknęło się z ręki, kończy się wyraźnym błędem, a nie zawieszeniem:

Limit Wartość
Elementów na zapytanie 2000
Wierszy materiału bazowego na zapytanie 50
Rozmiar treści zapytania 1 MB
Rozmiar treści żądania — ścieżki nest, które mogą nieść rysunek 10 MB
Aktywnych kluczy na konto 10
Wywołania validate bez klucza na adres 120 / minutę
Nieznane klucze API na adres 30 / minutę — potem 429 do końca minuty
Oczekiwanie na wolne miejsce obliczeń (ścieżki synchroniczne) ok. 8 s — potem 429, bez opłaty
Zadania max w stanie queued/running na konto 5
Budżet przeszukiwania nestingu max na zadanie 10–180 s (domyślnie 60 s)
Przechowywanie Idempotency-Key 24 godziny
Endpointy webhooków na konto 5
Próby doręczenia webhooka 8 w ciągu 24 godzin

Uzyskanie dostępu

Zacznij od strony Engine API. Engine API jest rozliczane osobno od planów aplikacji i żadna zmiana planu go nie włącza.

  1. Wypróbuj, potem wykup — albo napisz. API możesz wywołać, zanim zapłacisz: przyciski Uruchom ten przykład w dokumentacji API używają publicznego klucza demo, a każde zalogowane konto może w panelu utworzyć bezpłatne klucze testowe (własny, niewielki miesięczny limit, nigdy nie są rozliczane, subskrypcja niepotrzebna). Gdy będziesz gotowy, wykupienie na stronie Engine API to najszybsza droga — plan wstępny, Studio, startuje z bezpłatnym okresem próbnym, a dostęp sam pojawia się na koncie. Jeśli wolisz najpierw opisać swoją integrację albo potrzebujesz wolumenu powyżej planu standardowego, napisz do nas i podaj, co chcesz podłączyć i mniej więcej ile planów cięcia miesięcznie będzie potrzebnych.
  2. Dostęp zostaje dodany do Twojego konta. Nic więcej w Twoim koncie się nie zmienia.
  3. Utwórz klucz. Karta klucze API jest w Twoim panelu dla każdego zalogowanego konta: bez subskrypcji tworzy klucze testowe, z dostępem do API także klucze live. Klucze tworzysz tam, nazywasz i usuwasz samodzielnie.
  4. Skopiuj klucz od razu. Pełny klucz pokazywany jest dokładnie raz, w chwili jego utworzenia.

Klucz pokazywany jest tylko raz. CutOptim przechowuje wyłącznie jego skrót sha256, nigdy samego klucza — więc później nie odczyta go ani Ty, ani my. Przy tworzeniu skopiuj go od razu do konfiguracji swojego oprogramowania. Jeśli zgubisz klucz, usuń go i utwórz nowy; jeśli klucz kiedykolwiek wycieknie, usuń go, a wywołania natychmiast przestaną działać.

Traktuj klucz jak hasło: jego miejsce jest w konfiguracji Twojego oprogramowania, a nie w emailu, arkuszu kalkulacyjnym czy na zrzucie ekranu.

Co robi karta Klucze API w panelu

Cztery elementy — i warto precyzyjnie powiedzieć, co zmienia każdy z nich, zwłaszcza ostatni, po którym wiele osób spodziewa się wpływu na płatności. Nie ma go.

  • Plan, zmiana planu i Rozliczenia. Pokazuje, na którym planie jest konto (Studio albo Scale). Przejdź na Scale (albo Przejdź na Studio) zmienia plan po potwierdzeniu, a miesięczny limit konta zmienia się od razu. Rozliczenia otwiera ustawienia rozliczeń, gdzie aktualizujesz kartę, oglądasz faktury albo rezygnujesz.
  • Utwórz klucz. Generuje nowy klucz i pokazuje go tylko raz, od razu. Nazwa (Integracja ERP, staging) służy wyłącznie do rozróżniania kluczy później. Do 10 aktywnych kluczy na konto. Klucze testowe tworzy się tak samo i liczy osobno: mają własny, niewielki miesięczny limit i nigdy nie są rozliczane.
  • Pasek zużycia. Dwie liczby: łączne zużycie konta w miesiącu kalendarzowym wobec limitu oraz, dla każdego klucza, ile zużył. Wartość per klucz odpowiada na pytanie, która integracja zjada pulę — nie jest osobnym budżetem.
  • Wycofaj. Wyłącza ten jeden klucz od następnego wywołania. Wiersz pozostaje widoczny, żeby historia nie zniknęła.

Wycofanie klucza nie ma nic wspólnego z subskrypcją. Nic nie anuluje, nic nie zwraca i nie zwalnia limitu — plan działa dalej, pula zostaje, po prostu nie masz już tego jednego klucza. Wycofuj, gdy klucz wyciekł albo integracja jest wygaszana. Aby przestać płacić, anuluj subskrypcję: dostęp trwa wtedy do końca opłaconego okresu, a potem przestają działać nawet istniejące klucze.

Jeden limit na konto, nie po jednym na klucz

Każdy aktywny klucz Twojego konta czerpie z tej samej miesięcznej puli. Utworzenie drugiego klucza nie tworzy drugiego limitu — klucze służą do oddzielenia stagingu od produkcji, nadania każdej integracji własnych poświadczeń i wycofania jednego bez ruszania pozostałych.

GET /v1/usage podaje stan konta (used, limit, remaining), więc odpowiada na pytanie, które faktycznie masz — ile zostało, zanim wywołania zaczną się nie udawać — niezależnie od tego, którym kluczem zapytałeś. Gdy pula się skończy, każdy klucz zwraca 402, nie tylko ten, który ją zużył.


Plany, cena i limit zapytań

Engine API rozliczane jest osobno od planów aplikacji, co miesiąc, w EUR, w dwóch planach:

Plan Czym się różni
Studio Plan wstępny, z bezpłatnym okresem próbnym
Scale Większy miesięczny limit zapytań, bez okresu próbnego — przechodzi się na niego ze Studio

Cała reszta jest taka sama w obu: te same silniki, wszystkie cztery tryby, każda opcja, te same odpowiedzi. Każde zapytanie liczy się tak samo — zlecenie nestingu kosztuje jedno zapytanie, dokładnie jak zlecenie 2D albo 1D.

  • Twardy limit, bez dopłat za przekroczenie. Gdy miesięczny limit zostanie wyczerpany, wywołania zwracają 402, aż odnowi się on pierwszego dnia następnego miesiąca. Żadnej niespodzianki na fakturze.
  • Dwa e-maile, żeby limit Cię nie zaskoczył. Wysyłamy e-mail na adres konta przy 90% limitu i jeszcze raz, gdy limit zostanie wyczerpany.
  • Zmiana planu to jeden przycisk na karcie kluczy API w Twoim panelu (Przejdź na Scale / Przejdź na Studio); nowy limit obowiązuje od razu. Przejście na wyższy plan jest rozliczane od razu za resztę okresu; przy przejściu na niższy nie ma zwrotu, a niższa cena obowiązuje od następnego odnowienia. Zmiana jest dostępna po okresie próbnym.
  • Większe wolumeny niż w planie Scale wyceniamy indywidualnie — napisz do nas.

Aktualne ceny i limity zapytań są podane na stronie Engine API — ta strona czyta je z naszej konfiguracji cennika, więc pokazuje zawsze prawidłową wartość.

Szczegóły techniczne — dokładną strukturę zapytania i odpowiedzi, wszystkie opcje, wszystkie kody błędów oraz sposób wersjonowania — znajdziesz w dokumentacji API.


Komponenty open source

Silniki CutOptim opierają się na bibliotekach open source, używanych na naszych serwerach bez modyfikacji:

  • jagua-rs — geometryczny silnik kolizji stojący za nestingiem kształtów rzeczywistych (MPL-2.0).
  • sparrow — przeszukiwanie stojące za silnikiem nestingu max (MIT, KU Leuven).
  • PackingSolver — przeszukiwanie drzewa stojące za silnikiem max dla 2D (MIT).

Wszystko wokół nich — API, mapowanie między kontraktem a tymi silnikami, packery prostokątne i sama aplikacja — to własny kod CutOptim.


Czego to nie zmienia

Warto powiedzieć to wprost, bo Engine API łatwo błędnie odczytać jako zmianę w produkcie:

  • Optymalizator w aplikacji pozostaje bez zmian. Nadal działa w Twojej przeglądarce, dokładnie tak jak wcześniej.
  • Plany Bezpłatny, Pro i Warsztat są nienaruszone. Nadal zawierają optymalizator w aplikacji, z tymi samymi limitami co wcześniej. Nic nie zostało przeniesione za API.
  • Nic, co robisz w aplikacji, nie zużywa zapytań API. Miesięczny limit API zużywają wyłącznie wywołania wykonywane przez Twoje własne oprogramowanie.

Engine API to dodatek dla osób integrujących CutOptim z innym oprogramowaniem. Jeśli to nie Ty, nic się nie zmieniło.

FAQ

Czym różnią się plany Studio i Scale?
Tylko miesięcznym limitem zapytań i okresem próbnym. Oba plany uruchamiają te same silniki, wszystkie cztery tryby i każdą opcję, a każde zapytanie liczy się tak samo — zlecenie nestingu kosztuje jedno zapytanie, dokładnie jak zlecenie 2D. Studio to plan wstępny z bezpłatnym okresem próbnym; Scale ma większy miesięczny limit i nie ma okresu próbnego, ponieważ przechodzi się na niego ze Studio. Aktualne ceny i limity są na stronie Engine API.
Czy mogę przechodzić między planami Studio i Scale?
Tak, po zakończeniu okresu próbnego i pierwszej udanej płatności, przyciskiem Przejdź na Scale (albo Przejdź na Studio) na karcie kluczy API w Twoim panelu. Nowy miesięczny limit obowiązuje Twoje konto od razu. Przejście na wyższy plan jest rozliczane od razu za resztę okresu rozliczeniowego; przy przejściu na niższy nie ma zwrotu, a niższa cena obowiązuje od następnego odnowienia.
Czy mogę wypróbować API, zanim zapłacę?
Tak, na dwa sposoby. Dokumentacja API ma przyciski Uruchom ten przykład, które używają publicznego klucza demo, bez żadnego konta — tylko małe zlecenia. Poza tym każde zalogowane konto CutOptim może utworzyć w panelu klucze testowe: mają własny, niewielki miesięczny limit, nigdy nie są rozliczane i nie wymagają subskrypcji, więc całą integrację zbudujesz jeszcze przed zakupem. Studio startuje potem z bezpłatnym okresem próbnym.
Czy dostanę ostrzeżenie, zanim skończy się mój miesięczny limit?
Tak. Wysyłamy e-mail na adres konta, gdy zużyjesz 90% miesięcznego limitu, i jeszcze raz, gdy limit zostanie wyczerpany. Potem wywołania zwracają 402, aż limit odnowi się pierwszego dnia następnego miesiąca — albo od razu, jeśli przejdziesz na większy plan.
Czy potrzebuję Engine API?
Prawie na pewno nie. Jeśli tniesz płyty albo pręty, otwierając CutOptim w przeglądarce, aplikacja robi już wszystko to, co robi API — API to ten sam silnik, tylko bez ekranu. Istnieje wyłącznie dla jednej sytuacji: inne oprogramowanie potrzebuje planów cięcia bez tego, żeby ktoś otwierał aplikację. Jeśli nikt nie pisze kodu korzystającego z CutOptim, możesz o nim zapomnieć.
Dla kogo Engine API jest naprawdę przeznaczone?
Dla dwóch rodzajów klientów: dla kogoś, kto już korzysta z oprogramowania, w którym plan cięcia powinien się znaleźć — systemu ERP prowadzącego zamówienia, narzędzia ofertowego wyceniającego zlecenia, oprogramowania samej maszyny — oraz dla kogoś, komu takie oprogramowanie jest właśnie budowane, przez własnego programistę albo firmę zewnętrzną. W obu przypadkach pracę wykonuje ten, kto pisze to oprogramowanie, a nie Ty w interfejsie CutOptim.
Jak uzyskać dostęp do Engine API?
Możesz wykupić dostęp na stronie Engine API — działa z okresem próbnym, a dostęp sam pojawia się na koncie. To najszybsza droga. Jeśli wolisz najpierw opisać integrację albo potrzebujesz wolumenu powyżej planu standardowego, napisz do nas. Tak czy inaczej klucze live tworzysz potem samodzielnie na karcie Klucze API w panelu. Engine API jest rozliczane osobno od planów aplikacji i żadna zmiana planu go nie włącza.
Czy Engine API tnie też drewno, czy tylko płyty i pręty?
Wszystkie cztery tryby, które ma aplikacja: płyty, pręty, drewno i nesting true-shape. Endpoint drewna zna przekrój: elementy i materiał niosą oba boki przekroju, więc element 50×150 wycinany jest wyłącznie z materiału 50×150. Zlecenie dzielone jest według przekroju i każdy przekrój wraca z własnymi prętami i sumami, a zapotrzebowanie, dla którego przekroju nie ma żadnego materiału, raportowane jest osobno od elementów, które materiał miały i się nie zmieściły.
Czy Engine API zmienia mój plan Bezpłatny, Pro albo Warsztat?
Nie. Engine API to osobny dodatek i nie zmienia niczego w zwykłych planach. Optymalizator w aplikacji pozostaje bez zmian, nadal działa w Twojej przeglądarce i nadal jest zawarty w planach Bezpłatnym, Pro i Warsztat dokładnie tak jak wcześniej. Nic, co robisz w aplikacji, nie zużywa zapytań API.
Czy do Engine API jest SDK albo biblioteka kliencka?
Tak. Oficjalne SDK open source są dla TypeScript (npm @cutoptim/engine), Pythona (PyPI cutoptim) i PHP (Composer cutoptim/engine) — kod na github.com/cutoptim, przewodnik pod /engine/reference/guides/sdks. Są opcjonalne: API pozostaje zwykłym HTTPS z JSON, które każdy język wywoła bez pakietu CutOptim. Dla zadań asynchronicznych są webhooki: zarejestruj endpoint w panelu, a zamiast odpytywać dostaniesz podpisany POST, gdy zadanie max się zakończy. Większość wywołań od razu zwraca gotowy wynik; jedynym wyjątkiem jest asynchroniczny silnik max — dla płyt 2D oraz dla nestingu kształtów rzeczywistych — gdzie POST /v1/optimize/2d albo /v1/optimize/nest z engine "max" zwraca identyfikator zadania, który odpytujesz przez GET /v1/jobs/{id}, aż wynik będzie gotowy.
Czy silnik balanced jest lepszy od domyślnego?
Nie — to kompromis, a nie ulepszenie. Domyślny silnik heuristic daje najwyższe wykorzystanie materiału i każdy jego układ da się pociąć na pile panelowej, więc zawsze zwraca plan cięcia. Silnik balanced jest znacznie szybszy przy bardzo dużych zleceniach, ale wykorzystanie materiału jest nieco niższe, a jego układów często nie da się pociąć od krawędzi do krawędzi, więc dla nich nie zwraca żadnego planu cięcia. Wybieraj go tylko wtedy, gdy przy dużym zleceniu szybkość liczy się bardziej niż plan gotowy na piłę.
Dlaczego mój klucz API pokazywany jest tylko raz?
Ponieważ CutOptim nigdy nie przechowuje samego klucza — tylko jego skrót sha256. Oznacza to, że nikt, także my, nie odczyta Twojego klucza z bazy danych, więc można go pokazać wyłącznie w chwili jego utworzenia. Skopiuj go od razu do konfiguracji swojego oprogramowania; jeśli go zgubisz, usuń ten klucz i utwórz nowy.
Co się dzieje, gdy wycofam klucz API — dostanę zwrot pieniędzy?
Nie, i nic to też nie anuluje. Wycofanie wyłącza ten jeden klucz od następnego wywołania; subskrypcja działa dalej, a miesięczny limit zostaje. Wycofaj klucz, gdy wyciekł albo integracja jest wygaszana, i utwórz zastępczy. Aby przestać płacić, anuluj subskrypcję — dostęp trwa wtedy do końca opłaconego okresu, a potem przestają działać nawet istniejące klucze.
Czy utworzenie większej liczby kluczy API daje więcej zapytań?
Nie. Miesięczny limit należy do konta, a każdy aktywny klucz czerpie z tej samej puli — drugi klucz nie dodaje drugiego limitu. Klucze służą do oddzielenia stagingu od produkcji, nadania każdej integracji własnych poświadczeń i wycofania jednego bez ruszania pozostałych. Gdy pula się skończy, każdy klucz zwraca 402, nie tylko ten, który ją zużył. GET /v1/usage podaje stan konta, niezależnie od użytego klucza.
Czy Engine API może zwrócić rysunek, a nie tylko współrzędne?
Tak. Dodaj include: ["svg","csv","dxf"] do zapytania optymalizacji, a odpowiedź poniesie układ jako gotowy plik, w treści JSON: samodzielny rysunek 2D SVG, plik DXF R12/AC1009 na warstwach STOCK/PARTS/LABELS albo listę cięć CSV. Nie ma magazynowania ani drugiego wywołania. SVG dotyczy tylko 2D; zapytanie 1D lub wood zwraca zamiast tego ostrzeżenie. Możesz też dołączyć obiekt meta (numer artykułu z ERP, identyfikator pozycji zamówienia albo referencję klienta) do dowolnego elementu lub wiersza materiału bazowego, a wróci on niezmieniony w wyniku, dzięki czemu plan uzgadnia się z Twoim systemem. Pole meta służy też do odczytania, którą płytę wybrał optymalizator: wpisz swój kod w stock[].meta, a wróci on w sheets[].meta, i nigdy nie wpływa to na rozmieszczenie. Do identyfikacji nie używaj pola material — material to twardy podział (element wycinany jest wyłącznie z materiału bazowego o tym samym materiale), więc wypełnienie pola material we wszystkich wierszach materiału bazowego przy pozostawieniu elementów bez tego pola sprawia, że każdy element wraca jako unmatched, a wynik jest pusty.
Czy mogę sprawdzić zapytanie bez zużywania jednego z miesięcznych wywołań?
Tak. POST /v1/validate/2d, /v1/validate/1d, /v1/validate/wood albo /v1/validate/nest przyjmuje tę samą treść co odpowiadający mu endpoint optymalizacji i sprawdza ją bez rozwiązywania — bezpłatnie, bez klucza API i bez zużycia limitu. Błędnie sformułowane zapytanie wraca jako 400 z nazwą dokładnie tego pola, które jest nie tak, a poprawne zwraca valid: true wraz z ostrzeżeniami o wykonalności (na przykład o elemencie, który nie pasuje do żadnego materiału bazowego). Używaj tego do walidacji ładunków podczas budowania integracji, jeszcze zanim będziesz mieć klucz.
Co dzieje się z plikiem SVG lub DXF wysłanym do API?
Nic z niego nie zostaje. Plik podróżuje jako treść żądania, jest czytany w pamięci po to, by uzyskać obrys elementu, i znika, gdy tylko odpowiedź zostanie zapisana — żadnej kopii na dysku, żadnej kopii w bazie danych, żadnego wpisu w logu, który by go zawierał, a więc nie ma potem czego usuwać ani o jaki okres przechowywania pytać. To ta sama bezstanowość, którą utrzymuje reszta API: Twoich planów cięcia też nie trzymamy dłużej niż żądanie, które je wytworzyło.
Czy nesting kształtów rzeczywistych też ma silnik max?
Tak. POST /v1/optimize/nest z engine "max" jest asynchroniczny, tak samo jak max dla 2D: wywołanie odpowiada kodem 202 z identyfikatorem zadania, który odpytujesz przez GET /v1/jobs/{id}. Najpierw wykonuje natychmiastowy przebieg lbf, a następnie poświęca budżet czasu — domyślnie 60 sekund, od 10 do 180 przez options.timeBudgetMs — szukając układu z mniejszą liczbą płyt, wypełniając po jednej płycie naraz. Nigdy nie zwraca więcej płyt niż dałby lbf; gdy nie znajdzie poprawy, otrzymujesz układ lbf wraz z ostrzeżeniem, które to mówi. Ponieważ przeszukiwanie jest ograniczone czasowo, jego odpowiedzi niosą deterministic: false. Przyjmuje kilka rozmiarów płyt na materiał oraz respectStock i zachowuje własny wynik tylko wtedy, gdy jest lepszy w rankingu niż plan lbf (według ceny z options.minimizeCost, w przeciwnym razie według powierzchni płyty). Płyta w kształcie wielokąta albo strefy wykluczeń, których jego przeszukiwanie nie potrafi modelować, są obsługiwane przez przebieg lbf wewnątrz zadania z ostrzeżeniem — nigdy nie są odrzucane.
Dlaczego prostokątne elementy z nestingu wracały przechylone albo na dodatkowej płycie?
Przed 2026-09-28 mogło się tak zdarzyć: silnik nestingu lbf wyszukuje pozycje przez próbkowanie, więc przy swobodnym obrocie mógł obrócić prawie prostokątny element o ułamek stopnia i rzadko znajdował siatkę bez żadnego luzu, taką jak trzy elementy 500 mm na szerokości płyty 1500 mm przy zerowym odstępie. Oba silniki nestingu próbują teraz także ustawić elementy pod kątami prostymi, na które pozwalają, i układają prostokąty otaczające elementów dokładnym algorytmem pakowania prostokątów, po czym zachowują plan, który wypada najlepiej w rankingu; przy remisie wygrywa plan, który wypełnia płyty od przodu do tyłu, a potem ten z mniejszą liczbą przechylonych elementów. Nie musisz nic zmieniać w zapytaniu. Jeśli Twoje elementy nigdy nie mogą zejść z kątów prostych, wysyłaj allowedRotations: [0, 90, 180, 270] jak dotychczas.
Czy mogę ustawić prześwit przy krawędzi płyty osobno od odstępu między elementami?
Tak. options.minSeparation to odstęp między elementami, i sam w sobie stosuje się też przy krawędzi płyty. Dodaj options.edgeClearance, aby ustawić krawędź osobno — na przykład 5 między elementami i 0 albo 10 przy krawędzi. Działa w obu silnikach nestingu, a jeśli go pominiesz, krawędź zachowuje minSeparation dokładnie jak wcześniej. Wymaga prostokątnych płyt (w i h): przy płycie w kształcie wielokąta albo przy wartości, która nie zostawia miejsca na płycie, zapytanie jest odrzucane kodem 400, zanim wywołanie zostanie naliczone. Strefy wykluczeń zachowują minSeparation, tak jak elementy.
Jak nesting wybiera spośród kilku rozmiarów płyt?
Gdy materiał ma dwa lub więcej wierszy materiału bazowego, silnik lbf próbuje ich w Twojej kolejności, każdy rozmiar osobno i w kolejności od najtańszego, i zachowuje najlepszy wynik — więc odpowiedź nie zależy już od tego, który wiersz podasz jako pierwszy. Ranking opiera się na: najwięcej rozmieszczonych elementów obowiązkowych (elementów oznaczonych priority, co ma znaczenie przy options.respectStock), potem na największej liczbie rozmieszczonych elementów, potem na najmniejszej łącznej powierzchni płyt; z options.minimizeCost ranking opiera się zamiast tego na łącznej cenie (price, albo cost, gdy wiersz nie ma ceny), pod warunkiem że każdy wiersz tego materiału ją ma. Następnie każda płyta, zaczynając od najsłabiej wypełnionej, jest ponownie nestowana osobno na tańszych lub mniejszych wierszach i zastępowana, gdy cały plan wypada lepiej w rankingu — dzięki czemu rozmiary mogą być mieszane w obrębie jednego materiału: zwykle dwie duże płyty i mniejsza ostatnia. Z options.respectStock żaden wiersz nie jest użyty częściej niż jego qty. Odpowiedź podaje, z którego wiersza pochodzi każda płyta (sheets[].stock) i sumuje płyty, cenę i gęstość dla każdego wiersza (stockUsage). Silnik max stosuje ten sam ranking.
Czy mogę oznaczyć elementy nestingu jako obowiązkowe do cięcia?
Tak: parts[].priority: true. Ma to znaczenie, gdy zapas płyt jest ograniczony (options.respectStock), bo wtedy nie każdy element może się zmieścić: elementy obowiązkowe są rozmieszczane jako pierwsze, więc zwykły element nigdy nie zajmuje miejsca na płycie, którego potrzebuje element obowiązkowy, a każde porównanie planów wyżej rankinguje plan, który zachowuje ich więcej. Oba silniki nestingu to respektują. Bez respectStock każdy pasujący element i tak zostaje rozmieszczony, więc znacznik niczego nie zmienia. Element obowiązkowy, który nie mieści się na żadnej płycie, nadal wraca w unplaced. (Przed 2026-09-22 silnik nestingu przyjmował to pole, lecz go nie stosował.)
Czy odpowiedź nestingu zawiera długość cięcia?
Tak. Każda płyta niesie cutLength — sumę obwodów obrysów zewnętrznych i otworów rozmieszczonych na niej elementów, w Twojej jednostce — oraz pierces, jedno na każdy zamknięty kontur (obrys każdego elementu plus jedno na każdy otwór); metrics sumuje oba dla całego zlecenia. To geometryczna długość konturu: cięcie wspólną linią, najazdy/wyjazdy i mikropołączenia nie są uwzględnione, bo dokłada je CAM Twojej maszyny — więc to solidna podstawa do czasu maszynowego i materiałów eksploatacyjnych, a nie ostateczna ścieżka narzędzia.
Czy mogę policzyć opłatę tylko za wykorzystaną część arkusza?
API daje Ci liczby; reguła naliczania opłaty zostaje po Twojej stronie. Każda płyta niesie usedWidth i usedHeight — najdalszy punkt, do którego sięga dowolny rozmieszczony element, mierzony od narożnika początkowego płyty, w Twojej jednostce — oraz usedArea, ich iloczyn; stockUsage[].usedArea sumuje to dla każdego wiersza materiału bazowego. Cięcie poziome to usedHeight × szerokość płyty, cięcie pionowe to usedWidth × wysokość płyty, a prostokąt otaczający to usedArea. Oba silniki nestingu domyślnie zagęszczają też najsłabiej wypełnioną płytę każdego materiału: jej elementy są ponownie nestowane na tej samej płycie z podzbiorami obrotów, które dopuszcza każdy element (0/180, 0/90/180/270, jedna orientacja dla każdej kopii — nigdy nowy kąt), a zachowywany jest układ o najmniejszej wykorzystanej powierzchni. Liczba płyt, ich rozmiary, cena i rozmieszczone elementy nigdy się nie zmieniają. options.compact: false zwraca układ niezagęszczony. Jeśli naliczasz opłatę za pas, a nie za prostokąt otaczający, ustaw options.compactFor na "horizontal" (najniższa wykorzystana wysokość, dla pasa na całej szerokości płyty) lub "vertical" (najmniejsza wykorzystana szerokość, dla pasa na całej wysokości płyty); domyślna wartość "box" minimalizuje wykorzystaną powierzchnię. To, jak mała staje się wykorzystana powierzchnia, zależy od elementów, więc żadnego ułamka płyty nie da się obiecać z góry.
Ile budżetu czasu powinienem dać silnikowi max dla nestingu?
Zadanie kończy się mniej więcej jedną do dwóch sekund po upływie budżetu, plus czas oczekiwania w kolejce. Dla zlecenia liczącego kilkadziesiąt elementów zwykle wystarczy 15 sekund (options.timeBudgetMs: 15000); wartość domyślna to 60 sekund, a zakres to od 10 do 180. Większy budżet daje przeszukiwaniu więcej szans na zaoszczędzenie płyty, ale żaden budżet nie może obiecać konkretnej liczby płyt — zależy ona od elementów i odstępów. Odpytuj GET /v1/jobs/{id} co dwie do trzech sekund; odpytywanie nie zużywa limitu.
Czy API może uwzględnić kierunek usłojenia elementu?
Tak. W POST /v1/optimize/2d podaj w pozycji materiału grain: "w" lub "h" — bok płyty, wzdłuż którego biegnie usłojenie — a w elemencie grain: "w" lub "h" — bok elementu, wzdłuż którego usłojenie ma biec. Każdy taki element jest układany z usłojeniem zgodnym z usłojeniem jego płyty, w razie potrzeby obrócony o 90° (rotated: true), a rotatable jest dla niego wtedy ignorowane. Można mieszać pozycje materiału, których usłojenie biegnie w różnych kierunkach. Przy material liczą się tylko płyty z materiału danego elementu. Każda płyta zwraca w odpowiedzi grain swojej pozycji. Jeśli żadna pozycja materiału nie ma usłojenia, grain elementu nie ma wpływu, a warnings o tym informuje. Obsługują to wszystkie trzy silniki 2D (max — ze swoją zwykłą jedną pozycją materiału).
Czy API potrafi wyciąć dopasowane fronty tak, żeby słoje przechodziły z jednego elementu na drugi?
Tak, w POST /v1/optimize/2d. Nadaj wierszom elementów id i nazwij je w matchedSets — dla frontu szuflady nad dwojgiem drzwi: układ z dir rows i liniami [DF] oraz [DOOR, DOOR]. Zestaw jest wycinany obok siebie z jednego kawałka płyty, w odstępie dokładnie jednego rzazu, a słoje zestawu decydują o kierunku każdego członka. Każdy umieszczony członek wraca z matchedSet (identyfikator zestawu, egzemplarz i pozycja), a odpowiedź dodaje zbiorcze matchedSets, którego warnings mówią na przykład, że wymiary do siebie nie pasują. Silniki heuristic i balanced układają zestawy; silnik max odrzuca niepuste matchedSets kodem 400, zanim wywołanie zostanie naliczone. Eksporty pdf i labelsPdf rysują członków jak zwykłe elementy, a odpowiedź ostrzega o tym; csv, svg i dxf oznaczają zestawy. Bez niepustej tablicy matchedSets nic się nie zmienia, a parts[].id jest sprawdzane tylko w wierszach, które nazywa zestaw.
Czy grainGroup jest nadal obsługiwane?
Tak. grainGroup jest przestarzałe, ale nadal przyjmowane i działa dokładnie tak jak dotąd: elementy z jednej grupy są trzymane na jednej płycie. Nigdy nie układało ich obok siebie, więc nie daje ciągłych słojów — dla frontów, przez które rysunek słojów ma przechodzić dalej, użyj matchedSets. Silnik max odrzuca grainGroup, jak zawsze.

Zaktualizowano: 13 października 2026