Dokumentation/Integrationen

Integrationen und Datenaustausch

Werkstoffkatalog, Maschinenstundensätze und Kalkulationsregeln können aus dem System kommen, das sie ohnehin führt - und die ganze Preisliste lässt sich wieder herausholen.

Der Katalog darf aus einem anderen System kommen

MetronQ hält die gesamte Preisliste eines Betriebs - die eingekauften Werkstoffe, die Maschinen, auf denen gefertigt wird, die verkauften Oberflächen und die Parameter, mit denen die Engine rechnet - als eine Konfiguration, die sich auch außerhalb des Panels lesen und schreiben lässt. Stehen diese Zahlen bereits in einem ERP, einem CRM oder einer Tabelle, müssen sie kein zweites Mal eingetippt und auch nicht von Hand in zwei Kopien im Gleichschritt gehalten werden.

  • Werkstoffe - Bezeichnung, EN- und DIN-Nummer, Dichte, Preis je Kilogramm, Zeitspanvolumen beim Schruppen und beim Drehen, Schlichtleistung, Aufmaß, Schnittgeschwindigkeit.
  • Maschinen - Bezeichnung, Technologie, Stundensatz, Arbeitsraum, Achsen, Spindelleistung und Höchstdrehzahl, Werkzeugplätze, Mindestlosgröße sowie Hersteller, Modell, Steuerung, Baujahr, Seriennummer und Inventarnummer.
  • Oberflächen und Wärmebehandlung - Bezeichnung, Art, Kosten je Kilogramm, Kosten je Quadratdezimeter, feste Losgebühr und die Arbeitstage, die sie der Lieferzeit hinzufügt.
  • Kalkulationsregeln - Marge, Rüst- und Handhabungsminuten, Mindestzykluszeit, Lieferzeiten, Express-Faktor, Versand, Steuersatz sowie die Faktortabellen für Toleranzklasse, Geometrieklasse und Oberflächengüte.

Es gibt zwei Formate, und welches gebraucht wird, hängt davon ab, was am anderen Ende steht. Eine Tabelle je Katalog ist das, was die meisten ERP-Exporte erzeugen und was ein Mensch von Hand nachbessern kann. Ein JSON-Dokument mit allem darin ist das Format für den Fall, dass ein anderes System MetronQ selbsttätig aktuell halten soll.

Wo es zu finden ist

  1. 1Im Panel die Kalkulationsregeln öffnen.
  2. 2In der linken Leiste Import und Export wählen.
  3. 3Der Export erzeugt eine Datei im unten beschriebenen Format; der Import nimmt eine solche wieder entgegen.
Tipp

Zuerst exportieren, auch wenn nur ein Import geplant ist. Die exportierte Datei trägt die exakten Spaltennamen und die eigenen Katalogschlüssel bereits in sich - das einfachste Mapping im ERP ist daher jenes, das unseren eigenen Export ausfüllt.

Das Tabellenformat

Eine Datei je Katalog - Werkstoffe, Maschinen, Oberflächen. Die erste Zeile enthält die Spaltennamen, und das sind in jeder Sprache englische Bezeichner: gegen sie wird das Mapping im anderen System geschrieben, und sie sind es, die MetronQ beim Import zurückliest.

  • Zeilen werden ausschließlich über die Spalte key zugeordnet. Einen Schlüssel, den MetronQ kennt, aktualisiert der Import; einen unbekannten legt er an.
  • Gelesen werden nur die Spalten, die die Datei mitbringt. Fehlt eine Spalte, behält das Feld in jeder Zeile seinen Wert.
  • Eine leere Zelle bedeutet unverändert lassen, nicht leeren. Ein Teilexport - nur die gerade geführten Werkstoffe, nur die Sätze dieses Quartals - ist der Normalfall und nicht die Ausnahme.
  • Ein Import löscht niemals. Einen Werkstoff oder eine Maschine zu entfernen ist eine bewusste Handlung im Panel.
  • Das Dezimalzeichen gehört zum Spaltentrenner: Semikolon zu Komma-Dezimalen (1234,56), Komma zu Punkt-Dezimalen (1234.56). Beides wird gelesen, und der Export folgt der Trenner-Einstellung des Kontos.
  • Akzeptiert werden UTF-8 mit und ohne Byte Order Mark sowie die mitteleuropäische Codepage, die Excel unter Windows schreibt.
  • Eine Datei darf bis zu 20 000 Zeilen enthalten und bis zu 2 MB groß sein.

Die Werkzeugliste einer Maschine steht bewusst nicht in der Tabelle: eine Liste von Fräsern passt nicht in eine Zeile. Eine aus der Tabelle importierte Maschine behält daher die Werkzeugliste, die sie bereits hat - ein Umweg über Excel kann also nicht stillschweigend ändern, was die Maschine fertigen darf.

Die gesamte Konfiguration als ein Dokument

Der JSON-Export ist die vollständige Kalkulationskonfiguration, genau so, wie das Panel sie speichert, und wird unverändert wieder entgegengenommen. Er enthält die drei Kataloge sowie sämtliche Kalkulationsparameter, die Einstellungen der Prüf-Gates, die Strategien für Maschinen- und Rohteilwahl und die Währung. Damit ist er das Format für ein System, das eine eigene Kopie der Preisliste führt.

  • Zusammenführen, die Voreinstellung, übernimmt ausschließlich das, was das Dokument tatsächlich angibt. Eine Datei mit drei Werkstoffen und einer Marge ändert drei Werkstoffe und eine Marge; alles, wozu sie schweigt, behält den bereits gesetzten Wert.
  • Ersetzen übernimmt das Dokument vollständig, Löschungen eingeschlossen - für den Fall, dass ein anderes System der führende Datenbestand sein soll und nicht bloß eine Quelle.
  • Kataloge werden über dieselbe Spalte key zusammengeführt, die auch die Tabelle verwendet; beide Formate verstehen also dasselbe unter demselben Werkstoff.

