Engine API
Wenn Sie einfach Platten zuschneiden, brauchen Sie diese Seite nicht. Der Optimierer in CutOptim macht bereits alles, was hier beschrieben wird. Die Engine API ist dieselbe Engine, nur ohne Bildschirm — für den Fall, dass andere Software Schnittpläne benötigt, ohne dass eine Person die App öffnet.
Alles, was CutOptim in Ihrem Browser tut, beginnt mit einer einzigen Berechnung: Wie schneidet man diese Teile aus diesem Ausgangsmaterial am besten zu? Die Engine API stellt genau diese Berechnung über das Internet bereit, sodass ein anderes Programm die Frage stellen und die Antwort zurückbekommen kann — kein Browser, kein Klicken, niemand angemeldet.
Das ist die ganze Idee. Es ist kein neuer Optimierer, kein besserer Optimierer und kein größerer Tarif. Es ist dieselbe Engine, erreichbar für Software statt für einen Menschen.
Ist das etwas für mich?
Für die überwältigende Mehrheit der CutOptim-Nutzer lautet die ehrliche Antwort nein. Wenn Ihr Arbeitstag darin besteht, CutOptim zu öffnen, Teile und Ausgangsmaterial einzutippen und den Plan zu drucken oder zu exportieren, dann ist die App das Produkt, und diese Seite ist für Sie ohne Belang.
Die Engine API ist für eine Situation gedacht: Schnittpläne sollen in Software erscheinen, die Sie bereits nutzen, ohne dass jemand CutOptim aufruft. In der Praxis heißt das eine von zwei Personen:
- Sie betreiben schon Software, in die der Schnittplan gehört. Ein ERP, das Ihre Aufträge führt, eine Angebotssoftware, die Aufträge kalkuliert, oder die Software einer Maschine. Anstatt dass eine Bedienerin oder ein Bediener dieselbe Teileliste erneut in CutOptim eintippt, fragt dieses Programm die Engine direkt und zeigt den Plan dort, wo die Arbeit ohnehin stattfindet.
- Sie lassen sich Software bauen. Von einem eigenen Entwickler, einem örtlichen Softwarehaus oder dem Lieferanten Ihrer Maschine. Die Engine API ist das, womit diese sich verbinden.
Die Engine API zu nutzen bedeutet, dass jemand Software dafür schreibt. Es gibt keine Oberfläche, keine Tabelle zum Ausfüllen und nichts zu installieren — sie ist ein Dienst für Programme, und die Arbeit erledigt derjenige, der dieses Programm schreibt. Wenn auf Ihrer Seite niemand Code schreibt, ist die App das, was Sie möchten.
Wenn Sie nicht sicher sind, auf welcher Seite dieser Linie Sie stehen, hilft ein guter Test: Könnte der Plan entstehen, ohne dass ihn jemand anfordert? Wenn ja, ist die API relevant. Wenn immer ein Mensch entscheidet, einen Schnittplan zu erstellen, ist die App bereits das richtige Werkzeug.
Was sie leistet
Ihre Software sendet dieselben zwei Dinge, die Sie auch in der App eintippen würden — eine Liste von Teilen und eine Liste von Ausgangsmaterial — als JSON. Die Engine sendet eine vollständige Antwort zurück:
- Das komplette Layout. Jedes Teil, positioniert auf einer bestimmten Platte oder einem bestimmten Stab, inklusive der Angabe, ob es gedreht wurde.
- Einen Schnittplan. Nicht bloß ein Bild aus Rechtecken: die tatsächliche Guillotine-Schnittsequenz in der richtigen Reihenfolge, damit sich der Plan auf einer Plattensäge ausführen lässt.
- Die Zahlen. Wie viele Platten oder Stäbe der Auftrag braucht, die Auslastung in Prozent, wie viele Schnitte nötig sind und den Gesamtpreis des verwendeten Materials. Für Platten erhalten Sie zusätzlich die zwei ehrlichen Schnittzählungen — Schnittlinien, die Schnitte mit derselben Anschlagseinstellung zusammenfasst, und Sägedurchgänge, die jeden Durchgang zählt — sowie die gesamte gesägte Länge.
- Optional die Zeichnung. Fordern Sie
include: ["svg","csv","dxf"]an, und die Antwort trägt das Layout zusätzlich als fertige Datei mit — eine eigenständige 2D-SVG-Zeichnung, ein DXF (R12/AC1009) oder eine CSV-Schnittliste — inline im JSON, ohne Speicherung und ohne zweiten Aufruf. (SVG nur in 2D.) Bei 2D-Anfragen gibt es außerdemlabels(Etikettendaten je Teil),planHash(einen Fingerabdruck des Plans),pdf(das PDF des Zuschnittplans) undlabelsPdf(das Etiketten-PDF) — die PDFs base64-kodiert, mit demselben Code gezeichnet wie in der App. - Ihre eigenen Kennungen, zurückgegeben. Hängen Sie an jedes Teil oder jede Materialzeile ein
meta-Objekt — eine Artikelnummer, eine Auftragsposition, eine Kundenreferenz — und es kommt bei jedem platzierten Stück und jeder Platte bzw. jedem Stab unverändert zurück, sodass der Plan mit Ihrem eigenen System zusammenpasst. Genau dieses Feld nehmen Sie, wenn Sie Ihr gesamtes Ausgangsmaterial senden, jede Zeile mit Ihrem eigenen Code kennzeichnen und zurücklesen möchten, welche Platte der Optimierer gewählt hat: Der Code gehört instock[].metaund kommt aufsheets[].metazurück. Auf die Platzierung wirkt er sich nie aus. Nutzen Sie zur Kennzeichnung nicht das Feldmaterial:materialist eine harte Trennung — ein Teil wird ausschließlich aus Ausgangsmaterial desselben Materials geschnitten. Kennzeichnen Sie also jedestock-Zeile mit einemmaterial, lassen die Teile aber ungekennzeichnet, kommt jedes Teil alsunmatchedzurück und das Ergebnis bleibt leer.
Es gibt vier Optimierungsmodi, alle entsprechen der App — einen für 2D-Platten, einen für 1D-Linearmaterial wie Stäbe, Profile und Rohre, einen für Holz, dessen Material einen Querschnitt hat, und True-Shape-Nesting (POST /v1/optimize/nest), das beliebige Polygone für Laser-, Plasma- und Wasserstrahlschneiden verschachtelt (der Nesting-Modus der App). Jeder Optimize-Endpoint hat außerdem einen kostenlosen Validierungs-Endpoint, der eine Anfrage prüft, ohne sie zu lösen (siehe unten).
Endpoints
Die Basis-URL ist https://api.cutoptim.com. Die Optimize- und Usage-Endpoints führen einen Schlüssel im Header Authorization: Bearer <key> mit; die Validate- und Health-Endpoints benötigen keinen Schlüssel.
| Endpoint | Was er tut |
|---|---|
POST /v1/optimize/2d |
2D-Plattenoptimierung |
POST /v1/optimize/1d |
1D-/Linearoptimierung — Stäbe, Profile, Rohre |
POST /v1/optimize/wood |
Holzoptimierung — 1D mit Querschnitts-Zuordnung |
POST /v1/optimize/nest |
True-Shape-Nesting — unregelmäßige Polygone für Laser, Plasma und Wasserstrahl |
POST /v1/validate/2d · /1d · /wood · /nest |
Eine Anfrage prüfen, ohne zu rechnen — kostenlos, kein Schlüssel, kein Kontingent |
GET /v1/jobs/{id} |
Einen asynchronen Job der max-Engine abfragen — nur Ihre eigenen Jobs, kein Kontingent |
POST /v1/import/nest |
Teileumrisse aus einer SVG- oder DXF-Datei lesen — Schlüssel erforderlich, verbraucht kein Kontingent |
GET /v1/usage |
Verbrauch und Kontingent des KONTOS im laufenden Monat (alle Schlüssel teilen sich eines) |
GET /v1/health |
Liveness-Prüfung — benötigt keinen Schlüssel |
Die meisten Aufrufe werden direkt mit dem fertigen Ergebnis beantwortet. Die einzige Ausnahme ist die asynchrone Engine max (siehe Drei Engines weiter unten): Eine max-Übermittlung gibt eine Job-ID zurück, und Sie fragen GET /v1/jobs/{id} ab, bis der Plan fertig ist.
Die Validate-Endpoints nehmen denselben Body wie der jeweils passende Optimize-Endpoint entgegen und prüfen ihn, ohne die Berechnung auszuführen: Eine fehlerhafte Anfrage kommt als 400 zurück und benennt genau das fehlerhafte Feld, eine wohlgeformte liefert valid: true samt Machbarkeitswarnungen (etwa ein Teil, das in kein Ausgangsmaterial passt). Sie kosten nichts und brauchen keinen Schlüssel, sodass Sie Ihre Payloads schon während des Aufbaus der Anbindung validieren können — noch bevor Sie überhaupt einen Schlüssel besitzen — und sicherstellen, dass eine Anfrage nicht abgewiesen wird, ohne einen Ihrer monatlichen Aufrufe zu verbrauchen.
Faserrichtung bei Platten
Sperrholz und furnierte Platten haben eine Maserung, und ein sichtbares Teil muss so geschnitten werden, dass sie in die richtige Richtung läuft. Senden Sie bei POST /v1/optimize/2d an einer Materialzeile grain — "w" oder "h", die Seite der Platte, an der die Maserung entlangläuft — und an einem Teil grain, die Seite des Teils, an der sie entlanglaufen muss. Jedes solche Teil wird mit seiner Maserung entlang der Maserung seiner Platte platziert: bei Bedarf um 90° gedreht (rotated: true an der Platzierung, wie bei jeder Drehung), und rotatable wird dafür ignoriert. Ein Teil ohne grain dreht sich weiterhin frei, auch auf einer Materialzeile ohne grain (MDF, Melamin); ein Teil MIT grain behält auch auf einer solchen Zeile die Ausrichtung, die ihm die gemaserten Zeilen geben — mit material werden gemaserte und glatte Platten getrennt. Ein Teil, das nur gegen die Maserung um 90° gedreht passen würde, steht in unplaced in der gesendeten Größe, eine Zeile in warnings nennt es, und POST /v1/validate/2d meldet es, bevor ein Aufruf verbraucht wird.
Materialzeilen, deren Maserung in unterschiedliche Richtungen verläuft, können in einer Anfrage stehen — eine 2440 × 1220 mit "w" und eine 1220 × 2440 mit "h" —, und jede Platte kommt in der Ausrichtung ihrer eigenen Zeile zurück und trägt deren grain in sheets[]. Mit material wird ein Teil nur dann an eine Maserung gebunden, wenn sein eigenes Material eine Platte mit Maserung hat. Hat die Anfrage kein Material mit Maserung, bleibt das grain eines Teils ohne Wirkung, und eine Zeile in warnings sagt das. options.trim und ein erzwungenes options.firstCut gelten für jede Platte in der Ausrichtung ihrer eigenen Zeile, auch bei einer Zeile, deren Maserung in die andere Richtung läuft. Der Modus Faserrichtung der CutOptim-App führt denselben Code aus. (Seit 2026-10-02.)
Maserungsabgleich bei Platten (Sätze, matchedSets)
Die Faserrichtung hält die Maserung jedes Teils in die richtige Richtung. Manche Fronten brauchen mehr: eine Schubladenfront über zwei Türen, deren Maserungsbild von einem Teil ins nächste weiterläuft, als wären die drei noch ein Brett. Geben Sie bei POST /v1/optimize/2d diesen Teilezeilen eine id und benennen Sie sie in 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"]] } }
]
}
- Was ein Satz ist.
layout.lineslistet die Mitglieder nachparts[].id. Mitdir: "rows"ist jede Linie eine Reihe nebeneinanderliegender Mitglieder, und die Reihen liegen von oben nach unten übereinander;[["DF"], ["DOOR", "DOOR"]]ist also eine Schubladenfront über zwei Türen. Mit"cols"ist jede Linie eine Spalte, und die Spalten stehen nebeneinander. Ein Teil darf in einem Satz mehrfach vorkommen (Door, Door), kann aber nur zu einem Satz gehören.qty(Standard 1) ist die Zahl der benötigten Instanzen — drei gleiche Schränke sindqty: 3—, und die eigeneqtyder Teile muss jede Instanz abdecken. Ein Satz hat mindestens 2 und höchstens 24 Mitglieder, und eine Anfrage nimmt höchstens 50 Sätze an. - Wie er geschnitten wird. Der Satz durchläuft den Optimierer als ein Rechteck — der Block — und kommt als seine Mitglieder zurück, genau eine Schnittfuge (kerf) auseinander, aus einem Stück Platte. Die
graindes Satzes ("w"oder"h", entlang der Breite oder Höhe des Blocks) bestimmt die Richtung jedes Mitglieds; die eigenegraineines Mitglieds wird im Satz nicht verwendet, und eine Warnung nennt jedes Mitglied, das sie überschreibt. Ohnegrainam Satz darf der Block gedreht werden, wenn jedes Mitgliedrotatableist.installGapist die Fuge zwischen den Mitgliedern am Schrank (Standard: die Schnittfuge); auf der Platte liegen sie weiterhin eine Schnittfuge auseinander. - Was zurückkommt. Jedes platzierte Mitglied trägt
matchedSet: dieiddes Satzes, welcheinstanceund seinepositionin Leserichtung an der Schrankfront — von oben nach unten, von links nach rechts, ab 1 — sowie einenhintwie"left"oder"right", wo das eindeutig ist. Die Antwort ergänzt eine ZusammenfassungmatchedSets, einen Eintrag je Satz: seinenletter(A, B … in der Reihenfolge der Anfrage), wie viele Instanzen als ein Block geschnitten (asBlock), aufgeteilt oder unplatziert blieben, die Blockgröße und diewarningsdes Satzes. Passt ein Block auf keine Platte, platziertonMiss: "split"(der Standard) die Mitglieder einzeln mit einer Warnung, undonMiss: "unplaced"listet sie inunplaced. - Warnungen, keine Fehler. Ein Maß, das nicht zusammenpasst, ist eine Warnung am Satz, keine Ablehnung. Jede Zeile beginnt mit ihrem Code —
align:(die Linien schließen nicht bündig ab),gap:(die Schnittfuge ist breiter alsinstallGap),grain:,split:,unplaced:,unmatched:(kein Bestand des Materials des Satzes),priority:undgrainGroup:—, undalignundgapwerden bei 1/64 Ihrer Einheit oder einer Viertel-Schnittfuge beurteilt, je nachdem, was kleiner ist. Ein Satz, der sich gar nicht auslegen lässt — eine Mitglieds-ID, die kein Teil trägt, eine referenzierte ID an zwei Teilen, weniger als zwei Mitglieder, zu wenige Teile fürqty—, ist ein400, das das genaue Feld nennt, bevor ein Aufruf berechnet wird. parts[].idist sicher zu senden. Geprüft wird nur eine ID, auf die ein Satz verweist (ein nicht leerer druckbarer String mit höchstens 64 Zeichen oder eine ganze Zahl, an genau einem Teil). Jede andere ID wird ignoriert, was auch immer sie enthält, sodass Ihre ERP-Artikelnummern an den Zeilen bleiben können. Und für eine Anfrage ohne Sätze ändert sich nichts: Nur ein nicht leeres ArraymatchedSetsschaltet die Funktion ein — fehlend,null,[]oder jeder Wert, der kein Array ist, wird genau wie zuvor beantwortet.- Exporte. Mit Sätzen erhält
csvam Ende die SpaltenSetundPosition,svgdruckt den Positionscode (A1, A2 …) in die Teilebeschriftungen und zeichnet den Rahmen jedes Satzes in einer eigenen Gruppematched-sets—options.setOutlines: falselässt diese Gruppe weg —, unddxfträgt den Positionscode auf dem Layer LABELS.pdfundlabelsPdfkennzeichnen Sätze nicht: Sie zeichnen die Mitglieder als gewöhnliche Teile, undwarningssagt das; die Satz-Markierungen stehen insheets[].parts[].matchedSet,csvundsvg. - Engines und Endpoints. Die Engines
heuristicundbalancedlegen Sätze aus (balancedordnetprioritynicht, sodass ein Satz dort unterrespectStockseinen Platz verlieren kann, mit einer Warnungpriority:). Die Enginemaxlehnt ein nicht leeresmatchedSetsmit einem400ab, dessendetails.unsupportedes nennt, bevor ein Aufruf berechnet wird; ein leeres ist ein gewöhnlichermax-Job.matchedSetsundparts[].idgibt es nur in 2D: Die Endpoints für 1D, Holz und Nesting ignorieren sie. grainGroupist veraltet. Es wird weiterhin angenommen und funktioniert genau wie zuvor: Teile mit derselben Gruppe bleiben auf einer Platte. Es hat sie nie nebeneinander platziert, liefert also keine durchgehende Maserung über sie hinweg — verwenden Sie dafürmatchedSets.
Der Maserungsabgleich der CutOptim-App legt Sätze mit demselben Kern aus.
Warum Holz einen eigenen Endpoint hat
Linearmaterial kennt nur eine Dimension, seine Länge — also kann jeder Stab jedes Teil liefern. Bei Holz ist das nicht so: Ein Teil 50×150 lässt sich aus einem Stab 50×100 nicht herausschneiden, wie viel Länge auch übrig bleibt. Der Holz-Endpoint nimmt deshalb bei jedem Teil und jeder Materialzeile beide Querschnittsseiten entgegen, teilt den Auftrag nach Querschnitt auf, ordnet jedem Abschnitt sein eigenes Material zu und gibt die Abschnitte getrennt zurück — jeden mit eigenen Stäben und eigenen Summen, neben den Zahlen für den gesamten Auftrag.
Zwei Details, die man vor der Anbindung kennen sollte:
-
Die beiden Querschnittsseiten dürfen in beliebiger Reihenfolge kommen. 50×100 und 100×50 sind derselbe umgedrehte Balken und werden als ein Abschnitt behandelt. Ein Unterschied darin, wie Ihre Daten nun einmal erfasst sind, kann also kein Material verschwinden lassen.
-
„Kein Material dieses Querschnitts“ und „hat nicht gepasst“ werden getrennt gemeldet. Das erste ist eine Materialmeldung, das zweite ein Kapazitätsproblem, und beide verlangen eine andere Lösung — in einer Liste vermischt schicken sie Ihren Anwender an die falsche Stelle.
Sie könnten das mit mehreren eigenen 1d-Aufrufen annähern, indem Sie die Teile selbst gruppieren. Das kostet pro Querschnitt eine Anfrage aus Ihrem Kontingent statt einer für den Auftrag, verlagert die Materialzuordnung in Ihren Code und liefert eine Auftragssumme, die Sie selbst zusammensetzen müssten — und die nicht zwangsläufig mit dem übereinstimmt, was die CutOptim-App für denselben Auftrag anzeigt.
Teile aus einer CAD-Datei
Der Nesting-Endpoint nimmt nicht nur Koordinaten entgegen. Ein Teil darf stattdessen ein source tragen — ein SVG- oder DXF-Dokument —, und der Server liest dessen Umriss samt aller Löcher aus der Datei heraus. Es ist derselbe Leser, den die App verwendet, wenn Sie eine Zeichnung auf ihren Nesting-Modus ziehen; eine Teilebibliothek, die bereits als CAD-Dateien vorliegt, muss also nicht erst in Koordinatenlisten umgeschrieben werden.
Die Datei ersetzt nur die Geometrie. Menge, Material, erlaubte Drehungen und Ihre eigenen Metadaten bleiben gewöhnliche Felder der Teilezeile, genau wie beim Senden von Koordinaten. Eine Datei beschreibt ein Teil; enthält eine einzelne Zeichnung mehrere getrennte Bauteile, zerlegt POST /v1/import/nest sie zuerst in fertige Teilezeilen — und dieser Aufruf braucht einen Schlüssel, verbraucht aber keine Anfrage aus Ihrem Monatskontingent.
Nichts wird gespeichert. Die Datei existiert ausschließlich als die Anfrage selbst: sie wird im Arbeitsspeicher gelesen und ist fort, sobald die Antwort geschrieben ist. Es bleibt keine Kopie auf einer Festplatte oder in einer Datenbank, nichts landet in einem Log, und es gibt hinterher nichts zu löschen. Mit Einheiten verfahren wir ebenso — eine DXF-Datei kann Millimeter oder Zoll angeben, und wir melden, was sie sagte, rechnen Koordinaten aber nie um, denn kein Wert in dieser API trägt eine Einheit.
Jedes Mal dieselbe Antwort
Die Engine ist deterministisch: Dieselbe Eingabe liefert immer dieselbe Ausgabe. Es gibt keinen Zufall und keine Uhr im Algorithmus.
Das klingt akademisch, ist aber der praktische Grund, darauf aufzubauen. Es bedeutet, dass Ergebnisse gecacht werden können — wenn Sie genau diesen Auftrag schon einmal gefragt haben, können Sie die Antwort bedenkenlos wiederverwenden, statt erneut zu fragen. Es bedeutet außerdem, dass sich die Anbindung testen lässt: Ein Plan kann mit einem als korrekt bekannten Ergebnis verglichen werden, und ein Unterschied ist ein echter Unterschied, kein Rauschen. Software, die einem Kunden am Montag einen Preis nennt, nennt am Freitag denselben Preis.
Es gibt eine einzige, ausdrücklich zugelassene Ausnahme, und sie sagt es auch: Die Nesting-Engine max (unten) wendet ein festes Zeitbudget für die Suche auf, wie weit sie also kommt, hängt davon ab, wie viel Arbeit in dieses Zeitfenster passt. Ihre Antworten tragen deterministic: false. Jede andere Engine — auch die Standard-Engine des Nestings, lbf — ist deterministisch.
Sicher wiederholen. Bricht die Verbindung ab, wissen Sie nicht, ob die Anfrage angekommen ist. Senden Sie einen Idempotency-Key-Header — einen Wert, den Sie pro Auftrag wählen — und wiederholen Sie mit demselben Schlüssel: Innerhalb von 24 Stunden liefert dieselbe Anfrage die gespeicherte Antwort, markiert mit Idempotency-Replayed: true, und wird kein zweites Mal berechnet. Auch ein max-Job wird nicht doppelt eingereiht. Der öffentliche Demo-Schlüssel ignoriert diesen Header. (Seit 2026-10-15.)
Webhooks für asynchrone Jobs. Statt GET /v1/jobs/{id} abzufragen, registrieren Sie im Dashboard einen Endpunkt (eine https://-URL) und erhalten einen signierten POST — job.succeeded oder job.failed —, sobald ein asynchroner max-Job fertig ist. Prüfen Sie den Header CutOptim-Signature mit dem erhaltenen Geheimnis, antworten Sie innerhalb von 10 Sekunden und lesen Sie den Plan mit GET /v1/jobs/{id}. Eine fehlgeschlagene Zustellung wird wiederholt: 8 Versuche über 24 Stunden. (Seit 2026-10-19.)
Offizielle SDKs. Open-Source-Clients für TypeScript, Python und PHP — npm install @cutoptim/engine, pip install cutoptim, composer require cutoptim/engine — mit typisierten Anfragen, Wiederholungen, die nie doppelt berechnet werden (jeder Aufruf trägt einen Idempotency-Key), einer Warte-Hilfe für asynchrone Jobs und Webhook-Prüfung. Quellcode auf GitHub; Details im SDK-Leitfaden (Englisch).
MCP-Server für KI-Assistenten. Claude Code, Cursor, VS Code und Claude Desktop können die Engine über den gehosteten Model-Context-Protocol-Server unter https://api.cutoptim.com/mcp als Werkzeuge aufrufen, mit demselben API-Schlüssel (Authorization: Bearer …) und demselben Kontingent: ein Werkzeugaufruf ist ein API-Aufruf, die validate_*-Werkzeuge sind kostenlos. Lokal läuft er auch als Paket npx -y @cutoptim/mcp (Schlüssel in CUTOPTIM_API_KEY); im offiziellen MCP Registry steht er als io.github.cutoptim/engine. Die Client-Konfigurationen stehen im MCP-Leitfaden (Englisch).
Drei Engines
Die API bietet die Wahl zwischen dreien — zwei synchronen und einer asynchronen —, und der Unterschied ist keine Frage der Qualität: Er ist ein Kompromiss zwischen Geschwindigkeit und der Frage, ob sich das Ergebnis auf einer Plattensäge schneiden lässt.
heuristicist der Standard und dieselbe Engine, die auch die App verwendet. Sie erzeugt Guillotine-Layouts: höchste Auslastung, jedes Layout auf der Plattensäge schneidbar und immer ein vollständiger Schnittplan. Synchron.balancedist optional und muss ausdrücklich angefordert werden. Sie nutzt stattdessen freie Verschachtelung, was bei sehr großen Aufträgen dramatisch schneller ist — gemessen rund 25× schneller bei einem Auftrag mit 2.000 Teilen — auf Kosten einer geringfügig niedrigeren Auslastung. Der wichtige Haken: Ihre Layouts lassen sich häufig nicht von Kante zu Kante schneiden, und für diese gibt sie überhaupt keinen Schnittplan zurück. Synchron.maxist optional, für 2D-Platten (und, getrennt davon, für True-Shape-Nesting — siehe unten). Bei 2D ist es eine serverseitige Baumsuche, die das bewiesene Optimum bei weit mehr Aufträgen erreicht als der Standard, und ihre Layouts lassen sich weiterhin auf einer Plattensäge schneiden. Der Preis ist Zeit: Einemax-Berechnung dauert Sekunden bis zu einer Minute, sie antwortet also nicht in der Response. Stattdessen gibtPOST /v1/optimize/2dmitengine: "max"eine Job-ID zurück, und Sie fragenGET /v1/jobs/{id}ab, bis sie fertig ist. Es ist weiterhin deterministisch. Greifen Sie dazu, wenn bei einem großen, wertvollen Auftrag das Warten auf die letzten paar Platten sich lohnt. Sie modelliert ein Bestandsformat in voller Plattengröße mit unbegrenztem Vorrat. Enthält die Anfrage zusätzlich ein zweites Bestandsformat, seitenweisentrim, begrenzten Bestand (respectStock), Materialien, Faserrichtungsgruppen oder ein nicht leeresmatchedSets, wird sie vorab mit einem400abgelehnt, das genau benennt, was sie nicht kann — bevor ein Aufruf berechnet wird. Schicken Sie solche Aufträge anheuristic, das alles davon abbildet.
Nesting: lbf und max
True-Shape-Nesting hat zwei eigene Engines. lbf ist der Standard: sofort, synchron und deterministisch. max ist optional und asynchron, genau wie die 2D-Engine max — POST /v1/optimize/nest mit engine: "max" gibt eine Job-ID zurück, und Sie fragen GET /v1/jobs/{id} ab.
Die Nesting-Engine max führt zuerst den lbf-Durchlauf aus, sodass sie immer eine gültige Antwort in der Hand hat. Danach wendet sie ein Zeitbudget auf (options.timeBudgetMs, standardmäßig 60 Sekunden, zwischen 10 und 180), um ein Layout mit weniger Platten zu finden, wobei sie eine Platte nach der anderen füllt. Sie gibt nie mehr Platten zurück als lbf: Findet die Suche keine Verbesserung, erhalten Sie das lbf-Layout und eine Warnung, die das sagt. Weil die Suche zeitlich begrenzt ist, tragen ihre Antworten deterministic: false. Sie akzeptiert mehrere Plattengrößen je Material sowie respectStock und bewertet ihr Ergebnis nach derselben Regel wie lbf (unten): Sie ersetzt den lbf-Plan nur, wenn er besser ist — nie allein deshalb, weil er weniger Platten hat. Eine Polygon-Platte oder Sperrzonen, die ihre Streifensuche nicht abbilden kann, werden innerhalb des Jobs vom lbf-Durchlauf mit einer Warnung bedient — nie abgelehnt. Der ältere Name sparrow wird als Alias von max akzeptiert.
Rechteckige Teile erhalten ein exaktes Raster (seit 2026-09-28). lbf findet Positionen durch Stichproben, und das trifft fast nie ein Raster ohne jeden Spielraum: Drei 500 mm breite Teile quer über eine 1500 mm breite Platte bei null Abstand passen exakt, eine stichprobenbasierte Suche platziert zwei. Deshalb probieren beide Engines zusätzlich zwei Alternativen aus und behalten nach derselben Regel die, die am besten abschneidet: die Teile auf die rechten Winkel beschränkt, die sie erlauben, und die Bounding Boxes der Teile, gepackt von einem exakten Rechteck-Packer (Boxen, die sich nicht überlappen, können keine überlappenden Teile enthalten, das gilt also für jeden Umriss). Bei Gleichstand — gleiche Platten, gleiche Plattenfläche — gewinnt der Plan, der seine Platten von vorn nach hinten füllt, danach der mit weniger Teilen außerhalb der rechten Winkel. Es gibt nichts einzuschalten, und ein Ergebnis kann nach der Rangfolge nur besser werden; ein Plan, den die Rechtecke auf die geringste Plattenzahl bringen, die die Teilefläche zulässt, lässt max außerdem sofort antworten, statt zu suchen.
Ein Auftrag mit einigen Dutzend Teilen braucht meist etwa 15 Sekunden Budget (timeBudgetMs: 15000); der Job ist ungefähr ein bis zwei Sekunden nach Ablauf des Budgets fertig, zuzüglich der Zeit in der Warteschlange. Fragen Sie GET /v1/jobs/{id} alle zwei bis drei Sekunden ab — das Abfragen kostet kein Kontingent. Kein Budget kann eine bestimmte Plattenanzahl versprechen.
Nesting: Randabstand, Plattengrößen und was jede Platte kostet
- Randabstand.
options.minSeparationist der Abstand zwischen den Teilen und gilt für sich genommen auch an der Plattenkante.options.edgeClearancestellt die Kante getrennt ein — zum Beispiel 5 zwischen den Teilen und 0 oder 10 an der Kante. Lassen Sie es weg, behält die Kante genau wie bisherminSeparation. Es funktioniert auf beiden Engines, setzt rechteckige Platten voraus (wundh), und Sperrzonen behalten wie TeileminSeparation. Eine Polygon-Platte oder ein Wert, der auf einer Platte keinen Platz mehr lässt, wird mit einem400abgelehnt, bevor ein Aufruf berechnet wird. - Eine Plattengröße wählen. Hat ein Material zwei oder mehr Materialzeilen, probiert
lbfsie in Ihrer Reihenfolge aus, jede Größe für sich und zusätzlich in einer nach Preis aufsteigenden Reihenfolge, und behält die beste — das Ergebnis hängt also nicht mehr von der Reihenfolge ab, in der Sie die Zeilen auflisten. Die Rangfolge ist: die meisten platzierten Muss-Teile (siehe unten), dann die meisten platzierten Teile, dann die geringste gesamte Plattenfläche (Material), dann die wenigsten Platten. Mitoptions.minimizeCostbewertet sie stattdessen nach dem gesamten Preis (price, odercostfür eine Zeile ohne Preis) — aber nur, wenn jede Zeile dieses Materials einen trägt; andernfalls fällt sie auf die Fläche zurück und sagt das inwarnings. - Größen mischen. Danach wird jede Platte — die am wenigsten gefüllte zuerst — für sich auf die günstigeren oder kleineren Zeilen neu verschachtelt und ersetzt, wenn der gesamte Plan besser abschneidet. So können Größen innerhalb eines Materials gemischt werden: typischerweise zwei große Platten und eine kleinere zum Schluss, wo die halb leere letzte Platte früher eine große war. Mit
options.respectStockwird keine Zeile öfter genutzt als ihreqty. Die Enginemaxwendet dieselbe Rangfolge an. - Muss-Teile.
parts[].priority: truekennzeichnet ein Teil, das unbedingt geschnitten werden muss. Wichtig wird das mitoptions.respectStock— einem begrenzten Vorrat, bei dem nicht jedes Teil passen muss: Muss-Teile werden dann zuerst platziert, sodass ein einfaches Teil nie den Plattenplatz beansprucht, den ein Muss-Teil braucht, und jede Rangfolge oben stellt den Plan voran, der mehr davon behält, selbst wenn er insgesamt weniger Teile platziert. Beide Engines beachten es (maxbehält daslbf-Layout, sobald irgendetwas unplatziert bleibt). OhnerespectStockwird ohnehin jedes passende Teil platziert, das Flag ändert also nichts. Ein Muss-Teil, das auf keine Platte passt, steht weiterhin inunplaced. (Seit 2026-09-22 — davor nahm die Nesting-Engine das Feld entgegen, beachtete es aber nicht.) - Begrenzter Vorrat, auf den nicht alles passt. Mit
options.respectStockfüllt die Engine, wenn der Plan noch Teile übrig lässt, die Platten zusätzlich einzeln mit den umschließenden Rechtecken der Teile — jede so voll wie möglich, und ein Teil, das nur auf eine Plattengröße passt, kommt zuerst dorthin (eine hohe Seitenwand auf die eine große Platte, nicht auf einen Reststreifen). Dieser Plan wird nur übernommen, wenn er mehr Teile platziert (Muss-Teile zuerst) oder weniger Material braucht; ein Auftrag, bei dem alles passt, kommt genau wie bisher zurück. Er hält die erlaubten Drehungen jedes Teils,minSeparationundedgeClearanceein. (Seit 2026-10-14.) - Was jede Platte kostet. Jede Platte trägt
stock— den Index der Materialzeile aus der Anfrage, aus der sie geschnitten wurde —, und die Antwort ergänztstockUsage: einen Eintrag je genutzter Materialzeile, mit deren Plattenanzahl, Gesamtpreis und Dichte. Die Einheit ist die Materialzeile, nicht die Größe: Zwei Zeilen mit denselben Maßen, aber unterschiedlichem Preis odermetasind zwei Einträge. - Schnittlänge und Einstiche. Jede Platte trägt
cutLength— den Summenumfang der Umrisse und Löcher ihrer platzierten Teile, in Ihrer Einheit — sowiepierces, einen je geschlossener Kontur;metricssummiert beides. Es ist die geometrische Konturlänge: keine Überschneidungsschnitte, An-/Ausfahrwege oder Mikroverbindungen — die fügt Ihr CAM hinzu. - Genutzte Fläche, für die Teilplatten-Abrechnung. Jede Platte trägt
usedWidthundusedHeight— den am weitesten entfernten Punkt, den ein platziertes Teil von der Ursprungsecke der Platte erreicht, in Ihrer Einheit, auf der echten Platte (mitedgeClearanceist der Randabstand eingeschlossen) — sowieusedArea, deren Produkt;stockUsage[].usedAreasummiert das je Materialzeile. Das braucht ein ERP, um einen horizontalen Schnitt (usedHeight× Plattenbreite), einen vertikalen Schnitt (usedWidth× Plattenhöhe) oder die Bounding Box (usedArea) statt der ganzen Platte zu berechnen — die Abrechnungsregel bleibt Ihre. Um diese Zahlen klein zu halten, verdichten beide Engines standardmäßig die am wenigsten gefüllte Platte je Material: Ihre Teile werden auf derselben Platte mit Drehungsteilmengen dessen, was jedes Teil erlaubt, neu verschachtelt — 0/180, 0/90/180/270 und eine Ausrichtung für jede Kopie, geschnitten mit einem diskretenallowedRotations, nie ein neuer Winkel — und das Layout mit der kleinsten genutzten Fläche wird behalten. Mitengine: "max"packt anschließend auch die Suche selbst diese Platte neu — entlang der Plattenhöhe und, bei einem Plan mit nur einer Platte, auch entlang der Breite — und behält nach derselben Regel das engere Layout. Plattenanzahl, Größen, Preis und platzierte Teile ändern sich nie;options.compact: falsegibt das unverdichtete Layout zurück. Wenn Sie einen Streifen statt der Bounding Box berechnen, setzen Sieoptions.compactForentsprechend:"horizontal"behält das Layout mit der geringstenusedHeight(ein Streifen über die gesamte Plattenbreite),"vertical"das mit der kleinstenusedWidth(ein Streifen über die gesamte Plattenhöhe); der Standard"box"behält die kleinsteusedArea. Die Streifen-Modi probieren außerdem jede Kopie um eine Vierteldrehung (90° oder 270°) gedreht, sofernallowedRotationsdas erlaubt. Wie klein die genutzte Fläche wird, hängt von den Teilen ab. (Seit dem 22.09.2026.)
balanced bedeutet nicht „bessere Ergebnisse”. Sie ist schneller und erreicht eine etwas geringere Auslastung, und wenn ihr Layout nicht guillotine-schneidbar ist, gibt es keinen Schnittplan, den man einer Sägebedienung in die Hand geben kann. Wählen Sie sie nur, wenn Geschwindigkeit bei einem sehr großen Auftrag wichtiger ist als ein sägefertiger Plan. Wenn Sie unsicher sind, bleiben Sie beim Standard.
Limits
Jede Anfrage ist begrenzt, damit ein aus dem Ruder gelaufener Auftrag klar fehlschlägt statt hängen zu bleiben:
| Limit | Wert |
|---|---|
| Teile pro Anfrage | 2.000 |
| Materialzeilen pro Anfrage | 50 |
| Größe des Request-Bodys | 1 MB |
| Größe des Anfragerumpfs — nest-Pfade, die eine Zeichnung tragen können | 10 MB |
| Aktive Schlüssel pro Konto | 10 |
Schlüssellose validate-Aufrufe je Adresse |
120 / Minute |
| Unbekannte API-Schlüssel je Adresse | 30 / Minute — danach 429 für den Rest der Minute |
| Wartezeit auf einen freien Rechenplatz (synchrone Pfade) | ca. 8 s — danach 429, nichts wird berechnet |
Gleichzeitig queued/running max-Jobs je Konto |
5 |
| Suchbudget der Nesting-Engine max je Auftrag | 10–180 s (Standard 60 s) |
Aufbewahrung des Idempotency-Key |
24 Stunden |
| Webhook-Endpunkte pro Konto | 5 |
| Zustellversuche je Webhook-Ereignis | 8 über 24 Stunden |
Zugang erhalten
Beginnen Sie auf der Engine-API-Seite. Die Engine API wird getrennt von den App-Tarifen abgerechnet, und kein Tarif-Upgrade schaltet sie frei.
- Ausprobieren, dann abonnieren — oder anfragen. Sie können die API aufrufen, bevor Sie bezahlen: Die Buttons Dieses Beispiel ausführen in der API-Referenz nutzen einen öffentlichen Demo-Schlüssel, und jedes angemeldete Konto kann im Dashboard kostenlose Testschlüssel erstellen (eigenes kleines Monatskontingent, wird nie abgerechnet, kein Abo nötig). Sind Sie so weit, ist der Abschluss auf der Engine-API-Seite der schnellste Weg — der Einstiegstarif Studio beginnt mit einer kostenlosen Testphase, und der Zugang landet von selbst auf Ihrem Konto. Möchten Sie Ihre Anbindung lieber vorher beschreiben oder brauchen Sie ein Volumen über dem Standardtarif, nehmen Sie stattdessen Kontakt auf und sagen Sie, was Sie anbinden möchten und wie viele Schnittpläne pro Monat das ungefähr braucht.
- Der Zugang wird Ihrem Konto hinzugefügt. Sonst ändert sich an Ihrem Konto nichts.
- Legen Sie einen Schlüssel an. Die Karte API-Schlüssel ist für jedes angemeldete Konto in Ihrem Dashboard: Ohne Abo erstellt sie Testschlüssel, mit API-Zugang auch Live-Schlüssel. Dort erstellen, benennen und löschen Sie Schlüssel selbst.
- Kopieren Sie den Schlüssel sofort. Der vollständige Schlüssel wird genau ein einziges Mal angezeigt, in dem Moment, in dem Sie ihn erstellen.
Ein Schlüssel wird nur ein einziges Mal angezeigt. CutOptim speichert nur einen sha256-Hash davon, nie den Schlüssel selbst — er lässt sich später also nicht wieder auslesen, weder von Ihnen noch von uns. Übertragen Sie ihn beim Erstellen direkt in die Konfiguration Ihrer Software. Wenn Sie einen Schlüssel verlieren, löschen Sie ihn und legen einen neuen an; sollte ein Schlüssel jemals nach außen gelangen, löschen Sie ihn — die Aufrufe funktionieren dann sofort nicht mehr.
Behandeln Sie einen Schlüssel wie ein Passwort: Er gehört in die Konfiguration Ihrer Software, nicht in eine E-Mail, eine Tabelle oder einen Screenshot.
Was die API-Schlüssel-Karte im Dashboard tut
Vier Bedienelemente — und es lohnt sich, genau zu sagen, was jedes bewirkt, besonders das letzte, von dem viele annehmen, es berühre die Abrechnung. Tut es nicht.
- Tarif, Wechsel und Abrechnung. Zeigt, in welchem Tarif das Konto ist (Studio oder Scale). Zu Scale wechseln (bzw. Zu Studio wechseln) ändert den Tarif nach einer Bestätigung, und das Monatskontingent des Kontos ändert sich sofort. Abrechnung öffnet Ihre Abrechnungseinstellungen, in denen Sie die Karte aktualisieren, Rechnungen einsehen oder kündigen.
- Schlüssel erstellen. Erzeugt einen neuen Schlüssel und zeigt ihn einmal an, direkt dort. Der Name (
ERP-Anbindung,Staging) dient nur dazu, die Schlüssel später auseinanderzuhalten. Bis zu 10 aktive Schlüssel pro Konto. Testschlüssel erstellen Sie auf dieselbe Weise, sie werden getrennt gezählt: Sie haben ein eigenes kleines Monatskontingent und werden nie abgerechnet. - Der Verbrauchsbalken. Zwei Zahlen: der Gesamtverbrauch Ihres Kontos im Kalendermonat gegenüber dem Kontingent, und je Schlüssel, wie viel dieser verbraucht hat. Die Zahl pro Schlüssel beantwortet, welche Anbindung das Kontingent aufbraucht — sie ist kein eigenes Budget.
- Widerrufen. Setzt genau diesen Schlüssel ab dem nächsten Aufruf außer Kraft. Die Zeile bleibt sichtbar, damit die Historie nicht verloren geht.
Einen Schlüssel zu widerrufen hat nichts mit Ihrem Abo zu tun. Es kündigt nichts, erstattet nichts und gibt kein Kontingent frei — der Tarif läuft weiter und das Kontingent bleibt bestehen, Sie besitzen lediglich diesen einen Schlüssel nicht mehr. Widerrufen Sie, wenn ein Schlüssel offengelegt wurde oder eine Anbindung stillgelegt wird. Um die Abrechnung zu beenden, kündigen Sie stattdessen das Abo; der Zugang läuft dann bis zum Ende des bereits bezahlten Zeitraums, danach funktionieren auch bestehende Schlüssel nicht mehr.
Ein Kontingent für das Konto, nicht eines je Schlüssel
Jeder aktive Schlüssel Ihres Kontos schöpft aus demselben monatlichen Kontingent. Ein zweiter Schlüssel schafft kein zweites Kontingent — Schlüssel gibt es, damit Sie Staging von Produktion trennen, jeder Anbindung ein eigenes Zugangsmittel geben und einen davon widerrufen können, ohne die anderen zu stören.
GET /v1/usage meldet den Stand des Kontos (used, limit, remaining) und beantwortet damit die Frage, die Sie tatsächlich haben — wie viel bleibt, bevor Aufrufe fehlschlagen — unabhängig davon, mit welchem Schlüssel Sie gefragt haben. Ist das Kontingent aufgebraucht, antwortet jeder Schlüssel mit 402, nicht nur der, der es verbraucht hat.
Tarife, Preis und Kontingent
Die Engine API wird getrennt von den App-Tarifen abgerechnet, monatlich, in EUR, mit zwei Tarifen:
| Tarif | Was sich unterscheidet |
|---|---|
| Studio | Der Einstiegstarif, mit kostenloser Testphase |
| Scale | Ein größeres monatliches Anfragekontingent, keine Testphase — Sie wechseln von Studio dorthin |
Alles Übrige ist in beiden gleich: dieselben Engines, alle vier Modi, jede Option, dieselben Antworten. Jede Anfrage zählt gleich — ein Nesting-Auftrag kostet eine Anfrage, genau wie ein 2D- oder 1D-Auftrag.
- Hartes Limit, keine Zusatzkosten. Ist das Monatskontingent aufgebraucht, antworten Aufrufe mit
402, bis es am ersten Tag des nächsten Monats zurückgesetzt wird. Es gibt keine überraschende Rechnung. - Zwei E-Mails, damit das Limit Sie nicht überrascht. Wir schreiben dem Konto bei 90 % des Kontingents und noch einmal, wenn es aufgebraucht ist.
- Den Tarif wechseln Sie mit einem Button auf der Karte API-Schlüssel Ihres Dashboards (Zu Scale wechseln / Zu Studio wechseln); das neue Kontingent gilt sofort. Ein Upgrade wird für den Rest des Zeitraums sofort berechnet; ein Downgrade wird nicht erstattet, der niedrigere Preis gilt ab der nächsten Verlängerung. Der Wechsel ist nach der Testphase möglich.
- Größere Volumen als im Tarif Scale kalkulieren wir individuell — nehmen Sie Kontakt auf.
Die aktuellen Preise und Kontingente stehen auf der Engine-API-Seite — diese Seite liest sie aus unserer Preiskonfiguration, es sind also immer die zutreffenden Zahlen.
Für die technischen Details — die genaue Struktur von Request und Response, jede Option, alle Fehlercodes und wie die Versionierung funktioniert — siehe die API-Referenz.
Open-Source-Komponenten
Die Engines von CutOptim bauen auf Open-Source-Bibliotheken auf, die unverändert auf unseren Servern eingesetzt werden:
- jagua-rs — die geometrische Kollisions-Engine hinter True-Shape-Nesting (MPL-2.0).
- sparrow — die Suche hinter der Nesting-Engine max (MIT, KU Leuven).
- PackingSolver — die Baumsuche hinter der 2D-Engine max (MIT).
Alles rundherum — die API, die Zuordnung zwischen dem Contract und diesen Engines, die rechteckigen Packer und die App selbst — ist eigener Code von CutOptim.
Was sich dadurch nicht ändert
Das sei ausdrücklich gesagt, denn die Engine API wird leicht als Änderung am Produkt missverstanden:
- Der Optimierer in der App ist unverändert. Er läuft weiterhin in Ihrem Browser, genau wie bisher.
- Free, Pro und Werkstatt sind unberührt. Sie enthalten weiterhin den Optimierer in der App, mit denselben Limits wie bisher. Es wurde nichts hinter die API verlegt.
- Nichts, was Sie in der App tun, verbraucht API-Anfragen. Das monatliche API-Kontingent wird ausschließlich von Aufrufen berührt, die Ihre eigene Software macht.
Die Engine API ist eine Ergänzung für Menschen, die CutOptim in andere Software einbinden. Wenn Sie das nicht sind, hat sich nichts geändert.