Shipments

Will create a new shipment in the Maven Dispatch system or update an existing one.

If a request comes in where shipmentType is "delivery" and there already exists a shipment in Maven with the proNumber provided on the request, it will update that shipment.
If a request comes in where shipmentType is "pickup" and there already exists a shipment in Maven with the refNumber provided on the request, it will update that shipment.
If no shipment exists in Maven with these rules it will create a new shipment as well as its own stop. If an existing stop with the same windowStart, windowEnd, date, location, and terminal exist, this shipment may be grouped onto that existing stop. Other grouping configuration options are available.

Every request should be sent in with all known and relevant shipment information.

Required fields

Always:

  • associatedShipment
  • associatedShipment.shipmentType

When associatedShipment.shipmentType is "pickup" or "checkstop"

  • associatedShipment.requestedDate or associatedShipment.pickupDate
  • terminalCode or associatedShipment.originTerminalCode
  • associatedShipment.refNumber
  • associatedShipment.shipperCustomerNumber or associatedShipment.customerNumber or associatedShipment.shipperCustomerName+Address fields or associatedShipment.customerName+Address fields

When associatedShipment.shipmentType is "delivery"

  • associatedShipment.requestedDate or associatedShipment.deliveryDate
  • terminalCode or associatedShipment.destinationTerminalCode
  • associatedShipment.proNumber

Previously Required Fields
associatedShipment.consigneeCustomerNumber or associatedShipment.customerNumber or associatedShipment.consigneeCustomerName+Address fields or associatedShipment.customerName+Address fields used to be required, but no longer are. A delivery that is sent in without consignee information will be processed and show as "Unknown Customer."

Duplicated fields

Within the request, there are several cases where information for the shipment can be defined generically or specifically for a shipmentType. In these cases, we will populate information based on a priority of these fields.
For example: to specify terminal information, you have the option to provide terminalCode (general) and/or associatedShipment.originTerminalCode (specific) and/or associatedShipment.destinationTerminalCode (specific). In the case that the shipmentType is pickup and ONlY terminalCode is provided, we will infer that this is the terminalCode where the shipment is being picked up from. Vice versa for delivery: we will infer that the terminalCode is where the shipment is being delivered from. For specific versions, regardless of shipment type the field itself describes the information. originTerminalCode will represent the terminal the shipment is getting/got picked up from regardless of what the shipmentType on the request is. This will allow you to specify more information about the shipment than the purely generic ones. If both a specific and a generic are specified and conflict for that shipmentType (shipmentType = "pickup", terminalCode = "ABC", originTerminalCode = "DEF"), the following priorities will take place and all extra fields will be ignored.

Terminal Information

  • shipmentType = "pickup" or "checkstop" (one of these is required, so no further default)
    1. associatedShipment.originTerminalCode
    2. terminalCode
  • shipmentType = "delivery" (one of these is required, so no further default)
    1. associatedShipment.destinationTerminalCode
    2. terminalCode
    3. associatedShipment.destinationSIC (looking to deprecate as a supported field in the near future, please do not use if possible)

Date Information

  • shipmentType = "pickup" or "checkstop" (one of these is required, so no further default)
    1. associatedShipment.pickupDate
    2. associatedShipment.requestedDate
  • shipmentType = "delivery" (one of these is required, so no further default)
    1. associatedShipment.deliveryDate
    2. associatedShipment.requestedDate

Location Information

  • shipmentType = "pickup" or "checkstop" (one of these is required, so no further default)
    1. associatedShipment.shipperCustomerNumber
    2. associatedShipment.customerNumber
    3. associatedShipment.shipperCustomerName + Address fields (all)
    4. associatedShipment.customerName + Address fields (all)
  • shipmentType = "delivery" (one of these is required, so no further default)
    1. associatedShipment.consigneeCustomerNumber
    2. associatedShipment.customerNumber
    3. associatedShipment.consigneeCustomerName + Address fields (all)
    4. associatedShipment.customerName + Address fields (all)