Nichts wird übernommen, bevor die Vorschau zeigt, was es tut

Jeder Import ist zunächst ein Trockenlauf. Bevor ein einziger Wert geschrieben wird, zeigt das Panel, wie viele Einträge angelegt und wie viele aktualisiert würden, den Unterschied Feld für Feld zwischen der heutigen Preisliste und derjenigen, die die Datei hinterlassen würde, jede Zeile, die nicht gelesen werden konnte, und jede Spalte, die MetronQ nicht erkannt hat.

  • Eine Zeile, die die Preisliste zurückweist - eine fehlende Dichte, ein Preis, der keine Zahl ist - lässt die ganze Datei scheitern. Nichts wird halb übernommen, denn eine halb importierte Preisliste erzeugt falsche Preise, ohne dass es jemand bemerkt.
  • Eine nicht erkannte Spalte wird namentlich aufgeführt. Genau das fängt einen Export mit verschobenen Spalten oder einen Tippfehler in der Kopfzeile ab, der sonst als gar keine Änderung durchliefe und aussähe wie eine Datei, die funktioniert hat.
  • Speichert jemand die Preisliste, während die Vorschau offen ist, wird der Import abgelehnt und muss erneut ausgeführt werden: der Unterschied auf dem Bildschirm würde sonst nicht mehr beschreiben, was tatsächlich geschähe.

Jeder bestätigte Import wird im Änderungsprotokoll der Einstellungen als Import vermerkt, Feld für Feld - ein Preis, der sich bewegt hat, lässt sich also immer bis zu der Datei zurückverfolgen, die ihn bewegt hat.

Ein System direkt anbinden

Alles oben Beschriebene geht auch, ohne dass jemand das Panel öffnet: Ein Betrieb kann einen API-Schlüssel ausstellen und ihn seinem ERP, CRM oder Automatisierungswerkzeug geben. Der Zugang wird mit jedem Betrieb einzeln vereinbart - eine kurze Nachricht mit dem eingesetzten System genügt - denn eine Integration hängt davon ab, was auf der anderen Seite steht, und ist kein bloßes Häkchen. Der Schlüssel gehört dem Betrieb und nicht einer Person und funktioniert daher weiter, wenn die Person, die ihn angelegt hat, abwesend ist.

  1. 1Im Panel die Einstellungen und darin Integrationen öffnen. Diesen Bereich sieht ausschließlich der Kontoinhaber.
  2. 2Neuer Schlüssel anklicken, ihn nach dem System benennen, das ihn bekommt, und anhaken, was er darf.
  3. 3Den Schlüssel sofort kopieren. Er wird einmal angezeigt und von uns nicht gespeichert; geht er verloren, wird er widerrufen und neu erstellt.

Die erste Integration, Schritt für Schritt

Sechs Aufrufe in der Reihenfolge, in der man sie üblicherweise schreibt. Alle verwenden denselben Header, wer den ersten hinbekommt, bekommt alle hin. Die Basisadresse ist https://app.metronq.com, und die Antwort ist überall JSON, wo der Pfad nicht auf .csv endet.

1. Den Schlüssel prüfen. whoami braucht keine Berechtigung und antwortet, zu welchem Betrieb der Schlüssel gehört, was er darf und wie viel er verbrauchen darf. Funktioniert dieser Aufruf, ist alles Weitere nur noch eine Frage der Pfade.

curl
curl https://app.metronq.com/api/v1/integration/whoami \
  -H "Authorization: Bearer mq_live_YOUR_KEY"
json
{
  "tenant": { "name": "Musterwerk GmbH", "slug": "musterwerk", "currency": "EUR" },
  "key": {
    "name": "ERP sync",
    "prefix": "a1b2c3d4",
    "scopes": ["config:read", "quotes:read"],
    "expires_at": "2027-09-16T10:12:00+00:00"
  },
  "rate_limit": {
    "requests_per_minute": 120,
    "requests_per_day": 20000,
    "day_resets": "00:00 UTC",
    "requests_total": 400,
    "requests_total_used": 3,
    "requests_total_remaining": 397
  }
}

2. Einen Katalog lesen. Ein Aufruf je Katalog - materials, machines oder treatments - oder GET /config für das gesamte Preisdokument auf einmal.

curl
curl https://app.metronq.com/api/v1/integration/catalog/materials \
  -H "Authorization: Bearer mq_live_YOUR_KEY"
json
{
  "catalog": "materials",
  "count": 12,
  "items": [
    {
      "key": "alu_6061",
      "name": "Aluminium 6061",
      "kind": "metal",
      "en_number": "EN AW-6061",
      "din_number": "3.3211",
      "density_g_cm3": 2.7,
      "price_per_kg": 6.4,
      "mrr_rough_cm3_min": 50.0,
      "mrr_turning_cm3_min": 60.0,
      "finishing_rate_cm2_min": 90.0,
      "stock_allowance_mm": 3.0,
      "cutting_speed_m_min": 250.0
    }
  ]
}

3. Neue Anfragen abholen. Fragen Sie nach allem, was nach dem neuesten created_at entstanden ist, das Sie bereits haben; auf unserer Seite ist kein Cursor zu führen. limit ist 1 bis 200, offset blättert durch den Rest.

curl
curl "https://app.metronq.com/api/v1/integration/quotes?since=2026-09-16T00:00:00Z&limit=50" \
  -H "Authorization: Bearer mq_live_YOUR_KEY"
json
{
  "items": [
    {
      "id": "6f1c0f5a-2a4d-4d7e-9f0b-2c9b8f0a1d33",
      "number": 1042,
      "status": "priced",
      "created_at": "2026-09-16T08:41:12+00:00",
      "filename": "bracket.step",
      "material_key": "alu_6061",
      "quantity": 25,
      "unit_price": 41.5,
      "total_price": 1037.5,
      "currency": "EUR",
      "customer_email": "einkauf@example.com",
      "external_ref": "",
      "source": "widget"
    }
  ],
  "limit": 50,
  "offset": 0
}

