Dokumentacja/Integracje
Integracje i wymiana danych
Katalog materiałów, stawki maszyn i reguły cenowe mogą pochodzić z systemu, w którym już są prowadzone - cały cennik da się też pobrać z powrotem.
Katalog może pochodzić z innego systemu
MetronQ przechowuje cały cennik zakładu - kupowane materiały, maszyny, na których pracuje zakład, sprzedawane obróbki oraz parametry, według których liczy silnik - jako jedną konfigurację, możliwą do odczytania i zapisania spoza panelu. Jeśli dane te są już prowadzone w systemie ERP, CRM albo w arkuszu, nie trzeba wpisywać ich drugi raz ani ręcznie pilnować zgodności dwóch kopii.
- Materiały - nazwa, oznaczenie EN i DIN, gęstość, cena za kilogram, wydajności skrawania przy zgrubie i toczeniu, wydajność wykańczania, naddatek na półfabrykat, prędkość skrawania.
- Maszyny - nazwa, technologia, stawka godzinowa, przestrzeń robocza, liczba osi, moc i maksymalne obroty wrzeciona, liczba gniazd narzędziowych, minimalna partia, a także producent, model, sterowanie, rok, numer seryjny i numer inwentarzowy.
- Obróbki - nazwa, rodzaj, koszt za kilogram, koszt za decymetr kwadratowy, stała opłata za partię oraz liczba dni roboczych dodawanych do terminu realizacji.
- Reguły cenowe - marża, minuty przezbrojenia i obsługi, minimalny cykl, terminy realizacji, mnożnik ekspresu, dostawa, stawka VAT oraz tabele mnożników dla klasy tolerancji, klasy geometrii i wykończenia powierzchni.
Formaty są dwa, a wybór zależy od tego, co znajduje się po drugiej stronie. Osobny arkusz dla każdego katalogu odpowiada temu, co eksportuje większość systemów ERP, i pozwala poprawić dane ręcznie. Jeden dokument JSON z całą konfiguracją to format dla integracji, w której inny system ma samodzielnie utrzymywać dane w MetronQ w stanie aktualnym.
Gdzie to znaleźć
- 1Otworzyć w panelu zakładkę Zasady wyceny.
- 2Wybrać Import i eksport w menu po lewej stronie.
- 3Eksport pobiera plik w formacie opisanym niżej, Import przyjmuje taki plik z powrotem.
Warto zacząć od eksportu, nawet przy planowanym wyłącznie imporcie. Wyeksportowany plik zawiera już dokładne nazwy kolumn i własne klucze katalogowe zakładu, dlatego najprostsze mapowanie po stronie ERP polega na uzupełnieniu tego właśnie pliku.
Format arkusza
Jeden plik na katalog - materiały, maszyny, wykończenia. Pierwszy wiersz zawiera nazwy kolumn; w każdym języku są to angielskie identyfikatory, ponieważ to na nich opiera się mapowanie po stronie systemu zewnętrznego i to one są odczytywane przy imporcie.
- Wiersze dopasowywane są wyłącznie po kolumnie key. Klucz, który MetronQ już zna, zostaje zaktualizowany; klucz nieznany zostaje dodany.
- Odczytywane są wyłącznie kolumny obecne w pliku. Kolumna pominięta oznacza, że pole zachowuje dotychczasową wartość we wszystkich wierszach.
- Pusta komórka oznacza „pozostaw bez zmian”, a nie „wyczyść”. Eksport częściowy - tylko materiały aktualnie dostępne na stanie albo tylko stawki z bieżącego kwartału - jest sytuacją typową, a nie wyjątkiem.
- Import nigdy niczego nie usuwa. Materiał albo maszynę usuwa się w panelu, świadomą decyzją.
- Znak dziesiętny jest powiązany z separatorem kolumn: średnik występuje z przecinkiem dziesiętnym (1234,56), przecinek z kropką (1234.56). Odczytujemy oba warianty, a eksport stosuje separator ustawiony na koncie zakładu.
- Przyjmujemy UTF-8 z sygnaturą BOM i bez niej, a także środkowoeuropejską stronę kodową zapisywaną przez Excel w systemie Windows.
- Jeden plik może zawierać do 20 000 wierszy i mieć rozmiar do 2 MB.
Biblioteki narzędzi celowo nie ma w arkuszu: lista frezów nie mieści się w jednym wierszu. Maszyna zaimportowana z arkusza zachowuje więc bibliotekę, którą już ma, dzięki czemu przejście przez arkusz nie zmieni niepostrzeżenie zakresu detali, które ta maszyna może obrabiać.
Cała konfiguracja jako jeden dokument
Eksport JSON to cała konfiguracja wyceny w takiej postaci, w jakiej przechowuje ją panel; w tej samej postaci wraca przy imporcie. Zawiera trzy katalogi oraz wszystkie parametry wyceny, ustawienia bezpieczników, strategie doboru maszyny i półfabrykatu oraz walutę. Jest to więc format dla systemu, który prowadzi własną kopię cennika zakładu.
- Scal, czyli tryb domyślny, stosuje wyłącznie to, co dokument rzeczywiście zawiera. Plik z trzema materiałami i jedną marżą zmienia trzy materiały i jedną marżę; pozostałe pola zachowują wartości ustawione w panelu.
- Zastąp przyjmuje dokument w całości, łącznie z usunięciami - na wypadek, gdy to inny system ma być nadrzędnym rejestrem danych, a nie tylko ich źródłem.
- Katalogi scalają się po tej samej kolumnie key, której używa arkusz, więc oba formaty jednakowo rozpoznają, że chodzi o ten sam materiał.
Nic nie zostaje zastosowane bez wcześniejszego podglądu
Każdy import zaczyna się od próbnego przebiegu. Zanim zapisana zostanie choćby jedna wartość, panel pokazuje, ile pozycji zostałoby dodanych, a ile zaktualizowanych, różnicę pole po polu między obecnym cennikiem a cennikiem po imporcie, każdy wiersz, którego nie udało się odczytać, oraz każdą kolumnę nierozpoznaną przez MetronQ.
- Wiersz, którego cennik nie przyjmuje - brak gęstości, cena nie będąca liczbą - powoduje odrzucenie całego pliku. Import nigdy nie jest stosowany częściowo, ponieważ częściowo zaimportowany cennik daje ceny błędne w sposób, którego nikt nie zauważy.
- Nierozpoznana kolumna zostaje wymieniona z nazwy. To zabezpieczenie wychwytuje eksport z przesuniętymi kolumnami oraz literówkę w nagłówku, która w przeciwnym razie zostałaby zaimportowana jako brak zmian i wyglądałaby jak plik przyjęty poprawnie.
- Jeśli ktoś zapisze cennik przy otwartym podglądzie, import zostaje odrzucony i trzeba uruchomić go ponownie: różnica widoczna na ekranie przestałaby odpowiadać rzeczywistemu wynikowi.
Każdy zatwierdzony import zapisuje się w historii ustawień, pole po polu, z oznaczeniem „import”, dzięki czemu każdą zmienioną cenę można powiązać z plikiem, który ją zmienił.
Podłączenie systemu bezpośrednio
Wszystkie powyższe operacje można wykonać także bez otwierania panelu: zakład wystawia klucz API i przekazuje go swojemu systemowi ERP, CRM albo narzędziu automatyzacji. Zakres dostępu ustalamy indywidualnie z każdym zakładem - wystarczy napisać, o jaki system chodzi - ponieważ integracja wymaga rozmowy o tym, co znajduje się po drugiej stronie. Klucz należy do zakładu, a nie do osoby, więc działa również wtedy, gdy osoby, która go utworzyła, nie ma w pracy.
- 1Otworzyć w panelu Ustawienia, a w nich sekcję Integracje. Dostęp do niej ma wyłącznie właściciel konta.
- 2Wybrać Nowy klucz, nazwać go zgodnie z systemem, który będzie go używał, i zaznaczyć zakres uprawnień.
- 3Skopiować klucz od razu. Wyświetlamy go jeden raz i nie przechowujemy; w razie utraty należy go odwołać i utworzyć nowy.
Pierwsza integracja krok po kroku
Sześć wywołań w kolejności, w jakiej zwykle się je pisze. Każde używa tego samego nagłówka, więc klient, który poradzi sobie z pierwszym, poradzi sobie ze wszystkimi. Adres bazowy to https://app.metronq.com, a odpowiedzią jest JSON wszędzie tam, gdzie ścieżka nie kończy się na .csv.
1. Sprawdź klucz. whoami nie wymaga żadnego uprawnienia i odpowiada, do jakiego zakładu klucz należy, co wolno mu zrobić i ile może zużyć. Jeśli to wywołanie działa, cała reszta to już tylko kwestia ścieżek.
curl https://app.metronq.com/api/v1/integration/whoami \ -H "Authorization: Bearer mq_live_YOUR_KEY"
{
"tenant": { "name": "Zakład Mechaniczny Kowalski", "slug": "zaklad-kowalski", "currency": "PLN" },
"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. Odczytaj katalog. Jedno wywołanie na katalog - materials, machines albo treatments - albo GET /config po cały dokument cennika naraz.
curl https://app.metronq.com/api/v1/integration/catalog/materials \ -H "Authorization: Bearer mq_live_YOUR_KEY"
{
"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. Odpytaj o nowe zapytania. Poproś o wszystko utworzone po najnowszym created_at, który już masz; po naszej stronie nie ma żadnego kursora do pilnowania. limit to 1 do 200, offset przewija resztę.
curl "https://app.metronq.com/api/v1/integration/quotes?since=2026-09-16T00:00:00Z&limit=50" \ -H "Authorization: Bearer mq_live_YOUR_KEY"
{
"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": 178.5,
"total_price": 4462.5,
"currency": "PLN",
"customer_email": "zakupy@example.com",
"external_ref": "",
"source": "widget"
}
],
"limit": 50,
"offset": 0
}4. Odczytaj, co zmierzyła analiza - wtedy, gdy potrzebujesz detalu, a nie ceny. Jedno wywołanie na wycenę.
curl https://app.metronq.com/api/v1/integration/quotes/QUOTE_ID/metrics \ -H "Authorization: Bearer mq_live_YOUR_KEY"
{
"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. Zapisz własny numer i przesuwaj zamówienie tak, jak przesuwa się na Twojej hali. Zmieniane są wyłącznie pola, które wyślesz.
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"}'{
"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": 178.5,
"total_price": 4462.5,
"currency": "PLN",
"customer": { "name": "Anna Kowalska", "email": "zakupy@example.com", "city": "Warszawa" }
}6. Zaktualizuj cennik z ERP - dwa wywołania: podgląd i zatwierdzenie. Podgląd niczego nie zapisuje i zwraca base_hash, który zatwierdzenie musi odesłać.
Co może klucz
- config:read - odczyt katalogu i reguł cenowych.
- config:write - ich aktualizacja, tą samą ścieżką „najpierw podgląd, potem zastosowanie”, z której korzysta panel.
- quotes:read - odczyt wycen i zamówień: detal, materiał, ilość, cena i odczyt analizy. Nie obejmuje już danych kontaktowych - od tego jest customers:read poniżej. Klucz z tym zakresem widzi każde zapytanie, jakie zakład kiedykolwiek przyjął, więc nadaj go systemowi, który faktycznie potrzebuje zleceń.
- customers:read - odczyt danych kontaktowych klienta w zapytaniach i zamówieniach. To dodatek do quotes:read, a nie osobny zakres: bez niego wiersze nadal wracają, tylko customer_email, cały blok customer i notatka klienta są puste. Zostaw wyłączone dla systemu, któremu wystarczy detal, ilość i cena - klucz, który nie czyta nazwisk, nie wyniesie bazy klientów.
- quotes:write - zapis własnego numeru i przesuwanie zamówienia przez statusy. Nie pozwala niczego wycenić ani zatwierdzić.
Żaden klucz nie może utworzyć kolejnego klucza, odwołać go ani zmienić jego uprawnień. Te operacje pozostają po stronie zalogowanego właściciela, dzięki czemu przejęty klucz nie przedłuży sobie ważności. Klucz wygasa po roku, o ile nie zostanie wybrany inny termin, a odwołanie obowiązuje od następnego żądania.
Co API potrafi odczytać
Wszystko, co panel pokazuje o własnym katalogu i własnych zapytaniach tego zakładu, i nic o żadnym innym. Każde pytanie ma jeden endpoint:
- Materiały - cały katalog: oznaczenia, które czyta konstruktor (numer EN i Werkstoffnummer), gęstość, cena za kilogram, wydajności skrawania i prędkość skrawania. GET /catalog/materials
- Maszyny - park: technologia, stawka godzinowa, przestrzeń robocza, liczba osi, moc i maksymalne obroty wrzeciona, liczba gniazd narzędziowych, maksymalna masa detalu oraz blok danych identyfikacyjnych (producent, model, sterowanie, rok, numer inwentarzowy). GET /catalog/machines
- Narzędzia - biblioteka narzędzi jako płaska lista; każdy wiersz podaje maszynę, w której narzędzie siedzi, i promień naroża, który silnik z niego wyprowadza. GET /tools
- Dane skrawania - dla materiału prędkość skrawania i wydajności, z których liczona jest wycena, dla maszyny możliwości wrzeciona, które te wydajności skalują. GET /cutting-data
- Obróbki - obróbka powierzchniowa i cieplna wraz z kosztami i czasami realizacji. GET /catalog/treatments
- Zapytania i zamówienia - GET /quotes i GET /orders, od najnowszych, do odpytywania parametrem since=. Pojedyncza wycena niesie rozbicie ceny, zamówienie - dane klienta do faktury i wysyłki.
- Odczyt pliku - to, co zmierzyła analiza: gabaryt, masa, otwory, kieszenie, gwinty, ściany i tolerancje, dla każdej części w złożeniu osobno. GET /quotes/{id}/metrics
Dwa z nich wymagają zdania komentarza. Narzędzie należy do MASZYNY - jest tym, po co to wrzeciono może sięgnąć - więc każdy wiersz podaje swoją maszynę, i narzędzia są jedyną rzeczą, której arkusz katalogu nie przeniesie, bo wiersz nie ma miejsca na listę. A dane skrawania to nie tablica parametrów: w MetronQ nigdzie nie ma posuwu na ząb ani głębokości skrawania, bo model czasu pracuje na wydajnościach usuwania materiału. Ten endpoint publikuje komplet liczb stojących za ceną - własne liczby zakładu i dwie, które silnik z nich wyprowadza - żeby podłączony system miał taki sam obraz materiału jak silnik, który go wycenia.
Co oznacza każde pole
Jednostki są w nazwach pól wszędzie tam, gdzie mogłaby być wątpliwość: _mm, _kg, _cm3_min, _m_min. Wszystko jest zwykłą liczbą albo tekstem JSON, nic nie jest sformatowaną kwotą, a każda cena jest w walucie zakładu - tej, którą zwraca whoami.
Materiał (GET /catalog/materials):
- key - identyfikator, do którego wycena odwołuje się jako material_key. To po nim Twój system i nasz zgadzają się co do materiału; zmiana klucza tworzy nowy materiał, a nie zmienia nazwę istniejącego.
- name - to, co czyta klient zakładu w widgecie i na ofercie. Jest to sformułowanie zakładu, więc nie jest tłumaczone.
- kind - metal albo plastic. Decyduje o tym, jakie tolerancje, pasowania i wykończenia są w ogóle oferowane.
- en_number, din_number - oznaczenia normowe (EN AW-6061, 1.0503). Pokazywane konstruktorowi; silnik nigdy na nich nie liczy.
- density_g_cm3 - gęstość w g/cm3. Z niej bierze się masa detalu, a więc i koszt materiału.
- price_per_kg - cena zakupu za kilogram, w walucie zakładu. To najczęściej zapisywane przez ERP pole ze wszystkich.
- mrr_rough_cm3_min - wydajność zgrubna w cm3/min, na wrzecionie referencyjnym 15 kW. To ona sprawia, że jeden materiał obrabia się wolniej niż drugi.
- mrr_turning_cm3_min - to samo dla toczenia. null oznacza: użyj wydajności zgrubnej.
- finishing_rate_cm2_min - jak szybko przejście wykańczające pokrywa powierzchnię, w cm2/min.
- stock_allowance_mm - naddatek dodawany z każdej strony detalu przy doborze półfabrykatu, w mm.
- cutting_speed_m_min - prędkość skrawania vc w m/min. null oznacza, że jest wyprowadzana z wydajności zgrubnej; GET /cutting-data pokazuje wartość faktycznie użytą.
Maszyna (GET /catalog/machines) - pola, które decydują o cenie albo o odmowie:
- key, name - identyfikator i nazwa używana na hali.
- technology - milling, turning, bar_turning albo mill_turn. Decyduje, jakie detale maszyna może przyjąć i która wydajność skrawania obowiązuje.
- hourly_rate - stawka maszynowa za godzinę, w walucie zakładu. Nigdy nie jest zapisywana przez nasz import z katalogu: to liczba, której zakład musi umieć bronić.
- envelope_mm - przestrzeń robocza. Trzy liczby dla frezarki (x, y, z); dla tokarki pierwsza to średnica toczenia, druga długość toczenia.
- axes - liczba osi, 3 do 5 przy frezowaniu. Powyżej 3 detal wymaga mniejszej liczby ustawień.
- spindle_power_kw - moc wrzeciona. Poniżej referencyjnych 15 kW wydajności są proporcjonalnie obniżane; powyżej nic nie jest podnoszone, więc podanie mocy może wycenę tylko podrożyć.
- max_spindle_rpm - maksymalne obroty. Mają znaczenie tylko dla małych narzędzi, gdzie nie da się osiągnąć obrotów wymaganych przez prędkość skrawania.
- min_tool_radius_mm - najmniejszy promień naroża wewnętrznego, jaki ta maszyna zostawi. Przestaje być czytany w chwili, gdy maszyna ma bibliotekę narzędzi: wtedy decyduje najmniejsze narzędzie.
- tool_stations, max_workpiece_kg, through_spindle_coolant - liczba gniazd w magazynie, obciążenie stołu, chłodziwo przez wrzeciono.
- datasheet - maker, model, control, year, serial, inventory_no, notes. Wyłącznie identyfikacja; nic z tego bloku nie dociera do silnika.
Narzędzie (GET /tools):
{
"count": 2,
"items": [
{
"key": "e12",
"kind": "endmill",
"name": "frez 12 mm, węglik, 4 ostrza",
"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 - maszyna, w której narzędzie siedzi. Narzędzie zawsze do jakiejś należy.
- kind - drill, endmill, tap, thread_mill, reamer albo turning_insert.
- diameter_mm - średnica skrawania. Dla wiertła i rozwiertaka otwór, który robi; dla frezu palcowego sam frez; dla gwintownika średnica nominalna gwintu.
- nose_radius_mm - promień naroża płytki tokarskiej, najmniejsze zaokrąglenie, jakie zostawi na toczonym profilu.
- flute_length_mm - użyteczna długość robocza w mm. null oznacza brak podanego ograniczenia i silnik wtedy żadnego nie nakłada.
- cut_radius_mm - najmniejszy promień wewnętrzny, jaki to narzędzie zostawi, policzony przez nas: połowa średnicy albo promień naroża płytki. Najmniejszy z nich na maszynie staje się jej rzeczywistym ograniczeniem naroża.
Dane skrawania (GET /cutting-data) - dwie kolumny, które silnik wyprowadza, obok liczb zakładu:
{
"reference": { "spindle_power_kw": 15.0, "cutting_speed_m_min": 250.0 },
"materials": [
{
"key": "steel_c45",
"name": "Stal 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 - wrzeciono i prędkość skrawania, względem których napisany jest cały cennik: 15 kW i 250 m/min. Zwracamy je po to, żeby poniższe wyprowadzenie dało się sprawdzić, a nie tylko przyjąć na wiarę.
- cutting_speed_effective_m_min - prędkość skrawania faktycznie użyta: własna zakładu, jeśli ją wpisał, w przeciwnym razie reference / machinability_factor.
- machinability_factor - o ile trudniej niż aluminium obrabia się ten materiał: 1,0 aluminium, około 1,6 zwykła stal, około 3 nierdzewna. To pierwiastek ze stosunku wydajności do bazy aluminiowej.
- mrr_turning_effective_cm3_min - wydajność toczenia z już zastosowanym zastępstwem, żeby czytający nie musiał powtarzać tej reguły.
- spindle_power_factor - jak skalowane są wydajności na tej maszynie: spindle_power_kw / 15, ograniczone od góry do 1,0 i od dołu do 0,25.
- tool_radius_effective_mm - promień naroża faktycznie obowiązujący: wpisany min_tool_radius_mm albo najmniejsze narzędzie z biblioteki, jeśli biblioteka istnieje.
Zapytanie i zamówienie (GET /quotes, GET /orders):
- id - identyfikator, który przyjmuje każde inne wywołanie. number to ten czytelny dla człowieka, widoczny w zakładzie jako WYC-1042.
- status - gdzie jest zapytanie: created, analyzing, priced, approved, rejected, analysis_failed. Cenę niosą tylko priced i approved.
- unit_price, total_price, currency - cena za sztukę i za partię, w walucie zakładu. Wycena, która nigdy nie została policzona, ma tu null.
- material_key, quantity - to, co wybrał klient. material_key wskazuje na katalog powyżej.
- external_ref - Twój własny numer. Pusty, dopóki Twój system go nie zapisze; potem znajdziesz po nim zlecenie przez ?external_ref=.
- source - skąd trafiło zapytanie: widget (strona zakładu) albo panel (plik wgrał technolog). Puste na zapytaniach sprzed wprowadzenia tego pola.
- customer_email - jedyna dana kontaktowa, jaką niesie zapytanie. Cała reszta o osobie pojawia się dopiero przy zamówieniu.
- customer_email, customer, note - puste, jeśli klucz nie ma zakresu customers:read. customer_data_visible mówi, który to przypadek, bo "ten klucz nie może tego czytać" i "nikt nie zostawił adresu" to dwa różne fakty, a klient, który je pomyli, będzie gonił nieistniejącego zamawiającego.
- W zamówieniu dodatkowo: status (new, confirmed, in_production, shipped, cancelled), payment_status (unpaid, paid) oraz customer z pełnym adresem do faktury i wysyłki.
- breakdown - tylko w GET /quotes/{id}: zapisane rozbicie kosztów stojące za ceną, czyli to, czego potrzebuje system uzgadniający własne księgi.
Odczyt pliku (GET /quotes/{id}/metrics) - przygotowanie produkcji:
- geometry_metrics.bounding_box - gabaryt w mm. derived.bbox_sorted_dims to te same trzy liczby posortowane, i to na nich rozstrzygana jest wykonalność.
- geometry_metrics.volume, surface_area - objętość detalu w mm3 i powierzchnia w mm2. derived.volume_ratio to objętość przez gabaryt: niski stosunek oznacza, że schodzi dużo materiału.
- holes[] - każdy policzony otwór: średnica, głębokość, czy przelotowy i jego oś. Otwór jest liczony dlatego, że jest pełnym okręgiem, a nie dlatego, że jest duży.
- pockets[] - głębokość, powierzchnia dna, promień naroża i to, czy kieszeń jest otwarta albo przelotowa.
- min_wall_thickness - najcieńsza znaleziona ścianka w mm albo null, gdy nic dostatecznie cienkiego nie zostało zmierzone.
- gate_status, gate_reasons - czy wycenę dało się policzyć automatycznie, a jeśli nie, to dlaczego: code:machine:field:actual:limit, wraz z pomiarem stojącym za odmową.
Wszystkie wywołania, z przykładami
Adres bazowy https://app.metronq.com, klucz w nagłówku Authorization: Bearer, JSON w obie strony poza ścieżkami kończącymi się na .csv. Uprawnienie przy każdej linii to zakres, który klucz musi mieć; whoami nie wymaga żadnego.
GET /whoami - bez uprawnień. Do kogo należy klucz, co mu wolno i ile może zużyć. Pierwsze wywołanie, jakie się pisze, i to, które zamienia późniejsze 403 w zdanie.
curl https://app.metronq.com/api/v1/integration/whoami \ -H "Authorization: Bearer mq_live_YOUR_KEY"
GET /config - config:read. Cały dokument cennika: trzy katalogi, wszystkie parametry, bramki bezpieczeństwa, strategie doboru i waluta. Dokładnie to przyjmuje z powrotem import - możesz odesłać ten dokument bez żadnej otoczki. Trybu replace, który usuwa też to, czego dokument nie wymienia, żąda się osobno: {"config": ..., "mode": "replace"}.
curl https://app.metronq.com/api/v1/integration/config \ -H "Authorization: Bearer mq_live_YOUR_KEY" > pricing.json
GET /catalog/{name} - config:read. Jeden katalog jako JSON, gdzie {name} to materials, machines albo treatments. Odpowiada {catalog, count, items}.
curl https://app.metronq.com/api/v1/integration/catalog/materials \ -H "Authorization: Bearer mq_live_YOUR_KEY"
GET /catalog/{name}.csv - config:read. Ten sam katalog jako arkusz, który produkuje przycisk Eksport w panelu: BOM dla Excela, separator zakładu, jeden wiersz na pozycję. Maszyny tracą tu listę narzędzi - wiersz nie ma na nią miejsca.
curl https://app.metronq.com/api/v1/integration/catalog/machines.csv \ -H "Authorization: Bearer mq_live_YOUR_KEY" > machines.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. Wszystkie narzędzia zakładu, płasko, każdy wiersz podaje swoją maszynę. ?machine= zawęża do jednej.
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. Biblioteka jednej maszyny wraz z promieniem naroża, który z niej wynika.
curl https://app.metronq.com/api/v1/integration/machines/dmu50/tools \ -H "Authorization: Bearer mq_live_YOUR_KEY"
{
"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": "frez 12 mm, węglik",
"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. Podmiana całej biblioteki. Idempotentna, więc synchronizacja może wysłać listę, którą ma, nie wiedząc, co było wcześniej. Dwa narzędzia pod jednym kluczem to 422 duplicate_tool_key.
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": "frez 12 mm, węglik",
"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. Dodanie jednego narzędzia albo podmiana tego, które stoi pod tym kluczem. Dla systemu, który zgłasza pojedynczą zmianę, a nie wysyła dwustu pozycji od nowa.
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. Usunięcie jednego narzędzia. 404, gdy tego klucza nie ma, żeby synchronizacja odróżniła usunięcie od literówki we własnym mapowaniu.
curl -X DELETE https://app.metronq.com/api/v1/integration/machines/dmu50/tools/r8h7 \ -H "Authorization: Bearer mq_live_YOUR_KEY"
Zapis biblioteki narzędzi ZMIENIA to, co maszyna potrafi wycenić. Najmniejszy FREZ PALCOWY w niej - na tokarce płytka - staje się najmniejszym narożem wewnętrznym, jakie ta maszyna zostawi, a wpisane min_tool_radius_mm przestaje być czytane; wiertła i gwintowniki nie zostawiają naroża i nie zmieniają tu nic - więc park opisany samymi frezami 12 mm przestaje wyceniać detale, które wcześniej przyjmował. Dlatego każda odpowiedź zwraca tutaj tool_radius_effective_mm. Pusta lista przywraca maszynie jej wpisaną wartość.
GET /cutting-data - config:read. Dla materiału prędkość skrawania i wydajności, z których liczona jest cena; dla maszyny wrzeciono, które te wydajności skaluje. To nie jest tablica parametrów skrawania - patrz wyżej.
curl https://app.metronq.com/api/v1/integration/cutting-data \ -H "Authorization: Bearer mq_live_YOUR_KEY"
POST /config/import/preview - config:write. Co zrobiłby ten arkusz. Nic nie zapisuje; odpowiada dokumentem wynikowym, kluczami dodanymi i zmienionymi, wierszami nie do odczytania, kolumnami, których nie rozpoznał, oraz base_hash.
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. To samo dla całego dokumentu. merge stosuje tylko to, co dokument faktycznie podaje; replace pozwala mu wygrać w całości, łącznie z usunięciami.
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. Zapis tego, co zwrócił podgląd, z podaniem otrzymanego base_hash. 409 config_changed, gdy ktoś w międzyczasie zapisał cennik. Odpowiada zapisanym dokumentem.
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{
"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. Zapytania, od najnowszych. since= służy do odpytywania; status=, external_ref=, limit (1-200) i offset robią resztę. Bez zakresu customers:read pola kontaktowe są puste.
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. Jedno zapytanie wraz z zapisanym rozbiciem kosztów stojącym za ceną.
curl https://app.metronq.com/api/v1/integration/quotes/QUOTE_ID \ -H "Authorization: Bearer mq_live_YOUR_KEY"
GET /quotes/{id}/metrics - quotes:read. To, co zmierzyła analiza. 409 not_analysed, dopóki plik jest czytany - to znaczy 'zapytaj za chwilę', a nie 'zły identyfikator'.
curl https://app.metronq.com/api/v1/integration/quotes/QUOTE_ID/metrics \ -H "Authorization: Bearer mq_live_YOUR_KEY"
GET /orders - quotes:read. Zamówienia, od najnowszych, te same filtry. Zamówień przeniesionych przez zakład do kosza tu nie ma. Bez zakresu customers:read pola kontaktowe są puste.
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"
{
"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": 178.5,
"total_price": 4462.5,
"currency": "PLN",
"external_ref": "WO-2026-0912",
"customer": {
"name": "Anna Kowalska",
"email": "zakupy@example.com",
"company": "Kowalski sp. z o.o.",
"phone": "+48 22 000 00 00",
"address": "ul. Fabryczna 4",
"postcode": "00-001",
"city": "Warszawa"
},
"note": ""
}
],
"limit": 100,
"offset": 0
}GET /orders/{id} - quotes:read. Jedno zamówienie z danymi klienta do faktury i wysyłki.
curl https://app.metronq.com/api/v1/integration/orders/ORDER_ID \ -H "Authorization: Bearer mq_live_YOUR_KEY"
PATCH /quotes/{id} - quotes:write. Własny numer na zapytaniu i nic poza tym: cena i zatwierdzenie należą do silnika i do technologa.
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. Własny numer, status i znacznik płatności. Ruszane są tylko pola podane w treści. confirmed i shipped wysyłają maila do klienta zakładu.
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"}'Ile zapytań przypada na klucz
Dostęp do API ustalamy indywidualnie z każdym zakładem i tak samo ustalamy jego limity - są częścią tych samych uzgodnień, a nie cennikiem publikowanym z góry. Uzgodniona integracja pracuje na 120 zapytaniach na minutę i 20 000 na dobę, liczonych od godziny 00:00 UTC. Synchronizacja katalogu co godzinę wraz z odpytywaniem o wyceny co minutę mieści się w tym z dużym zapasem; jeśli Wasz system potrzebuje więcej, wystarczy napisać, a ustawimy liczbę pod niego. Zakład może też ograniczyć pojedynczy własny klucz mocniej niż pozostałe - już przy jego tworzeniu.
Klucz wydany na TESTY ma zamiast tego trzecią liczbę: 400 zapytań na cały test, które nie wracają następnego dnia. Tyle wynosi darmowy test: wystarczy, żeby zbudować na tym integrację - przejrzenie całej powierzchni to około trzydziestu wywołań, przewodnik powyżej sześć - i nie wystarczy, żeby ją eksploatować, bo od tego jest integracja uzgodniona. Panel pokazuje limit w Ustawieniach, w sekcji Integracje, razem z tym, ile już zostało zużyte, a whoami zwraca go jako requests_total. Po jego wyczerpaniu odpowiedzią jest 429 z kodem total_quota_exceeded i bez nagłówka Retry-After: nie ma godziny, o której znowu zacznie działać.
Każda odpowiedź mówi, ile zostało, więc klient może dopasować tempo zanim dojdzie do limitu, a nie dopiero potem. Dwa ostatnie wiersze pojawiają się tylko wtedy, gdy obowiązuje limit łączny testów:
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
Co oznacza odmowa
Każdy błąd zwraca krótki kod w treści odpowiedzi i to on jest tym, na co można zareagować - sam status HTTP nie mówi, co zrobić dalej.
- 429 rate_limited - minuta jest pełna. To samo zapytanie zadziała za chwilę; Retry-After podaje, za ile sekund.
- 429 daily_quota_exceeded - doba jest wyczerpana. Retry-After odlicza do godziny 00:00 UTC.
- 429 total_quota_exceeded - wyczerpany budżet testowy. Bez Retry-After, bo czekanie niczego nie zmieni.
- 401 invalid_api_key - klucz nieznany, unieważniony, wygasły albo konto z zamkniętym dostępem do API. Celowo jedna odpowiedź na wszystkie przypadki: rozróżnianie ich byłoby cenne dla tego, kto klucz ukradł, i bezwartościowe dla właściciela.
- 403 missing_scope - klucz jest poprawny, ale nie ma uprawnienia wymaganego przez ten endpoint. Ponowienie nie pomoże; pomoże klucz z właściwymi zakresami.
- 404 not_found, unknown_catalog, unknown_machine - nie ma takiej wyceny, zamówienia, katalogu albo maszyny na tym koncie.
- 409 config_changed - ktoś zapisał cennik między podglądem a zatwierdzeniem, więc wysyłany dokument nie opisuje już tego, co faktycznie by się stało. Odczytaj konfigurację ponownie, zrób podgląd i zatwierdź jeszcze raz.
- 409 not_analysed - wycena istnieje, ale nie ma jeszcze odczytu. Plik jest w analizie; zapytaj za chwilę.
- 422 - arkusz albo dokument został odrzucony i nic nie zostało zapisane. Treść odpowiedzi nazywa przyczynę, a podgląd wylicza wiersze i kolumny, które za nią stoją.
Wzorzec mq_live_ warto dodać do skanera sekretów używanego w zespole, aby klucz omyłkowo umieszczony w repozytorium został wykryty jak każde inne poświadczenie.
Kto może to zrobić
Import i eksport podlegają uprawnieniu do zakładki Zasady wyceny, więc korzysta z nich właściciel oraz każdy pracownik, któremu ją udostępniono. Eksport jest zwykłym pobraniem pliku w ramach zalogowanej sesji; w żaden inny sposób pliki nie opuszczają konta.
Jeśli potrzebne jest coś, czego ta strona nie obejmuje - synchronizacja o stałej porze albo przesyłanie wycen do systemu zakładu w chwili ich powstania - wystarczy napisać na kontakt@metronq.pl i podać, o jaki system chodzi; na tej podstawie ustalamy kolejność prac.
