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ć olabels(dane etykiet dla każdej części),planHash(odcisk planu),pdf(PDF planu cięcia) ilabelsPdf(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 wstock[].meta, a wróci on wsheets[].meta. Nigdy nie wpływa to na rozmieszczenie. Do identyfikacji nie używaj polamaterial:materialto twardy podział — element wycinany jest wyłącznie z materiału bazowego o tym samym materiale — więc wypełnienie polamaterialwe wszystkich wierszach materiału bazowego przy pozostawieniu elementów bez tego pola sprawia, że każdy element wraca jakounmatched, 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.lineswylicza członków wedługparts[].id. Przydir: "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 toqty: 3— a własneqtyelementó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.
grainzestawu ("w"lub"h", wzdłuż szerokości albo wysokości bloku) decyduje o kierunku każdego członka; własnegrainczłonka nie jest w zestawie używane, a ostrzeżenie wymienia każdego członka, którego nadpisuje. Bezgrainzestawu blok może się obrócić, gdy każdy członek jestrotatable.installGapto 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:idzestawu, któryinstanceoraz jegopositionw kolejności czytania na froncie szafki — z góry na dół, od lewej do prawej, od 1 — a takżehint, na przykład"left"albo"right", tam gdzie to jednoznaczne. Odpowiedź dodaje zbiorczematchedSets, po jednym wpisie na zestaw: jegoletter(A, B … w kolejności zapytania), ile egzemplarzy wycięto jako jeden blok (asBlock), podzielono lub zostawiono bez miejsca, rozmiar bloku iwarningszestawu. Gdy blok nie mieści się na żadnej płycie,onMiss: "split"(domyślnie) umieszcza członków pojedynczo z ostrzeżeniem, aonMiss: "unplaced"wypisuje ich wunplaced. - 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:igrainGroup:— aalignigapsą 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 naqty— to400wskazujące dokładne pole, zanim wywołanie zostanie naliczone. parts[].idmoż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 innyidjest 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 tablicamatchedSets— brak pola,null,[]lub dowolna wartość niebędąca tablicą jest obsługiwana dokładnie jak dotąd.- Eksporty. Przy zestawach
csvdostaje na końcu kolumnySetiPosition,svgdrukuje kod pozycji (A1, A2 …) w etykietach elementów i rysuje ramkę każdego zestawu w osobnej grupiematched-sets—options.setOutlines: falsepomija tę grupę — adxfniesie kod pozycji na warstwie LABELS.pdfilabelsPdfnie oznaczają zestawów: rysują członków jak zwykłe elementy, awarningso tym informuje; oznaczenia zestawów są wsheets[].parts[].matchedSet,csvisvg. - Silniki i endpointy. Silniki
heuristicibalancedukładają zestawy (balancednie oceniapriority, więc przyrespectStockzestaw może tam stracić swoje miejsce, z ostrzeżeniempriority:). Silnikmaxodrzuca niepustematchedSetskodem400, w któregodetails.unsupportedjest to nazwane, zanim wywołanie zostanie naliczone; puste to zwykłe zleceniemax.matchedSetsiparts[].iddotyczą tylko 2D: endpointy 1D, wood i nest je ignorują. grainGroupjest 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żyjmatchedSets.
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.
heuristicjest 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.balancedtrzeba 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.maxtrzeba 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: obliczeniemaxtrwa od sekund do minuty, więc nie odpowiada w treści zapytania. Zamiast tegoPOST /v1/optimize/2dzengine: "max"zwraca identyfikator zadania, a Ty odpytujeszGET /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,trimna bok, ograniczony zapas (respectStock), materiały, grupy słojów lub niepustematchedSetsjest odrzucane z góry kodem400, który nazywa dokładnie to, czego silnik nie potrafi — zanim wywołanie zostanie naliczone. Takie zlecenia kieruj doheuristic, 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.minSeparationto odstęp między elementami, i sam w sobie stosuje się też przy krawędzi płyty.options.edgeClearanceustawia krawędź osobno — na przykład 5 między elementami i 0 albo 10 przy krawędzi. Pomiń go, a krawędź zachowujeminSeparation, dokładnie jak wcześniej. Działa w obu silnikach, wymaga prostokątnych płyt (wih), a strefy wykluczeń zachowująminSeparationtak jak elementy. Płyta w kształcie wielokąta albo wartość, która nie zostawia miejsca na płycie, jest odrzucana kodem400, zanim wywołanie zostanie naliczone. - Wybór rozmiaru płyty. Gdy materiał ma dwa lub więcej wierszy materiału bazowego,
lbfpró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. Zoptions.minimizeCostranking opiera się zamiast tego na łącznej cenie (price, albocostdla 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 wwarnings. - 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ż jegoqty. Silnikmaxstosuje ten sam ranking. - Elementy obowiązkowe.
parts[].priority: trueoznacza element, który musi zostać wycięty. Ma to znaczenie zoptions.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ą (maxzachowuje układlbf, gdy cokolwiek pozostaje nierozmieszczone). BezrespectStockkaż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 wunplaced. (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,minSeparationiedgeClearance. (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ź dodajestockUsage: 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 lubmeta, 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 — orazpierces, jedno na każdy zamknięty kontur;metricssumuje 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
usedWidthiusedHeight— 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 (przyedgeClearanceodstęp od krawędzi jest wliczony) — orazusedArea, ich iloczyn;stockUsage[].usedAreasumuje 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 dyskretnymallowedRotations, nigdy nowy kąt — a zachowywany jest układ o najmniejszej wykorzystanej powierzchni. Przyengine: "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: falsezwraca układ niezagęszczony. Jeśli naliczasz opłatę za pas, a nie za prostokąt otaczający, ustaw odpowiedniooptions.compactFor:"horizontal"zachowuje układ o najniższymusedHeight(pas na całej szerokości płyty),"vertical"— o najmniejszymusedWidth(pas na całej wysokości płyty); domyślna wartość"box"zachowuje najmniejszeusedArea. Tryby pasowe próbują też każdej kopii obróconej o ćwierć obrotu (90° lub 270°), tam gdzie pozwala na toallowedRotations. 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.
- 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.
- Dostęp zostaje dodany do Twojego konta. Nic więcej w Twoim koncie się nie zmienia.
- 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.
- 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
maxdla 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.