4. Lesen, was die Analyse gemessen hat - dann, wenn Sie das Teil brauchen und nicht den Preis. Ein Aufruf je Kalkulation.

curl
curl https://app.metronq.com/api/v1/integration/quotes/QUOTE_ID/metrics \
  -H "Authorization: Bearer mq_live_YOUR_KEY"
json
{
  "quote_id": "6f1c0f5a-2a4d-4d7e-9f0b-2c9b8f0a1d33",
  "analyzed_at": "2026-09-16T08:41:29+00:00",
  "file_extension": ".step",
  "status": "priced",
  "gate_status": "instant",
  "gate_reasons": [],
  "complexity": 34.2,
  "material_key": "alu_6061",
  "quantity": 25,
  "tolerance_class": "standard",
  "surface_finish": "as_machined",
  "confirmed_threads": { "8.0": 4 },
  "geometry_metrics": {
    "bounding_box": { "x": 120.0, "y": 80.0, "z": 18.0 },
    "volume": 74210.5,
    "surface_area": 31890.2,
    "face_count": 46,
    "holes": [
      { "diameter": 8.2, "depth": 18.0, "through": true, "direction": [0, 0, 1] }
    ],
    "pockets": [
      { "depth": 6.0, "floor_area": 1840.0, "corner_radius": 5.0, "open": false }
    ],
    "min_wall_thickness": 3.1,
    "derived": { "volume_ratio": 0.43, "area_ratio": 1.71 }
  },
  "parts": []
}

5. Die eigene Nummer zurückschreiben und den Auftrag so bewegen, wie er sich in Ihrer Fertigung bewegt. Geändert wird ausschließlich, was Sie senden.

curl
curl -X PATCH https://app.metronq.com/api/v1/integration/orders/ORDER_ID \
  -H "Authorization: Bearer mq_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"external_ref": "WO-2026-0912", "status": "in_production"}'
json
{
  "id": "1b7a44c0-9d2e-4e51-8a10-64d1f0a2e777",
  "quote_id": "6f1c0f5a-2a4d-4d7e-9f0b-2c9b8f0a1d33",
  "status": "in_production",
  "payment_status": "unpaid",
  "external_ref": "WO-2026-0912",
  "quantity": 25,
  "unit_price": 41.5,
  "total_price": 1037.5,
  "currency": "EUR",
  "customer": { "name": "Anna Muster", "email": "einkauf@example.com", "city": "Musterstadt" }
}

6. Die Preisliste aus dem ERP aktualisieren - zwei Aufrufe, Vorschau und Übernahme. Die Vorschau schreibt nichts und liefert einen base_hash, den die Übernahme zurückgeben muss.

Was ein Schlüssel darf

  • config:read - Katalog und Kalkulationsregeln lesen.
  • config:write - sie aktualisieren, über dieselbe Vorschau-dann-Anwenden-Strecke, die auch das Panel nutzt.
  • quotes:read - Kalkulationen und Bestellungen lesen: Teil, Werkstoff, Menge, Preis und Auslesebericht. Die Kontaktdaten gehören nicht mehr dazu - dafür gibt es unten customers:read. Ein Schlüssel damit sieht jede Anfrage, die der Betrieb je angenommen hat; geben Sie ihn einem System, das die Aufträge braucht.
  • customers:read - die Kontaktdaten des Kunden auf Anfragen und Aufträgen lesen. Eine Ergänzung zu quotes:read, kein eigener Scope: ohne ihn kommen die Zeilen weiterhin zurück, nur sind customer_email, der ganze customer-Block und die Notiz des Kunden null. Für ein System, dem Teil, Menge und Preis genügen, ausgeschaltet lassen - ein Schlüssel, der keinen Namen lesen kann, kann auch keine Kundenliste abziehen.
  • quotes:write - die eigene Nummer zurückschreiben und einen Auftrag durch seine Status bewegen. Kalkulieren oder freigeben kann dieser Schlüssel nichts.

Kein Schlüssel kann einen weiteren Schlüssel erstellen, einen widerrufen oder Berechtigungen ändern. Das bleibt dem angemeldeten Inhaber vorbehalten; ein gestohlener Schlüssel kann seine Gültigkeit also nicht selbst verlängern. Ein Schlüssel läuft nach einem Jahr ab, sofern nichts anderes gewählt wird, und ein Widerruf wirkt ab der nächsten Anfrage.

Was die API lesen kann

Alles, was das Panel über den eigenen Katalog und die eigenen Anfragen dieses Betriebs zeigt, und nichts über irgendeinen anderen. Jede Frage hat genau einen Endpunkt:

  • Werkstoffe - der ganze Katalog: die Bezeichnungen, die ein Konstrukteur liest (EN-Nummer und Werkstoffnummer), Dichte, Preis je Kilogramm, Zerspanleistungen und Schnittgeschwindigkeit. GET /catalog/materials
  • Maschinen - der Park: Technologie, Stundensatz, Arbeitsraum, Achsenzahl, Spindelleistung und Höchstdrehzahl, Werkzeugplätze, maximales Werkstückgewicht sowie der Datenblattteil daneben (Hersteller, Modell, Steuerung, Baujahr, Inventarnummer). GET /catalog/machines
  • Werkzeuge - die Werkzeugbibliothek als flache Liste; jede Zeile nennt die Maschine, in der das Werkzeug sitzt, und den Eckenradius, den die Engine daraus ableitet. GET /tools
  • Schnittdaten - je Werkstoff die Schnittgeschwindigkeit und die Zerspanleistungen, aus denen eine Kalkulation gerechnet wird, je Maschine die Spindeldaten, mit denen diese Leistungen skaliert werden. GET /cutting-data
  • Behandlungen - Oberflächen- und Wärmebehandlung mit Kosten und Durchlaufzeiten. GET /catalog/treatments
  • Anfragen und Aufträge - GET /quotes und GET /orders, neueste zuerst, mit since= abfragbar. Eine einzelne Kalkulation trägt die Preisaufschlüsselung, ein Auftrag die Kundendaten für Rechnung und Versand.
  • Der Auslesebericht einer Datei - was die Analyse gemessen hat: Abmaße, Gewicht, Bohrungen, Taschen, Gewinde, Flächen und Toleranzen, bei einer Baugruppe je Teil. GET /quotes/{id}/metrics

