{"openapi":"3.1.0","info":{"title":"Simeons Movers Manifest API","summary":"Booking capacity and driver manifest planning","description":"\nThe Simeons Movers platform sends a current operating snapshot containing locations, Nuggets,\nbooked movement legs, drivers, and lorries. The API uses HGV journey data to produce a\ntime-sequenced manifest for each driver or to check whether proposed booking movements fit the\navailable capacity.\n\nBoth operations are stateless. They do not create bookings, change manifests, or store the\nsubmitted operating snapshot. All planning requests require a bearer credential.\n\nA customer booking may contain several movement legs. The source platform remains responsible\nfor translating the customer-visible booking type into the movement legs that need scheduling.\n","version":"1.0.0"},"servers":[{"url":"/","description":"Current deployment"}],"paths":{"/v1/manifests":{"post":{"tags":["Manifest planning"],"summary":"Generate driver manifests","description":"Send the current warehouses, customer properties, handover points, Nuggets, booked movement legs, drivers, and lorries. The response contains a time-sequenced manifest for each assigned driver and identifies movement legs that could not be scheduled. The request does not change platform data.","operationId":"generate_driver_manifests","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManifestPlanRequest"},"examples":{"two_customer_movements":{"summary":"Two customer movement legs","description":"Two empty-Nugget deliveries, two available Nuggets, one driver, and one lorry for a Tewkesbury operating day.","value":{"data_as_of":"2026-08-18T23:57:00Z","planning_period":{"start":"2026-08-19T06:00:00+01:00","end":"2026-08-19T18:00:00+01:00"},"locations":[{"id":"tewkesbury-warehouse","name":"Tewkesbury warehouse","type":"warehouse","latitude":51.9906,"longitude":-2.1573},{"id":"cheltenham-customer","name":"Cheltenham customer","type":"customer_property","latitude":51.8994,"longitude":-2.0783},{"id":"gloucester-customer","name":"Gloucester customer","type":"customer_property","latitude":51.8642,"longitude":-2.2382},{"id":"stroud-off-hire","name":"Stroud off-hire Nugget","type":"customer_property","latitude":51.7457,"longitude":-2.2178}],"nuggets":[{"id":"NUGGET-1","availability":"in_service","location_id":"tewkesbury-warehouse"},{"id":"NUGGET-2","availability":"in_service","location_id":"stroud-off-hire"}],"movements":[{"id":"MOVEMENT-1001","booking_id":"BOOKING-1001","destination_id":"cheltenham-customer","window":{"start":"2026-08-19T07:00:00+01:00","end":"2026-08-19T12:00:00+01:00"},"type":"deliver_empty"},{"id":"MOVEMENT-1002","booking_id":"BOOKING-1002","destination_id":"gloucester-customer","window":{"start":"2026-08-19T08:00:00+01:00","end":"2026-08-19T14:00:00+01:00"},"type":"deliver_empty"}],"drivers":[{"id":"DRIVER-1","home_warehouse_id":"tewkesbury-warehouse","availability":[{"start":"2026-08-19T06:00:00+01:00","end":"2026-08-19T18:00:00+01:00"}]}],"lorries":[{"id":"LORRY-1","start_location_id":"tewkesbury-warehouse","availability":[{"start":"2026-08-19T06:00:00+01:00","end":"2026-08-19T18:00:00+01:00"}]}]}}}}},"required":true},"responses":{"200":{"description":"Validated driver manifests and any unplanned movement legs.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManifestPlanResponse"},"example":{"data_as_of":"2026-08-18T23:57:00Z","manifests":[{"driver_id":"DRIVER-1","activities":[{"type":"pickup","start":"2026-08-19T06:00:00+01:00","end":"2026-08-19T06:05:00+01:00","movement_id":"MOVEMENT-1001","booking_id":"BOOKING-1001","nugget_ids":["NUGGET-1"],"lorry_id":"LORRY-1","location_id":"tewkesbury-warehouse"},{"type":"drive","start":"2026-08-19T06:05:00+01:00","end":"2026-08-19T06:33:00+01:00","movement_id":"MOVEMENT-1001","booking_id":"BOOKING-1001","nugget_ids":["NUGGET-1"],"lorry_id":"LORRY-1","from_location_id":"tewkesbury-warehouse","to_location_id":"cheltenham-customer"},{"type":"wait","start":"2026-08-19T06:33:00+01:00","end":"2026-08-19T07:00:00+01:00","lorry_id":"LORRY-1","location_id":"cheltenham-customer"},{"type":"delivery","start":"2026-08-19T07:00:00+01:00","end":"2026-08-19T07:05:00+01:00","movement_id":"MOVEMENT-1001","booking_id":"BOOKING-1001","nugget_ids":["NUGGET-1"],"lorry_id":"LORRY-1","location_id":"cheltenham-customer"},{"type":"drive","start":"2026-08-19T07:05:00+01:00","end":"2026-08-19T07:45:00+01:00","lorry_id":"LORRY-1","from_location_id":"cheltenham-customer","to_location_id":"stroud-off-hire"},{"type":"pickup","start":"2026-08-19T07:45:00+01:00","end":"2026-08-19T07:50:00+01:00","movement_id":"MOVEMENT-1002","booking_id":"BOOKING-1002","nugget_ids":["NUGGET-2"],"lorry_id":"LORRY-1","location_id":"stroud-off-hire"},{"type":"drive","start":"2026-08-19T07:50:00+01:00","end":"2026-08-19T08:26:00+01:00","movement_id":"MOVEMENT-1002","booking_id":"BOOKING-1002","nugget_ids":["NUGGET-2"],"lorry_id":"LORRY-1","from_location_id":"stroud-off-hire","to_location_id":"gloucester-customer"},{"type":"delivery","start":"2026-08-19T08:26:00+01:00","end":"2026-08-19T08:31:00+01:00","movement_id":"MOVEMENT-1002","booking_id":"BOOKING-1002","nugget_ids":["NUGGET-2"],"lorry_id":"LORRY-1","location_id":"gloucester-customer"},{"type":"drive","start":"2026-08-19T08:31:00+01:00","end":"2026-08-19T08:59:00+01:00","lorry_id":"LORRY-1","from_location_id":"gloucester-customer","to_location_id":"tewkesbury-warehouse"}]}],"unplanned_movements":[],"warnings":[{"code":"driver_allowances_missing","message":"Current Fleet Check allowances were not supplied for the affected drivers.","affected_ids":["DRIVER-1"]}],"metadata":{"generated_at":"2026-08-18T23:57:00Z","policy_version":"simeons-manifest-v1"}}}}},"400":{"description":"Malformed HTTP request metadata.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Bearer credential missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Credential does not allow this operation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"Request body exceeds the service limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Request fields or references are invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Trial rate or usage allowance exceeded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected planning-service failure.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"502":{"description":"Invalid response or authentication failure upstream.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Planning dependency or capacity temporarily unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"504":{"description":"End-to-end planning deadline expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"BearerAuth":[]}]}},"/v1/booking-checks":{"post":{"tags":["Manifest planning"],"summary":"Check booking availability","description":"Send the current operating snapshot and the movement legs for a proposed booking. The service checks whether they fit the available driver, lorry, Nugget, time-window, and HGV journey capacity without changing platform data. A result may be feasible, proven infeasible, or unknown within the bounded check.","operationId":"check_booking_availability","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingCheckRequest"},"examples":{"proposed_booking_movement":{"summary":"Proposed booking movement","description":"One accepted movement remains in `movements`; the proposed Gloucester delivery is present only in `new_movements`.","value":{"data_as_of":"2026-08-18T23:57:00Z","planning_period":{"start":"2026-08-19T06:00:00+01:00","end":"2026-08-19T18:00:00+01:00"},"locations":[{"id":"tewkesbury-warehouse","name":"Tewkesbury warehouse","type":"warehouse","latitude":51.9906,"longitude":-2.1573},{"id":"cheltenham-customer","name":"Cheltenham customer","type":"customer_property","latitude":51.8994,"longitude":-2.0783},{"id":"gloucester-customer","name":"Gloucester customer","type":"customer_property","latitude":51.8642,"longitude":-2.2382},{"id":"stroud-off-hire","name":"Stroud off-hire Nugget","type":"customer_property","latitude":51.7457,"longitude":-2.2178}],"nuggets":[{"id":"NUGGET-1","availability":"in_service","location_id":"tewkesbury-warehouse"},{"id":"NUGGET-2","availability":"in_service","location_id":"stroud-off-hire"}],"movements":[{"id":"MOVEMENT-1001","booking_id":"BOOKING-1001","destination_id":"cheltenham-customer","window":{"start":"2026-08-19T07:00:00+01:00","end":"2026-08-19T12:00:00+01:00"},"type":"deliver_empty"}],"drivers":[{"id":"DRIVER-1","home_warehouse_id":"tewkesbury-warehouse","availability":[{"start":"2026-08-19T06:00:00+01:00","end":"2026-08-19T18:00:00+01:00"}]}],"lorries":[{"id":"LORRY-1","start_location_id":"tewkesbury-warehouse","availability":[{"start":"2026-08-19T06:00:00+01:00","end":"2026-08-19T18:00:00+01:00"}]}],"new_movements":[{"id":"MOVEMENT-CANDIDATE-1","booking_id":"BOOKING-CANDIDATE-1","destination_id":"gloucester-customer","window":{"start":"2026-08-19T08:00:00+01:00","end":"2026-08-19T14:00:00+01:00"},"type":"deliver_empty"}]}}}}},"required":true},"responses":{"200":{"description":"Bounded booking-capacity result.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingCheckResponse"},"example":{"data_as_of":"2026-08-18T23:57:00Z","status":"feasible","alternatives":[],"requires_full_replan":false,"warnings":[{"code":"driver_allowances_missing","message":"Current Fleet Check allowances were not supplied for the affected drivers.","affected_ids":["DRIVER-1"]}],"metadata":{"generated_at":"2026-08-18T23:57:00Z","policy_version":"simeons-manifest-v1"}}}}},"400":{"description":"Malformed HTTP request metadata.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Bearer credential missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Credential does not allow this operation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"Request body exceeds the service limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Request fields or references are invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Trial rate or usage allowance exceeded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected planning-service failure.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"502":{"description":"Invalid response or authentication failure upstream.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Planning dependency or capacity temporarily unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"504":{"description":"End-to-end planning deadline expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"BearerAuth":[]}]}}},"components":{"schemas":{"ActivityType":{"type":"string","enum":["drive","pickup","delivery","break","wait","yard_work","service","hold"],"title":"ActivityType"},"AllowanceRefresh":{"properties":{"effective_at":{"type":"string","format":"date-time","title":"Effective At","description":"Time after a future rest period when these counters become authoritative."},"driving_today_minutes":{"type":"integer","minimum":0.0,"title":"Driving Today Minutes","description":"Driving counter after the rest period.","default":0},"driving_this_week_minutes":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Driving This Week Minutes","description":"Weekly driving counter after the rest period, when it changes."},"driving_previous_week_minutes":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Driving Previous Week Minutes","description":"Previous-week driving counter after the rest period, when it changes."},"driving_since_break_minutes":{"type":"integer","minimum":0.0,"title":"Driving Since Break Minutes","description":"Continuous-driving counter after the rest period.","default":0},"working_since_break_minutes":{"type":"integer","minimum":0.0,"title":"Working Since Break Minutes","description":"Continuous-working counter after the rest period.","default":0},"last_break_ended_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Break Ended At","description":"End of the qualifying rest period, when available."}},"additionalProperties":false,"type":"object","required":["effective_at"],"title":"AllowanceRefresh"},"AlternativeWindow":{"properties":{"movement_id":{"type":"string","title":"Movement Id","description":"Proposed movement leg to which this alternative window applies."},"window":{"$ref":"#/components/schemas/Window","description":"Alternative window for the movement leg."}},"additionalProperties":false,"type":"object","required":["movement_id","window"],"title":"AlternativeWindow"},"BookingCheckAlternative":{"properties":{"proposed_window":{"$ref":"#/components/schemas/Window","description":"Combined alternative window for the proposed booking."},"movement_windows":{"items":{"$ref":"#/components/schemas/AlternativeWindow"},"type":"array","title":"Movement Windows","description":"Per-movement alternative windows when the booking contains several legs.","default":[]},"requires_full_replan":{"type":"boolean","title":"Requires Full Replan","description":"Whether accepting this alternative requires a complete manifest solve.","default":false}},"additionalProperties":false,"type":"object","required":["proposed_window"],"title":"BookingCheckAlternative"},"BookingCheckRequest":{"properties":{"data_as_of":{"type":"string","format":"date-time","title":"Data As Of","description":"When the platform read this operating snapshot."},"planning_period":{"$ref":"#/components/schemas/Window","description":"Inclusive period for which manifests may be scheduled."},"timezone":{"type":"string","minLength":1,"title":"Timezone","description":"IANA timezone used for operating days and driver-hours boundaries.","default":"Europe/London"},"locations":{"items":{"$ref":"#/components/schemas/Place"},"type":"array","maxItems":500,"minItems":1,"title":"Locations","description":"Every place referenced by Nuggets, movements, drivers, or lorries."},"nuggets":{"items":{"$ref":"#/components/schemas/Nugget"},"type":"array","maxItems":20000,"title":"Nuggets","description":"Current Nugget inventory state."},"movements":{"items":{"oneOf":[{"$ref":"#/components/schemas/DeliverEmpty"},{"$ref":"#/components/schemas/CollectEmpty"},{"$ref":"#/components/schemas/MoveNugget"}],"discriminator":{"propertyName":"type","mapping":{"collect_empty":"#/components/schemas/CollectEmpty","deliver_empty":"#/components/schemas/DeliverEmpty","move_nugget":"#/components/schemas/MoveNugget"}}},"type":"array","maxItems":20000,"title":"Movements","description":"Accepted movement legs that must be included in the operating plan."},"drivers":{"items":{"$ref":"#/components/schemas/Driver"},"type":"array","maxItems":200,"minItems":1,"title":"Drivers","description":"Drivers available during the planning period."},"lorries":{"items":{"$ref":"#/components/schemas/Lorry"},"type":"array","maxItems":200,"minItems":1,"title":"Lorries","description":"Lorries available during the planning period."},"new_movements":{"items":{"oneOf":[{"$ref":"#/components/schemas/DeliverEmpty"},{"$ref":"#/components/schemas/CollectEmpty"},{"$ref":"#/components/schemas/MoveNugget"}],"discriminator":{"propertyName":"type","mapping":{"collect_empty":"#/components/schemas/CollectEmpty","deliver_empty":"#/components/schemas/DeliverEmpty","move_nugget":"#/components/schemas/MoveNugget"}}},"type":"array","maxItems":100,"minItems":1,"title":"New Movements","description":"Proposed movement legs to test without adding them to the accepted plan."}},"additionalProperties":false,"type":"object","required":["data_as_of","planning_period","locations","nuggets","movements","drivers","lorries","new_movements"],"title":"BookingCheckRequest"},"BookingCheckResponse":{"properties":{"data_as_of":{"type":"string","format":"date-time","title":"Data As Of","description":"Snapshot observation time supplied in the request."},"status":{"type":"string","enum":["feasible","infeasible_proven","unknown"],"title":"Status","description":"Three-valued result of the bounded booking check."},"reason_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason Code","description":"Stable machine-readable explanation when status is not feasible."},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason","description":"Human-readable explanation; do not branch on this value."},"alternatives":{"items":{"$ref":"#/components/schemas/BookingCheckAlternative"},"type":"array","title":"Alternatives","description":"Feasible alternative windows found by the bounded check.","default":[]},"requires_full_replan":{"type":"boolean","title":"Requires Full Replan","description":"Whether accepting the proposed movements requires a complete manifest solve.","default":false},"warnings":{"items":{"$ref":"#/components/schemas/PlanningWarning"},"type":"array","title":"Warnings","description":"Assumptions that affected the result.","default":[]},"metadata":{"$ref":"#/components/schemas/ResponseMetadata","description":"Small stable metadata about this response."}},"additionalProperties":false,"type":"object","required":["data_as_of","status","metadata"],"title":"BookingCheckResponse"},"CollectEmpty":{"properties":{"type":{"type":"string","const":"collect_empty","title":"Type","description":"Collect a named off-hire Nugget.","default":"collect_empty"},"id":{"type":"string","minLength":1,"title":"Id","description":"Stable movement-leg identifier."},"booking_id":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}],"title":"Booking Id","description":"Parent customer booking, when known."},"nugget_id":{"type":"string","minLength":1,"title":"Nugget Id","description":"Nugget to collect."},"location_id":{"type":"string","minLength":1,"title":"Location Id","description":"Place from which the Nugget must be collected."},"window":{"$ref":"#/components/schemas/Window","description":"Allowed pickup window at the collection place."},"must_clear_by":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Must Clear By","description":"Hard latest time by which the empty Nugget must leave the property."},"handling_method":{"$ref":"#/components/schemas/HandlingMethod","description":"Equipment and driver certification required to handle this movement.","default":"crane"},"handling_minutes_per_nugget":{"type":"integer","maximum":240.0,"minimum":1.0,"title":"Handling Minutes Per Nugget","description":"Expected time to load the Nugget at the collection location.","default":5}},"additionalProperties":false,"type":"object","required":["id","nugget_id","location_id","window"],"title":"CollectEmpty"},"DeliverEmpty":{"properties":{"type":{"type":"string","const":"deliver_empty","title":"Type","description":"Deliver an available off-hire Nugget.","default":"deliver_empty"},"id":{"type":"string","minLength":1,"title":"Id","description":"Stable movement-leg identifier."},"booking_id":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}],"title":"Booking Id","description":"Parent customer booking, when known."},"destination_id":{"type":"string","minLength":1,"title":"Destination Id","description":"Customer property or handover point receiving the Nugget."},"window":{"$ref":"#/components/schemas/Window","description":"Allowed arrival window at the destination."},"quantity":{"type":"integer","maximum":100.0,"minimum":1.0,"title":"Quantity","description":"Number of empty Nuggets to deliver.","default":1},"empty_source":{"$ref":"#/components/schemas/EmptySource","description":"Whether the planner may redirect an off-hire Nugget or must collect one from a warehouse.","default":"any_available"},"split_across_lorries":{"type":"boolean","title":"Split Across Lorries","description":"Whether different Nuggets in this movement may use different lorries.","default":true},"handling_method":{"$ref":"#/components/schemas/HandlingMethod","description":"Equipment and driver certification required to handle this movement.","default":"crane"},"handling_minutes_per_nugget":{"type":"integer","maximum":240.0,"minimum":1.0,"title":"Handling Minutes Per Nugget","description":"Expected handling time at each pickup and delivery stop for one Nugget.","default":5}},"additionalProperties":false,"type":"object","required":["id","destination_id","window"],"title":"DeliverEmpty"},"Driver":{"properties":{"id":{"type":"string","minLength":1,"title":"Id","description":"Stable platform driver identifier."},"home_warehouse_id":{"type":"string","minLength":1,"title":"Home Warehouse Id","description":"Driver's normal warehouse base."},"start_location_id":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}],"title":"Start Location Id","description":"Defaults to home_warehouse_id."},"availability":{"items":{"$ref":"#/components/schemas/Window"},"type":"array","maxItems":64,"minItems":1,"title":"Availability","description":"Periods during which the driver may be assigned work."},"qualifications":{"items":{"$ref":"#/components/schemas/DriverQualification"},"type":"array","uniqueItems":true,"title":"Qualifications","description":"Licences and equipment certifications held by the driver.","default":["crane","hgv_c"]},"fleet_check_allowances":{"anyOf":[{"$ref":"#/components/schemas/DriverAllowances"},{"type":"null"}],"description":"Current driver-hours counters from Fleet Check; omission is returned as a warning."},"future_allowance_refreshes":{"items":{"$ref":"#/components/schemas/AllowanceRefresh"},"type":"array","maxItems":32,"title":"Future Allowance Refreshes","description":"Authoritative counters after known future rest periods in a multi-day plan.","default":[]}},"additionalProperties":false,"type":"object","required":["id","home_warehouse_id","availability"],"title":"Driver"},"DriverAllowances":{"properties":{"observed_at":{"type":"string","format":"date-time","title":"Observed At","description":"When Fleet Check reported these counters."},"driving_today_minutes":{"type":"integer","minimum":0.0,"title":"Driving Today Minutes","description":"Driving already completed today.","default":0},"driving_this_week_minutes":{"type":"integer","minimum":0.0,"title":"Driving This Week Minutes","description":"Driving already completed this week.","default":0},"driving_previous_week_minutes":{"type":"integer","minimum":0.0,"title":"Driving Previous Week Minutes","description":"Driving completed in the previous week for the rolling two-week limit.","default":0},"driving_since_break_minutes":{"type":"integer","minimum":0.0,"title":"Driving Since Break Minutes","description":"Driving completed since the last qualifying break.","default":0},"working_since_break_minutes":{"type":"integer","minimum":0.0,"title":"Working Since Break Minutes","description":"Working time completed since the last qualifying break.","default":0},"last_break_ended_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Break Ended At","description":"When the last qualifying break ended, when supplied by Fleet Check."}},"additionalProperties":false,"type":"object","required":["observed_at"],"title":"DriverAllowances"},"DriverManifest":{"properties":{"driver_id":{"type":"string","title":"Driver Id","description":"Driver assigned this ordered manifest."},"activities":{"items":{"$ref":"#/components/schemas/PlannedActivity"},"type":"array","title":"Activities","description":"Time-ordered activities for the driver."}},"additionalProperties":false,"type":"object","required":["driver_id","activities"],"title":"DriverManifest"},"DriverQualification":{"type":"string","enum":["hgv_c","hgv_ce","crane","forklift"],"title":"DriverQualification"},"EmptySource":{"type":"string","enum":["any_available","warehouse_only"],"title":"EmptySource"},"ErrorBody":{"properties":{"code":{"type":"string","title":"Code","description":"Stable machine-readable error category."},"message":{"type":"string","title":"Message","description":"Human-readable explanation; do not branch on this value."},"request_id":{"type":"string","title":"Request Id","description":"Support identifier also returned in the X-Request-ID header."},"details":{"items":{"$ref":"#/components/schemas/ErrorDetail"},"type":"array","title":"Details","description":"Field-level validation failures, when applicable.","default":[]}},"additionalProperties":false,"type":"object","required":["code","message","request_id"],"title":"ErrorBody"},"ErrorDetail":{"properties":{"path":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Path","description":"Path to the invalid request field."},"code":{"type":"string","title":"Code","description":"Machine-readable validation rule."},"message":{"type":"string","title":"Message","description":"Human-readable explanation; do not branch on this value."}},"additionalProperties":false,"type":"object","required":["path","code","message"],"title":"ErrorDetail"},"ErrorResponse":{"properties":{"error":{"$ref":"#/components/schemas/ErrorBody","description":"Structured information about the failed request."}},"additionalProperties":false,"type":"object","required":["error"],"title":"ErrorResponse"},"HandlingMethod":{"type":"string","enum":["crane","forklift"],"title":"HandlingMethod"},"Lorry":{"properties":{"id":{"type":"string","minLength":1,"title":"Id","description":"Stable platform lorry identifier."},"start_location_id":{"type":"string","minLength":1,"title":"Start Location Id","description":"Place where the lorry begins this planning period."},"availability":{"items":{"$ref":"#/components/schemas/Window"},"type":"array","maxItems":64,"minItems":1,"title":"Availability","description":"Periods during which the lorry may be assigned work."},"nugget_capacity":{"type":"integer","minimum":1.0,"title":"Nugget Capacity","description":"Maximum number of Nuggets carried at once.","default":4},"equipment":{"items":{"$ref":"#/components/schemas/LorryEquipment"},"type":"array","uniqueItems":true,"title":"Equipment","description":"Handling equipment physically available on the lorry.","default":["crane"]}},"additionalProperties":false,"type":"object","required":["id","start_location_id","availability"],"title":"Lorry"},"LorryEquipment":{"type":"string","enum":["crane","forklift"],"title":"LorryEquipment"},"ManifestPlanRequest":{"properties":{"data_as_of":{"type":"string","format":"date-time","title":"Data As Of","description":"When the platform read this operating snapshot."},"planning_period":{"$ref":"#/components/schemas/Window","description":"Inclusive period for which manifests may be scheduled."},"timezone":{"type":"string","minLength":1,"title":"Timezone","description":"IANA timezone used for operating days and driver-hours boundaries.","default":"Europe/London"},"locations":{"items":{"$ref":"#/components/schemas/Place"},"type":"array","maxItems":500,"minItems":1,"title":"Locations","description":"Every place referenced by Nuggets, movements, drivers, or lorries."},"nuggets":{"items":{"$ref":"#/components/schemas/Nugget"},"type":"array","maxItems":20000,"title":"Nuggets","description":"Current Nugget inventory state."},"movements":{"items":{"oneOf":[{"$ref":"#/components/schemas/DeliverEmpty"},{"$ref":"#/components/schemas/CollectEmpty"},{"$ref":"#/components/schemas/MoveNugget"}],"discriminator":{"propertyName":"type","mapping":{"collect_empty":"#/components/schemas/CollectEmpty","deliver_empty":"#/components/schemas/DeliverEmpty","move_nugget":"#/components/schemas/MoveNugget"}}},"type":"array","maxItems":20000,"title":"Movements","description":"Accepted movement legs that must be included in the operating plan."},"drivers":{"items":{"$ref":"#/components/schemas/Driver"},"type":"array","maxItems":200,"minItems":1,"title":"Drivers","description":"Drivers available during the planning period."},"lorries":{"items":{"$ref":"#/components/schemas/Lorry"},"type":"array","maxItems":200,"minItems":1,"title":"Lorries","description":"Lorries available during the planning period."}},"additionalProperties":false,"type":"object","required":["data_as_of","planning_period","locations","nuggets","movements","drivers","lorries"],"title":"ManifestPlanRequest"},"ManifestPlanResponse":{"properties":{"data_as_of":{"type":"string","format":"date-time","title":"Data As Of","description":"Snapshot observation time supplied in the request."},"manifests":{"items":{"$ref":"#/components/schemas/DriverManifest"},"type":"array","title":"Manifests","description":"Generated driver manifests."},"unplanned_movements":{"items":{"$ref":"#/components/schemas/UnplannedMovement"},"type":"array","title":"Unplanned Movements","description":"Accepted movement legs the planner could not schedule."},"warnings":{"items":{"$ref":"#/components/schemas/PlanningWarning"},"type":"array","title":"Warnings","description":"Assumptions that affected the result.","default":[]},"metadata":{"$ref":"#/components/schemas/ResponseMetadata","description":"Small stable metadata about this response."}},"additionalProperties":false,"type":"object","required":["data_as_of","manifests","unplanned_movements","metadata"],"title":"ManifestPlanResponse"},"MoveNugget":{"properties":{"type":{"type":"string","const":"move_nugget","title":"Type","description":"Move one or more named Nuggets.","default":"move_nugget"},"id":{"type":"string","minLength":1,"title":"Id","description":"Stable movement-leg identifier."},"booking_id":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}],"title":"Booking Id","description":"Parent customer booking, when known."},"nugget_ids":{"items":{"type":"string"},"type":"array","maxItems":100,"minItems":1,"title":"Nugget Ids","description":"Nuggets moved by this leg."},"origin_id":{"type":"string","minLength":1,"title":"Origin Id","description":"Place from which the Nuggets are collected."},"destination_id":{"type":"string","minLength":1,"title":"Destination Id","description":"Place receiving the Nuggets."},"pickup_window":{"$ref":"#/components/schemas/Window","description":"Allowed pickup window at the origin."},"arrival_window":{"anyOf":[{"$ref":"#/components/schemas/Window"},{"type":"null"}],"description":"Optional hard arrival window at the destination."},"split_across_lorries":{"type":"boolean","title":"Split Across Lorries","description":"Whether different Nuggets in this movement may use different lorries.","default":true},"handling_method":{"$ref":"#/components/schemas/HandlingMethod","description":"Equipment and driver certification required at the movement stops.","default":"crane"},"origin_handling_minutes_per_nugget":{"type":"integer","maximum":240.0,"minimum":1.0,"title":"Origin Handling Minutes Per Nugget","description":"Expected loading time at the origin for one Nugget.","default":5},"destination_handling_minutes_per_nugget":{"type":"integer","maximum":240.0,"minimum":1.0,"title":"Destination Handling Minutes Per Nugget","description":"Expected unloading time at the destination for one Nugget.","default":5}},"additionalProperties":false,"type":"object","required":["id","nugget_ids","origin_id","destination_id","pickup_window"],"title":"MoveNugget"},"Nugget":{"properties":{"id":{"type":"string","minLength":1,"title":"Id","description":"Stable platform Nugget identifier."},"availability":{"$ref":"#/components/schemas/NuggetAvailability","description":"Current operational availability of the Nugget."},"location_id":{"type":"string","minLength":1,"title":"Location Id","description":"Place where the Nugget is currently located."},"on_hire_to_customer_id":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}],"title":"On Hire To Customer Id","description":"Customer currently hiring the Nugget; absent means the Nugget is off-hire."},"reserved_for_movement_id":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}],"title":"Reserved For Movement Id","description":"Accepted movement leg that has exclusive use of this off-hire Nugget."}},"additionalProperties":false,"type":"object","required":["id","availability","location_id"],"title":"Nugget"},"NuggetAvailability":{"type":"string","enum":["in_service","in_maintenance","quarantined","destroyed"],"title":"NuggetAvailability"},"Place":{"properties":{"id":{"type":"string","minLength":1,"title":"Id","description":"Stable platform location identifier."},"name":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}],"title":"Name","description":"Human-readable name; not used by the solver."},"type":{"$ref":"#/components/schemas/PlaceType","description":"Operational role of this place."},"latitude":{"type":"number","maximum":90.0,"minimum":-90.0,"title":"Latitude","description":"WGS84 latitude of the lorry stop."},"longitude":{"type":"number","maximum":180.0,"minimum":-180.0,"title":"Longitude","description":"WGS84 longitude of the lorry stop."},"nugget_capacity":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Nugget Capacity","description":"Maximum Nuggets that may remain at this place, when constrained."}},"additionalProperties":false,"type":"object","required":["id","type","latitude","longitude"],"title":"Place"},"PlaceType":{"type":"string","enum":["warehouse","customer_property","handover_point"],"title":"PlaceType"},"PlannedActivity":{"properties":{"type":{"$ref":"#/components/schemas/ActivityType","description":"Operational activity performed during this block."},"start":{"type":"string","format":"date-time","title":"Start","description":"Scheduled activity start."},"end":{"type":"string","format":"date-time","title":"End","description":"Scheduled activity end."},"movement_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Movement Id","description":"Movement leg served by this activity."},"booking_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Booking Id","description":"Parent booking of the movement leg."},"nugget_ids":{"items":{"type":"string"},"type":"array","title":"Nugget Ids","description":"Nuggets carried or handled during this activity.","default":[]},"lorry_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lorry Id","description":"Lorry assigned to this activity."},"location_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Location Id","description":"Place where a non-driving activity occurs."},"from_location_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"From Location Id","description":"Origin of a driving activity."},"to_location_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"To Location Id","description":"Destination of a driving activity."}},"additionalProperties":false,"type":"object","required":["type","start","end"],"title":"PlannedActivity"},"PlanningWarning":{"properties":{"code":{"$ref":"#/components/schemas/WarningCode","description":"Stable machine-readable warning category."},"message":{"type":"string","title":"Message","description":"Human-readable explanation; do not branch on this value."},"affected_ids":{"items":{"type":"string"},"type":"array","title":"Affected Ids","description":"Driver, lorry, or other identifiers affected by the warning.","default":[]}},"additionalProperties":false,"type":"object","required":["code","message"],"title":"PlanningWarning"},"ResponseMetadata":{"properties":{"generated_at":{"type":"string","format":"date-time","title":"Generated At","description":"When this response was produced."},"policy_version":{"type":"string","const":"simeons-manifest-v1","title":"Policy Version","description":"Stable planning-policy version applied to the request.","default":"simeons-manifest-v1"}},"additionalProperties":false,"type":"object","required":["generated_at"],"title":"ResponseMetadata"},"UnplannedMovement":{"properties":{"movement_id":{"type":"string","title":"Movement Id","description":"Movement leg that was not scheduled."},"booking_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Booking Id","description":"Parent customer booking, when known."},"reason_code":{"type":"string","title":"Reason Code","description":"Stable machine-readable reason category."},"message":{"type":"string","title":"Message","description":"Human-readable explanation; do not branch on this value."}},"additionalProperties":false,"type":"object","required":["movement_id","reason_code","message"],"title":"UnplannedMovement"},"WarningCode":{"type":"string","enum":["routing_profile_provisional","routing_profile_incomplete","driver_allowances_missing","operational_data_provisional","planning_assumption"],"title":"WarningCode"},"Window":{"properties":{"start":{"type":"string","format":"date-time","title":"Start","description":"Inclusive start of the operating or customer window."},"end":{"type":"string","format":"date-time","title":"End","description":"Inclusive end of the operating or customer window."}},"additionalProperties":false,"type":"object","required":["start","end"],"title":"Window"}},"securitySchemes":{"BearerAuth":{"type":"http","description":"Bearer credential issued by Haladir.","scheme":"bearer"}}},"tags":[{"name":"Manifest planning","description":"Generate driver manifests and check booking capacity from a current operating snapshot."}]}