Product Information (not shipmentType specific, but similarly there are 2 ways to define in the request)

  1. associatedShipment.shipmentItems
  2. associatedShipment.shipmentTotalXs (i.e. shipmentTotalWeight, shipmentTotalPieces)
  3. default of {
    description: null,
    weight: 0,
    pieces: 0,
    palletCount: 0,
    palletSpaces: 0,
    handlingUnits: 0
    }

Any "extra" fields (fields send in the request, where there is higher priority field defined) will be ignored.

Update special considerations

Override Updates And Patch Updates

Every request should be sent in with all known and relevant shipment information.
We will essentially re-build an entire shipment and possibly it's stop for each request and then update our system accordingly. This means that for most fields, if a value is not sent in we will assume it to be some default value (usually null) and override whatever was previously sent in on that field. We will call these fields "override updates"
For example:
Request 1 comes in for shipment 1 with an instructions field of "pickup on elm street" and request 2 comes in to update shipment 1 with no instructions field populated, we will set the instructions field to null assuming that is what the request intended.
ALL relevant information needs to be sent in on every request.

However, for some fields, it doesn't make sense to override information with assumed defaults. These updates will be called "patch updates" where if a field is not sent in on a request, we don't touch the field in our database; we leave it as is.
For example:
Request 1 comes in for shipment 1 as a pickup with a pickupDate of "2021-09-01". It get's completed in Maven, and then later request 2 comes in for shipment 1 as a delivery with a deliveryDate of "2021-09-02", however no pickupDate is specified. Pickup date is considered a patch update when shipmentType="delivery" so in this case we won't override the existing pickupDate in the Maven system (we consider this historical data and while still updatable if you want, we won't touch it unless the request specifically tells us to).

The general philosophies around deciding if a field should be override or patch updated are as follows:

  • If a field is shipmentType specific, we should patch update to not loose data when the shipment becomes the other type
    • example: pickupDate is "pickup" shipmentType specific, we shouldn't override when the shipmentType is "delivery".
    • however, we may still override if the shipmentType is correct and this field is not required when this shipmentType is specified
  • If a field is usually set by the app or portal (not through the integrations although we allow it), we should patch not override to avoid messing with the driver’s inputted info
    • example: destinationZipCode is usually provided by the driver upon pickup, although we allow the integration to set it as well

Please see the field definitions to see which fields are expected to be which type of update.

Updating information also relevant to a shipment's stop

If the request is to update an existing shipment, it is possible its current stop must be adjusted. By adjusted, we mean that it's possible that the stop itself get's updated with new information, or that the shipment get's split off its original stop onto an entirely different one.
If any of the following information is different from the original shipment record’s information, the stop will be adjusted:

  • terminal
  • date
  • customer/location (where it's being picked up or delivered from)
  • appointment window times
  • routeCode
  • routeName

If the stop needs to be adjusted, and the stop currently has multiple shipments on it, then the update operation may trigger a splitting of the stop, so that the updated shipment is split onto a separate new stop that better matches the request to update, without effecting the other shipments on that stop.
Before splitting the stop, the operation will check to see if the updated shipment is eligible to be grouped onto any stops in that terminal. If an eligible stop is found, instead of splitting the shipment off onto a new stop, the shipment will be grouped with a preexisting stop.
So, please keep in mind that updating a shipment may cause stop splitting or stop grouping.

Updating to an entirely new stop

The shipment will be assigned a completely new stop in the following three cases (also possible to be grouped):

  1. The shipment's date is changing and the shipmentType is changing from a pickup to a delivery (shipment was picked up on 9/1 and will be delivered on 9/2)
  2. The shipment's date is changing and the shipment has been completed in some way (shipment failed to be delivered 9/1 and will attempt to be delivered again 9/2)
  3. The shipment's date is changing and the shipment's previous date was in the past (terminal time).
    In any of these three cases, the completed shipment’s shipmentStatus will be reset to pending, and a new stop will be created for it, unless it can be grouped onto an already existing stop.

We do not currently support updating shipments to be "same-day" through the integration (i.e. pickup and delivered on the same day, or pickup failed and try again same day).

refNumber and proNumber

As described above, refNumber and proNumber are the unique identifiers that link Maven's system to our external client's. Maven will use them to determine if a shipment already exists or not and therefore whether to create a new shipment or update an existing one. Also notably, refNumber is considered the unique identifier for a pickup while proNumber is considered the unique identifier for a delivery. Because of that, we allow updates (including to null) in the other version of the field depending on shipmentType.
For example:

  1. a request comes in with shipmentType "pickup" and refNumber "1234" and proNumber null
  2. the shipment gets completed in Maven and the driver adds proNumber "ABCD"
  3. a request comes in with the shipmentType "delivery" and refNumber "5678" and proNumber "ABCD"
  4. Since the request is for a delivery, we assume the proNumber is the unique identifier, find the shipment with proNumber "ABCD" exists and decide to update that shipment to become a delivery while also updating it's refNumber to be "5678"

manifestNumber special considerations

If a manifestNumber is provided in the request, the shipment will be assigned to that manifest if possible.

  • manifestNumber is not allowed to be null (will provide back a 400 error)
  • if the provided manifestNumber does not yet belong to a route instance in Maven, it will provide back a 400 error
    Assuming that the manifestNumber is known to the Maven system, any information relevant to both the route instance and the shipment will be "force matched" to the route. Meaning that we will follow the philosophy that the goal is to assign this shipment (and its stop) to this route instance, so if there is conflicting data, we will assume the route instance is correct and force the shipment to match.
    This data includes:
  • terminal
  • date
  • routeCode (associatedRouteCode)
    For example: if in Maven there is a route instance with a manifestNumber of "12345" and a terminal of "ABC", then a request to create or update a shipment comes in, where the terminal information on the request itself says "DEF" but the manifestNumber is "12345", the shipment will be assigned to terminal "ABC" in order to be assigned to this route instance and assume it's terminal is correct, effectively ignoring "DEF".

Inbound Product

If the company sending the request has our inbound product enabled, a delivery sent through this request will be set to be added to inbound or updated according to its various state within the inbound product.
Most of this information provided should remain the same, except that we will ignore any manifestNumber field sent in on a delivery (since it should be assigned through the inbound product). Also in the conditions listed under "Updating to an entirely new stop" we will set the inbound planning status to be unplanned and the delivery will become available on the "Available Freight" screen.

Associated Linehaul

When the inbound product is enabled, there is an option to specify a top level "associatedLinehaul" object. This object will describe any relevant linehaul information this shipment is currently on or will be on as it get's to its destination terminal. This information will inform the grouping on the available freight screen as it describes this shipment's physical location until the shipment has been closed onto another route/trailer. Similarly, the associatedLinehaul's manifestNumber is a unique identifier to this linehaul and will inform whether this request will update or create a linehaul grouping in the Maven system.

Further Validation Information

Window Time Validation:

If a windowStart and windowEnd are provided in the request, the windowEnd must be later than the windowStart, or else the request will fail.
We will always pull the appointment window information from the same "source". Meaning both the start and end time will come from the request itself, the location information we have stored, or defaults. We will never pull the start time from the request and the end time from the location, for example.
Any necessary window times must be sent in on every create and update request. This follows with the philosophy that "Every request should be sent in with all known and relevant shipment information." If an appointment window is set on a previous request and then another request comes in for this same shipment without windowStart and windowEnd times, the appointment window will be overridden with defaults based on the customer for the shipment or company sending in the request.
Assuming valid window times, appointment windows will be set from following priority:

  1. If a windowStart and/or windowEnd is sent in as valid values or null, then the integration will use these.
  • If windowStart and/or windowEnd set the start and/or end times as null respectively.
  1. If windowStart and windowEnd fields are not present in the request, the system will look to the location information of the shipment. If the relevant customer record has an openTime or closeTime, those will be set as the shipment’s open and close times (See postCustomer for more context).
  2. If windowStart and windowEnd fields are not present in the request and the customer record does not contain an openTime or closeTime, then the system will look to the default open and close time that was set during the initial integration phase with Maven Machines. If times were set, those default times will be used.

Route Validation:

A route code and route label (associatedRouteCode, associatedRouteLabel) must map to the same route record in the Maven System, and must be set up during the initial integration phase with Maven Machines.