Zwei davon brauchen je einen Satz. Ein Werkzeug gehört zu einer MASCHINE - es ist das, wonach diese Spindel greifen kann - deshalb nennt jede Zeile ihre Maschine, und Werkzeuge sind das Einzige, was die Katalogtabelle nicht transportieren kann, weil eine Zeile keinen Platz für eine Liste hat. Und Schnittdaten sind keine Schnittwerttabelle: In MetronQ gibt es weder Vorschub je Zahn noch Schnitttiefe, weil das Zeitmodell mit Zerspanleistungen je Werkstoff rechnet. Dieser Endpunkt veröffentlicht die vollständigen Zahlen hinter einem Preis - die eigenen des Betriebs und die zwei, die die Engine daraus ableitet - damit ein angebundenes System denselben Blick auf einen Werkstoff hat wie die Engine, die damit kalkuliert.

Was jedes Feld bedeutet

Die Einheiten stehen überall dort im Feldnamen, wo Zweifel möglich wären: _mm, _kg, _cm3_min, _m_min. Alles ist eine einfache JSON-Zahl oder -Zeichenkette, nichts ist ein formatierter Betrag, und jeder Preis steht in der Währung des Betriebs - jener, die whoami liefert.

Werkstoff (GET /catalog/materials):

  • key - die Kennung, auf die sich eine Kalkulation als material_key bezieht. Darüber einigen sich Ihr System und unseres auf einen Werkstoff; ein geänderter Schlüssel ist ein neuer Werkstoff, keine Umbenennung.
  • name - was der Kunde des Betriebs im Widget und im Angebot liest. Es ist die Formulierung des Betriebs und wird deshalb nicht übersetzt.
  • kind - metal oder plastic. Entscheidet, welche Toleranzen, Passungen und Oberflächen überhaupt angeboten werden.
  • en_number, din_number - die Normbezeichnungen (EN AW-6061, 1.0503). Für den Konstrukteur; die Engine rechnet nie damit.
  • density_g_cm3 - Dichte in g/cm3. Daraus ergeben sich Teilegewicht und damit die Materialkosten.
  • price_per_kg - Einkaufspreis je Kilogramm in der Währung des Betriebs. Das mit Abstand am häufigsten aus einem ERP geschriebene Feld.
  • mrr_rough_cm3_min - Schruppzeitspanvolumen in cm3/min, bezogen auf die Referenzspindel mit 15 kW. Es macht den Unterschied, dass sich ein Werkstoff langsamer zerspanen lässt als ein anderer.
  • mrr_turning_cm3_min - dasselbe fürs Drehen. null bedeutet: das Schruppvolumen verwenden.
  • finishing_rate_cm2_min - wie schnell ein Schlichtgang Fläche abdeckt, in cm2/min.
  • stock_allowance_mm - Aufmaß je Seite bei der Rohteilwahl, in mm.
  • cutting_speed_m_min - Schnittgeschwindigkeit vc in m/min. null heißt, sie wird aus dem Schruppvolumen abgeleitet; GET /cutting-data zeigt den tatsächlich verwendeten Wert.

Maschine (GET /catalog/machines) - die Felder, die über einen Preis oder eine Ablehnung entscheiden:

  • key, name - Kennung und der Name in der Halle.
  • technology - milling, turning, bar_turning oder mill_turn. Entscheidet, welche Teile die Maschine annehmen darf und welches Zeitspanvolumen gilt.
  • hourly_rate - Maschinenstundensatz in der Währung des Betriebs. Wird von einem Katalogimport unsererseits nie geschrieben: das ist die Zahl, die ein Betrieb vertreten können muss.
  • envelope_mm - Arbeitsraum. Drei Zahlen bei einer Fräsmaschine (x, y, z); bei einer Drehmaschine ist die erste der Drehdurchmesser und die zweite die Drehlänge.
  • axes - Achsenzahl, beim Fräsen 3 bis 5. Über 3 braucht ein Teil weniger Aufspannungen.
  • spindle_power_kw - Spindelleistung. Unterhalb der Referenz von 15 kW werden die Zeitspanvolumina proportional gesenkt; oberhalb wird nichts erhöht, eine angegebene Leistung kann eine Kalkulation also nur verteuern.
  • max_spindle_rpm - Höchstdrehzahl. Sie zählt nur bei kleinen Werkzeugen, wo die für die Schnittgeschwindigkeit nötige Drehzahl nicht erreicht wird.
  • min_tool_radius_mm - der kleinste Innenradius, den diese Maschine hinterlassen kann. Wird in dem Moment nicht mehr gelesen, in dem die Maschine eine Werkzeugbibliothek hat: dann entscheidet das kleinste Werkzeug.
  • tool_stations, max_workpiece_kg, through_spindle_coolant - Magazinplätze, Tischlast, Kühlmittel durch die Spindel.
  • datasheet - maker, model, control, year, serial, inventory_no, notes. Nur Identifikation; nichts aus diesem Block erreicht die Engine.

Werkzeug (GET /tools):

