{"openapi":"3.1.0","info":{"title":"cargo3d API","version":"v1 (1.10.0)","description":"Optymalizacja trasy i załadunku 3D (3L-CVRP, LIFO). Jednostki: mm, kg, km. Wywołanie asynchroniczne: POST zwraca job_id, wynik przez GET lub podpisany webhook (X-Cargo3d-Signature = HMAC-SHA256 z `timestamp.body`, ponowienia z wykładniczym odstępem do 10 prób / 24 h).","contact":{"email":"cargo3d@makespan.pl"}},"servers":[{"url":"https://cargo3d.pl"}],"components":{"securitySchemes":{"bearer":{"type":"http","scheme":"bearer","description":"Klucz API z panelu cargo3d"}},"schemas":{"OptimizeRequest":{"type":"object","properties":{"optimization_settings":{"type":"object","properties":{"optimize_for":{"type":"string","enum":["min_cost","min_distance","min_vehicle_size"],"default":"min_cost"},"distance_matrix_type":{"type":"string","enum":["haversine","real_road_network"],"default":"haversine"},"unassigned_orders_allowed":{"type":"boolean","default":false},"partial_selection":{"type":"string","enum":["route_order","cluster_savings"],"default":"route_order"},"time_limit_s":{"type":"integer","minimum":1,"maximum":300,"default":30},"callback_url":{"type":"string","format":"uri"},"external_ref":{"type":"string","maxLength":200}},"additionalProperties":false,"default":{}},"depots":{"type":"array","items":{"type":"object","properties":{"depot_id":{"type":"string","minLength":1,"maxLength":100},"name":{"type":"string","maxLength":200},"address":{"type":"string","maxLength":300},"location":{"type":"object","properties":{"lat":{"type":"number","minimum":-90,"maximum":90},"lng":{"type":"number","minimum":-180,"maximum":180}},"required":["lat","lng"],"additionalProperties":false}},"required":["depot_id","name","location"],"additionalProperties":false},"minItems":1,"maxItems":1},"vehicles":{"type":"array","items":{"type":"object","properties":{"vehicle_id":{"type":"string","minLength":2,"maxLength":20,"pattern":"^[A-Z0-9](?:[A-Z0-9_-]*[A-Z0-9])?$"},"type":{"type":"string","maxLength":100},"start_location":{"type":"object","properties":{"lat":{"type":"number","minimum":-90,"maximum":90},"lng":{"type":"number","minimum":-180,"maximum":180}},"required":["lat","lng"],"additionalProperties":false},"end_location":{"type":"object","properties":{"lat":{"type":"number","minimum":-90,"maximum":90},"lng":{"type":"number","minimum":-180,"maximum":180}},"required":["lat","lng"],"additionalProperties":false},"cost_per_km":{"type":"number","minimum":0,"default":0},"fixed_cost":{"type":"number","minimum":0,"default":0},"max_weight_kg":{"type":"number","exclusiveMinimum":true,"minimum":0},"cargo_space_dimensions_mm":{"type":"object","properties":{"length":{"type":"integer","exclusiveMinimum":true,"minimum":0,"maximum":20000},"width":{"type":"integer","exclusiveMinimum":true,"minimum":0,"maximum":5000},"height":{"type":"integer","exclusiveMinimum":true,"minimum":0,"maximum":5000}},"required":["length","width","height"],"additionalProperties":false},"max_axle_loads_kg":{"type":"object","properties":{"front":{"type":"number","exclusiveMinimum":true,"minimum":0},"rear":{"type":"number","exclusiveMinimum":true,"minimum":0},"rear_double":{"type":"number","exclusiveMinimum":true,"minimum":0}},"required":["front"],"additionalProperties":false},"axle_geometry_mm":{"type":"object","properties":{"front_axle_x":{"type":"number"},"rear_axle_x":{"type":"number"},"cargo_offset_x":{"type":"number","default":0},"empty_front_kg":{"type":"number","minimum":0,"default":0},"empty_rear_kg":{"type":"number","minimum":0,"default":0}},"required":["front_axle_x","rear_axle_x"],"additionalProperties":false}},"required":["vehicle_id","max_weight_kg","cargo_space_dimensions_mm"],"additionalProperties":false},"minItems":1,"maxItems":20},"delivery_points":{"type":"array","items":{"type":"object","properties":{"point_id":{"type":"string","minLength":1,"maxLength":100},"name":{"type":"string","maxLength":200},"address":{"type":"string","maxLength":300},"location":{"type":"object","properties":{"lat":{"type":"number","minimum":-90,"maximum":90},"lng":{"type":"number","minimum":-180,"maximum":180}},"required":["lat","lng"],"additionalProperties":false},"time_window":{"type":"object","properties":{"start":{"type":"string","format":"date-time"},"end":{"type":"string","format":"date-time"}},"required":["start","end"],"additionalProperties":false},"service_time_minutes":{"type":"number","minimum":0,"maximum":600,"default":15}},"required":["point_id","name","location"],"additionalProperties":false},"minItems":1,"maxItems":100},"cargo_items":{"type":"array","items":{"type":"object","properties":{"item_id":{"type":"string","minLength":1,"maxLength":100},"description":{"type":"string","maxLength":200,"default":""},"delivery_point_id":{"type":"string","minLength":1,"maxLength":100},"client_id":{"type":"string","maxLength":100},"weight_kg":{"type":"number","exclusiveMinimum":true,"minimum":0,"maximum":30000},"dimensions_mm":{"type":"object","properties":{"length":{"type":"integer","exclusiveMinimum":true,"minimum":0,"maximum":20000},"width":{"type":"integer","exclusiveMinimum":true,"minimum":0,"maximum":5000},"height":{"type":"integer","exclusiveMinimum":true,"minimum":0,"maximum":5000}},"required":["length","width","height"],"additionalProperties":false},"constraints":{"type":"object","properties":{"stackable":{"type":"boolean","default":true},"max_stacking_weight_kg":{"type":"number","minimum":0,"default":0},"allowed_orientations":{"type":"array","items":{"type":"string","enum":["any","lengthwise","widthwise","floor_only","this_side_up"]},"minItems":1,"default":["any"]}},"additionalProperties":false,"default":{}},"fragile":{"type":"boolean"},"adr_class":{"type":"string","maxLength":20},"temperature":{"type":"string","enum":["ambient","chilled","frozen"]}},"required":["item_id","delivery_point_id","weight_kg","dimensions_mm"],"additionalProperties":false},"minItems":1,"maxItems":1000}},"required":["depots","vehicles","delivery_points","cargo_items"],"additionalProperties":false}}},"security":[{"bearer":[]}],"paths":{"/api/public/v1/health":{"get":{"summary":"Stan usługi","security":[],"responses":{"200":{"description":"OK"}}}},"/api/public/v1/submit":{"post":{"summary":"Optymalizacja asynchroniczna (202 + job_id)","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OptimizeRequest"}}}},"responses":{"202":{"description":"Przyjęte","content":{"application/json":{"schema":{"type":"object","properties":{"job_id":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["queued"]},"status_url":{"type":"string"}}}}}},"401":{"description":"Nieprawidłowy klucz","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"402":{"description":"Brak kredytów","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"413":{"description":"Za duże żądanie","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"422":{"description":"Błąd walidacji","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"429":{"description":"Limit wywołań","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/public/v1/optimize":{"post":{"summary":"Optymalizacja synchroniczna (czeka na wynik)","description":"Zwraca pełny wynik w odpowiedzi HTTP (200). Dla małych zadań: time_limit_s ≤ 60, bez callback_url. Zużywa kredyt jak /submit; wynik jest też dostępny pod status_url.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OptimizeRequest"}}}},"responses":{"200":{"description":"Pełny wynik (success/partial/infeasible) z job_id i status_url"},"401":{"description":"Nieprawidłowy klucz","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"422":{"description":"Błąd walidacji, SYNC_TIME_LIMIT_EXCEEDED lub CALLBACK_NOT_SUPPORTED_IN_SYNC","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"429":{"description":"Limit wywołań lub kredytów","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"504":{"description":"Przekroczono czas oczekiwania – sprawdź status_url","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/public/v1/jobs/{jobId}":{"get":{"summary":"Status i wynik zlecenia","parameters":[{"name":"jobId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Status (queued/running) lub pełny wynik (success/partial/infeasible/failed) z widget_url"},"401":{"description":"Nieprawidłowy klucz","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"404":{"description":"Nie znaleziono","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}}}}