json
{
  "count": 2,
  "items": [
    {
      "key": "e12",
      "kind": "endmill",
      "name": "12 mm Hartmetall, 4 Schneiden",
      "diameter_mm": 12.0,
      "nose_radius_mm": null,
      "flute_length_mm": 45.0,
      "designation": "",
      "machine_key": "dmu50",
      "machine_name": "DMU 50",
      "cut_radius_mm": 6.0
    }
  ]
}
  • machine_key, machine_name - die Maschine, in der das Werkzeug sitzt. Ein Werkzeug gehört immer zu einer.
  • kind - drill, endmill, tap, thread_mill, reamer oder turning_insert.
  • diameter_mm - Schneiddurchmesser. Bei Bohrer und Reibahle die erzeugte Bohrung; beim Schaftfräser der Fräser selbst; beim Gewindebohrer der Gewindenenndurchmesser.
  • nose_radius_mm - Eckenradius einer Drehplatte, die kleinste Rundung, die sie auf einer gedrehten Kontur hinterlässt.
  • flute_length_mm - nutzbare Schneidenlänge in mm. null heißt, es ist keine Grenze angegeben, und die Engine setzt dann auch keine.
  • cut_radius_mm - der kleinste Innenradius, den dieses Werkzeug hinterlässt, von uns berechnet: der halbe Durchmesser oder der Eckenradius der Platte. Der kleinste davon auf einer Maschine wird zu deren tatsächlicher Eckengrenze.

Schnittdaten (GET /cutting-data) - die beiden Spalten, die die Engine ableitet, neben den Zahlen des Betriebs:

json
{
  "reference": { "spindle_power_kw": 15.0, "cutting_speed_m_min": 250.0 },
  "materials": [
    {
      "key": "steel_c45",
      "name": "Stahl C45",
      "kind": "metal",
      "en_number": "1.0503",
      "din_number": "",
      "density_g_cm3": 7.85,
      "cutting_speed_m_min": null,
      "cutting_speed_effective_m_min": 156.2,
      "machinability_factor": 1.6,
      "mrr_rough_cm3_min": 19.5,
      "mrr_turning_cm3_min": null,
      "mrr_turning_effective_cm3_min": 19.5,
      "finishing_rate_cm2_min": 40.0,
      "stock_allowance_mm": 3.0
    }
  ],
  "machines": [
    {
      "key": "dmu50",
      "name": "DMU 50",
      "technology": "milling",
      "spindle_power_kw": 13.0,
      "max_spindle_rpm": 10000.0,
      "spindle_power_factor": 0.867,
      "min_tool_radius_mm": 1.0,
      "tool_radius_effective_mm": 6.0,
      "tool_count": 2
    }
  ]
}
  • reference - die Spindel und die Schnittgeschwindigkeit, auf die die gesamte Preisliste geschrieben ist: 15 kW und 250 m/min. Sie werden mitgeliefert, damit die Ableitung unten nachgerechnet und nicht geglaubt werden muss.
  • cutting_speed_effective_m_min - die tatsächlich verwendete Schnittgeschwindigkeit: die eigene des Betriebs, wenn er eine eingetragen hat, sonst reference / machinability_factor.
  • machinability_factor - um wie viel schwerer als Aluminium sich dieser Werkstoff zerspanen lässt: 1,0 Aluminium, etwa 1,6 ein gewöhnlicher Stahl, etwa 3 ein nichtrostender. Es ist die Wurzel aus dem Verhältnis der Zeitspanvolumina zur Aluminium-Basis.
  • mrr_turning_effective_cm3_min - das Drehvolumen mit bereits angewandter Ersatzregel, damit ein Leser sie nicht wiederholen muss.
  • spindle_power_factor - wie die Zeitspanvolumina auf dieser Maschine skaliert werden: spindle_power_kw / 15, nach oben auf 1,0 begrenzt und nach unten auf 0,25.
  • tool_radius_effective_mm - der tatsächlich geltende Eckenradius: der eingetragene min_tool_radius_mm oder das kleinste Werkzeug der Bibliothek, sobald es eine gibt.

Anfrage und Auftrag (GET /quotes, GET /orders):

  • id - die Kennung, die jeder weitere Aufruf entgegennimmt. number ist die menschenlesbare, die der Betrieb als WYC-1042 sieht.
  • status - wo die Anfrage steht: created, analyzing, priced, approved, rejected, analysis_failed. Einen Preis tragen nur priced und approved.
  • unit_price, total_price, currency - Preis je Stück und für die Charge, in der Währung des Betriebs. Eine nie kalkulierte Anfrage hat hier null.
  • material_key, quantity - was der Kunde gewählt hat. material_key verweist in den Katalog oben.
  • external_ref - Ihre eigene Nummer. Leer, bis Ihr System eine schreibt; danach finden Sie den Auftrag darüber mit ?external_ref= wieder.
  • source - woher die Anfrage stammt: widget (die Website des Betriebs) oder panel (ein Techniker hat die Datei hochgeladen). Leer bei Anfragen von vor der Einführung dieses Feldes.
  • customer_email - die einzige Kontaktangabe, die eine Anfrage trägt. Alles Weitere zur Person erscheint erst mit einer Bestellung.
  • customer_email, customer, note - null, wenn der Schlüssel customers:read nicht trägt. customer_data_visible sagt, welcher der beiden Fälle vorliegt, denn "dieser Schlüssel darf es nicht lesen" und "niemand hat eine Adresse hinterlassen" sind verschiedene Tatsachen, und wer sie verwechselt, verfolgt einen Kunden, den es nicht gibt.
  • Beim Auftrag zusätzlich: status (new, confirmed, in_production, shipped, cancelled), payment_status (unpaid, paid) sowie customer mit vollständiger Rechnungs- und Lieferanschrift.
  • breakdown - nur bei GET /quotes/{id}: die gespeicherte Kostenaufschlüsselung hinter dem Preis, also das, was ein System für die eigene Nachkalkulation braucht.

Auslesebericht einer Datei (GET /quotes/{id}/metrics) - Arbeitsvorbereitung:

  • geometry_metrics.bounding_box - Abmaße in mm. derived.bbox_sorted_dims sind dieselben drei Zahlen sortiert, und darauf wird die Machbarkeit entschieden.
  • geometry_metrics.volume, surface_area - Teilevolumen in mm3 und Oberfläche in mm2. derived.volume_ratio ist Volumen geteilt durch Hüllquader: ein niedriger Wert heißt, es geht viel Material herunter.
  • holes[] - jede gezählte Bohrung: Durchmesser, Tiefe, ob durchgehend, und ihre Achse. Eine Bohrung wird gezählt, weil sie ein voller Kreis ist, nicht weil sie groß ist.
  • pockets[] - Tiefe, Bodenfläche, Eckenradius und ob die Tasche offen oder durchgehend ist.
  • min_wall_thickness - die dünnste gefundene Wand in mm, oder null, wenn nichts hinreichend Dünnes gemessen wurde.
  • gate_status, gate_reasons - ob die Kalkulation automatisch möglich war, und wenn nicht, warum: code:machine:field:actual:limit, mit der Messung hinter der Ablehnung.

Alle Aufrufe, mit Beispiel

Basisadresse https://app.metronq.com, der Schlüssel im Header Authorization: Bearer, JSON in beide Richtungen außer dort, wo ein Pfad auf .csv endet. Die Berechtigung neben jeder Zeile ist der Scope, den der Schlüssel tragen muss; whoami braucht keinen.

GET /whoami - ohne Berechtigung. Wem der Schlüssel gehört, was er darf und wie viel er verbrauchen darf. Der erste Aufruf, den man schreibt, und der, der ein späteres 403 in einen Satz verwandelt.

curl
curl https://app.metronq.com/api/v1/integration/whoami \
  -H "Authorization: Bearer mq_live_YOUR_KEY"

GET /config - config:read. Das gesamte Preisdokument: drei Kataloge, alle Kalkulationsparameter, die Sicherheitsschranken, die Auswahlstrategien und die Währung. Genau das nimmt der Import wieder entgegen - Sie können das Dokument unverändert zurückschicken, ohne jede Umhüllung. Der Modus replace, der auch löscht, was das Dokument nicht nennt, wird gesondert angefordert: {"config": ..., "mode": "replace"}.

curl
curl https://app.metronq.com/api/v1/integration/config \
  -H "Authorization: Bearer mq_live_YOUR_KEY" > pricing.json

GET /catalog/{name} - config:read. Ein Katalog als JSON, wobei {name} materials, machines oder treatments ist. Antwortet mit {catalog, count, items}.

curl
curl https://app.metronq.com/api/v1/integration/catalog/materials \
  -H "Authorization: Bearer mq_live_YOUR_KEY"

GET /catalog/{name}.csv - config:read. Derselbe Katalog als die Tabelle, die der Export-Knopf im Panel erzeugt: BOM für Excel, der Trenner des Betriebs, eine Zeile je Eintrag. Maschinen verlieren hier ihre Werkzeugliste - eine Zeile hat dafür keinen Platz.

curl
curl https://app.metronq.com/api/v1/integration/catalog/machines.csv \
  -H "Authorization: Bearer mq_live_YOUR_KEY" > machines.csv
csv
key;name;technology;hourly_rate;min_quantity;envelope_mm.1;envelope_mm.2;...
dmu50;DMU 50;milling;280,00;1;500,0;450,0;400,0;...

GET /tools - config:read. Alle Werkzeuge des Betriebs, flach, jede Zeile nennt ihre Maschine. ?machine= grenzt auf eine ein.

curl
curl https://app.metronq.com/api/v1/integration/tools \
  -H "Authorization: Bearer mq_live_YOUR_KEY"
curl "https://app.metronq.com/api/v1/integration/tools?machine=dmu50" \
  -H "Authorization: Bearer mq_live_YOUR_KEY"

GET /machines/{key}/tools - config:read. Die Bibliothek einer Maschine und der Eckenradius, der daraus folgt.

curl
curl https://app.metronq.com/api/v1/integration/machines/dmu50/tools \
  -H "Authorization: Bearer mq_live_YOUR_KEY"
json
{
  "machine_key": "dmu50",
  "machine_name": "DMU 50",
  "count": 3,
  "min_tool_radius_mm": 1.0,
  "tool_radius_effective_mm": 3.4,
  "items": [
    {
      "key": "e12",
      "kind": "endmill",
      "name": "12 mm Hartmetall",
      "diameter_mm": 12.0,
      "nose_radius_mm": null,
      "flute_length_mm": 45.0,
      "designation": "",
      "machine_key": "dmu50",
      "machine_name": "DMU 50",
      "cut_radius_mm": 6.0
    },
    { "key": "d6.8", "kind": "drill", "diameter_mm": 6.8, "cut_radius_mm": 3.4, "...": "..." },
    { "key": "m8", "kind": "tap", "diameter_mm": 8.0, "designation": "M8", "...": "..." }
  ]
}

PUT /machines/{key}/tools - config:write. Die ganze Bibliothek ersetzen. Idempotent, ein Abgleich kann also die Liste senden, die er hat, ohne zu wissen, was vorher hier stand. Zwei Werkzeuge unter einem Schlüssel: 422 duplicate_tool_key.

curl
curl -X PUT https://app.metronq.com/api/v1/integration/machines/dmu50/tools \
  -H "Authorization: Bearer mq_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"tools": [
        {"key": "e12", "kind": "endmill", "name": "12 mm Hartmetall",
         "diameter_mm": 12.0, "flute_length_mm": 45.0},
        {"key": "d6.8", "kind": "drill", "diameter_mm": 6.8},
        {"key": "m8", "kind": "tap", "diameter_mm": 8.0, "designation": "M8"}
      ]}'

POST /machines/{key}/tools - config:write. Ein Werkzeug hinzufügen oder das unter diesem Schlüssel ersetzen. Für das System, das eine einzelne Änderung meldet, statt zweihundert Einträge erneut zu senden.

curl
curl -X POST https://app.metronq.com/api/v1/integration/machines/dmu50/tools \
  -H "Authorization: Bearer mq_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"key": "r8h7", "kind": "reamer", "diameter_mm": 8.0}'

DELETE /machines/{key}/tools/{tool} - config:write. Ein Werkzeug entfernen. 404, wenn dieser Schlüssel nicht in der Bibliothek ist, damit ein Abgleich eine Entfernung von einem Tippfehler im eigenen Mapping unterscheiden kann.

curl
curl -X DELETE https://app.metronq.com/api/v1/integration/machines/dmu50/tools/r8h7 \
  -H "Authorization: Bearer mq_live_YOUR_KEY"
Tipp

Das Schreiben einer Werkzeugbibliothek ÄNDERT, was die Maschine kalkulieren kann. Der kleinste SCHAFTFRÄSER darin - an einer Drehmaschine die Wendeplatte - wird zum kleinsten Innenradius, den diese Maschine hinterlassen kann, und der eingetragene min_tool_radius_mm wird nicht mehr gelesen; Bohrer und Gewindebohrer hinterlassen keine Ecke und ändern hier nichts - ein Park, der nur mit 12-mm-Fräsern beschrieben ist, kalkuliert Teile nicht mehr, die er vorher angenommen hat. Genau deshalb liefert hier jede Antwort tool_radius_effective_mm. Eine leere Liste setzt die Maschine auf ihren eingetragenen Wert zurück.

GET /cutting-data - config:read. Je Werkstoff die Schnittgeschwindigkeit und die Zeitspanvolumina, aus denen ein Preis gerechnet wird; je Maschine die Spindel, mit der diese skaliert werden. Keine Schnittwerttabelle - siehe oben.

curl
curl https://app.metronq.com/api/v1/integration/cutting-data \
  -H "Authorization: Bearer mq_live_YOUR_KEY"

POST /config/import/preview - config:write. Was diese Tabelle tun würde. Schreibt nichts und antwortet mit dem entstehenden Dokument, den neuen und geänderten Schlüsseln, den nicht lesbaren Zeilen, den nicht erkannten Spalten und einem base_hash.

curl
curl -X POST https://app.metronq.com/api/v1/integration/config/import/preview \
  -H "Authorization: Bearer mq_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"catalog\": \"materials\", \"csv_base64\": \"$(base64 -w0 materials.csv)\"}"

POST /config/import/preview-json - config:write. Dasselbe für ein ganzes Dokument. merge wendet nur an, was das Dokument tatsächlich nennt; replace lässt es vollständig gewinnen, Löschungen eingeschlossen.

curl
curl -X POST https://app.metronq.com/api/v1/integration/config/import/preview-json \
  -H "Authorization: Bearer mq_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"mode": "merge", "config": {"materials": [ ... ], "machines": [ ... ]}}'

POST /config/import - config:write. Das anwenden, was eine Vorschau geliefert hat, unter Angabe des base_hash. 409 config_changed, wenn jemand zwischendurch die Preisliste gespeichert hat. Antwortet mit dem gespeicherten Dokument.

curl
curl -X POST https://app.metronq.com/api/v1/integration/config/import \
  -H "Authorization: Bearer mq_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d @commit.json      # {"config": ..., "base_hash": "..."} from the preview
json
{
  "materials": [ { "key": "alu-6061", "price_per_kg": 32.0, "...": "..." } ],
  "machines": [ "..." ],
  "treatments": [ "..." ],
  "params": { "margin_pct": 30.0, "...": "..." },
  "gates": { "mode": "review_all", "...": "..." },
  "machine_selection": "cheapest",
  "stock_selection": "cheapest",
  "currency": "PLN"
}

GET /quotes - quotes:read. Anfragen, neueste zuerst. since= ist das, worauf ein Poll läuft; status=, external_ref=, limit (1-200) und offset erledigen den Rest. Ohne customers:read sind die Kontaktfelder null.

curl
curl "https://app.metronq.com/api/v1/integration/quotes?since=2026-09-16T00:00:00Z&status=priced&limit=50&offset=0" \
  -H "Authorization: Bearer mq_live_YOUR_KEY"

GET /quotes/{id} - quotes:read. Eine Anfrage samt gespeicherter Kostenaufschlüsselung hinter ihrem Preis.

curl
curl https://app.metronq.com/api/v1/integration/quotes/QUOTE_ID \
  -H "Authorization: Bearer mq_live_YOUR_KEY"

GET /quotes/{id}/metrics - quotes:read. Was die Analyse gemessen hat. 409 not_analysed, solange die Datei noch gelesen wird - das heißt 'gleich nochmal fragen', nicht 'falsche Kennung'.

curl
curl https://app.metronq.com/api/v1/integration/quotes/QUOTE_ID/metrics \
  -H "Authorization: Bearer mq_live_YOUR_KEY"

GET /orders - quotes:read. Aufträge, neueste zuerst, dieselben Filter. Aufträge, die der Betrieb in den Papierkorb gelegt hat, fehlen hier. Ohne customers:read sind die Kontaktfelder null.

curl
curl "https://app.metronq.com/api/v1/integration/orders?since=2026-09-16T00:00:00Z&external_ref=WO-2026-0912" \
  -H "Authorization: Bearer mq_live_YOUR_KEY"
json
{
  "items": [
    {
      "id": "1b7a44c0-9d2e-4e51-8a10-64d1f0a2e777",
      "quote_id": "6f1c0f5a-2a4d-4d7e-9f0b-2c9b8f0a1d33",
      "status": "confirmed",
      "payment_status": "unpaid",
      "created_at": "2026-09-16T09:12:40+00:00",
      "paid_at": null,
      "quantity": 25,
      "unit_price": 41.5,
      "total_price": 1037.5,
      "currency": "EUR",
      "external_ref": "WO-2026-0912",
      "customer": {
        "name": "Anna Muster",
        "email": "einkauf@example.com",
        "company": "Muster GmbH",
        "phone": "+49 000 0000000",
        "address": "Musterstraße 4",
        "postcode": "00000",
        "city": "Musterstadt"
      },
      "note": ""
    }
  ],
  "limit": 100,
  "offset": 0
}

GET /orders/{id} - quotes:read. Ein Auftrag mit den Kundendaten für Rechnung und Versand.

curl
curl https://app.metronq.com/api/v1/integration/orders/ORDER_ID \
  -H "Authorization: Bearer mq_live_YOUR_KEY"

PATCH /quotes/{id} - quotes:write. Die eigene Nummer auf einer Anfrage und sonst nichts: Preis und Freigabe gehören der Engine und einem Arbeitsvorbereiter.

curl
curl -X PATCH https://app.metronq.com/api/v1/integration/quotes/QUOTE_ID \
  -H "Authorization: Bearer mq_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"external_ref": "RFQ-2026-0455"}'

PATCH /orders/{id} - quotes:write. Eigene Nummer, Status und Zahlungsmarkierung. Angefasst wird nur, was im Body steht. confirmed und shipped senden dem Kunden des Betriebs eine E-Mail.

curl
curl -X PATCH https://app.metronq.com/api/v1/integration/orders/ORDER_ID \
  -H "Authorization: Bearer mq_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"external_ref": "WO-2026-0912", "status": "in_production",
       "payment_status": "paid"}'

Wie viele Anfragen ein Schlüssel hat

Der API-Zugang wird mit jedem Betrieb einzeln vereinbart, und seine Limits ebenso - sie gehören zur selben Absprache und sind kein veröffentlichter Tarif. Eine vereinbarte Integration läuft mit 120 Anfragen pro Minute und 20 000 pro Tag, gezählt ab 00:00 UTC. Ein stündlicher Katalogabgleich samt minütlicher Abfrage neuer Anfragen bleibt deutlich darunter; braucht Ihr System mehr, sagen Sie es uns, und wir setzen eine passende Zahl. Ein Betrieb kann außerdem einen einzelnen eigenen Schlüssel schon beim Anlegen strenger begrenzen als die übrigen.

Ein Schlüssel für eine TESTPHASE trägt stattdessen eine dritte Zahl: 400 Anfragen für den ganzen Test, die am nächsten Tag nicht wiederkommen. Das ist der Umfang eines kostenlosen Tests: genug, um eine Anbindung dagegen zu bauen - die gesamte Schnittstelle durchzusehen kostet rund dreißig Aufrufe, der Leitfaden oben sechs - und nicht genug, um eine zu betreiben; dafür gibt es die vereinbarte Anbindung. Das Panel zeigt das Kontingent unter Einstellungen, Integrationen, zusammen mit dem bereits Verbrauchten, und whoami liefert es als requests_total. Ist es aufgebraucht, antwortet die API mit 429 und total_quota_exceeded, ohne Retry-After: es gibt keine Uhrzeit, ab der es wieder funktioniert.

Jede Antwort nennt den aktuellen Stand, damit ein Client sein Tempo vor einem Limit anpassen kann und nicht erst danach. Die letzten beiden Zeilen erscheinen nur, solange ein Testkontingent gilt:

http
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 118
X-RateLimit-Reset: 41
X-RateLimit-Quota: 20000
X-RateLimit-Quota-Remaining: 19863
X-RateLimit-Quota-Reset: 51240
X-RateLimit-Total: 400
X-RateLimit-Total-Remaining: 347

Was eine Ablehnung bedeutet

Jeder Fehler antwortet mit einem kurzen Code im Body, und dieser Code ist das, worauf man reagieren kann - der HTTP-Status allein sagt nicht, was als Nächstes zu tun ist.

  • 429 rate_limited - die Minute ist voll. Dieselbe Anfrage funktioniert kurz darauf; Retry-After nennt die Sekunden.
  • 429 daily_quota_exceeded - der Tag ist aufgebraucht. Retry-After zählt bis 00:00 UTC herunter.
  • 429 total_quota_exceeded - ein Testbudget ist aufgebraucht. Kein Retry-After, weil Warten nichts ändert.
  • 401 invalid_api_key - unbekannter, widerrufener oder abgelaufener Schlüssel, oder ein Konto ohne API-Zugang. Bewusst eine Antwort für alle Fälle: eine Unterscheidung wäre für den Dieb des Schlüssels wertvoll und für den Eigentümer wertlos.
  • 403 missing_scope - der Schlüssel ist gültig, hat aber die für diesen Endpunkt nötige Berechtigung nicht. Ein erneuter Versuch hilft nicht, ein Schlüssel mit den richtigen Scopes schon.
  • 404 not_found, unknown_catalog, unknown_machine - diese Kalkulation, dieser Auftrag, dieser Katalog oder diese Maschine gibt es in diesem Konto nicht.
  • 409 config_changed - jemand hat die Preisliste zwischen Vorschau und Bestätigung gespeichert, das übermittelte Dokument beschreibt also nicht mehr, was tatsächlich passieren würde. Konfiguration neu lesen, erneut vorschauen, erneut anwenden.
  • 409 not_analysed - die Kalkulation existiert, hat aber noch keinen Auslesebericht. Die Datei wird noch analysiert; kurz darauf erneut fragen.
  • 422 - die Tabelle oder das Dokument wurde abgelehnt und nichts geschrieben. Der Body nennt den Grund, die Vorschau die Zeilen und Spalten dahinter.
Tipp

Das Muster mq_live_ gehört in den Secret-Scanner des Teams, damit ein versehentlich eingecheckter Schlüssel so auffällt wie jedes andere Geheimnis.

Wer das darf

Import und Export folgen der Berechtigung für die Kalkulationsregeln: Der Inhaber und jeder Mitarbeiter, dem dieser Reiter freigegeben ist, können sie nutzen. Exporte sind gewöhnliche Downloads innerhalb der angemeldeten Sitzung; auf anderem Weg verlässt keine Datei das Konto.

Alles, was diese Seite nicht abdeckt - eine Synchronisation zu fester Zeit oder Angebote, die beim Entstehen automatisch in das eigene System übertragen werden -, geht an contact@metronq.com; die Nennung des eingesetzten Systems entscheidet mit, was als Nächstes entsteht.