Data & Delivery Format

Introduction

This document describes the data format that contains all necessary information, so that an external system can use Bettermile as a route optimization system. Drivers using Bettermile App will get an optimized route sequence, routing support (turn by turn navigation), consignee addresses, timeframes and other helpful information. Furthermore, it is a prerequisite for route optimization analysis and monitoring within the Bettermile Backoffice. The top level object in the data format is job, which is an abstraction of a single task a delivery driver has to perform. Currently there are three different types of jobs:

  • delivery - job type for which the consignee-contact will be considered for tour calculation.
  • pickup - pickup of a specific parcel with an already known parcel id. Shipper-contact will be considered for tour-calculation.
  • collection - collecting an unknown number of parcels at the shipper-contact location (e.g. parcel shop, drop box).

Although all required information could technically be combined in one single job object, the different aspects typically become available at different points in time in the lifecycle of a parcel. Bettermile considers three phases of data transmission:

  • master data - job properties that do not change (id, type, depot) or that are unlikely to change (shipper & consignee information) until the job is done. This information can be transmitted to Bettermile as soon as it is available in the tenants IT system. The actual date of delivery does not need to be final at this time.
  • assignment data - contains assignment information for one job to a specific driver (or route, vehicle, etc) on a specific date. This is required for all jobs designated for a specific driver/route before Better Route is able to calculate optimized sequences and navigation routes for the driver. The ultimate goal is that assignments reflect 100% of the parcels physically present in a driver's vehicle when he/she leaves the depot in the morning and logs into Bettermile App.
    Please note that it is quite common that there will be multiple assignments for one job:
    • Drivers trade/swap parcels after the initial assignment was transmitted: in that case the tenant's connector should send a new assignment for the same job id with the new assignment value and a later scan date.
    • A parcel was not delivered today and it will be assigned to the same (or another) driver/route tomorrow: in this case the connector needs to transmit a new assignment for the next day, so that Better Route can include it on a new delivery sequence for the next day.
  • status updates - are typically sent after the driver left the depot and a parcel gets a new status (e.g. “delivered”) in the tenants IT systems. Main purpose is to know which jobs need to be considered for tour (re-)calculation and which can be ignored because they are done.

General remarks on the format

Bettermile expects that all the data that is required for a certain date is exported daily before any driver activity takes place. The standard delivery mechanism is a periodic upload to an AWS S3 bucket.

The data is sent in JSON format as a top level array of elements (preferred) or as concatenated JSON.

Array example:

Copy
Copied
[
  {
    "id": "dc5a6618-66ac-4128-b198-fabcfca45423",
    "date": "2020-01-02",
    "...": "..."
  },
  {
    "id": "f30f3f1c-2115-4f36-8be3-c0fda62a78aa",
    "date": "2020-01-02",
    "...": "..."
  }
]

Concatenated JSON (Wikipedia):

Copy
Copied
{
  "id": "dc5a6618-66ac-4128-b198-fabcfca45423",
  "date": "2020-01-02",
  "...": "..."
}
{
  "id": "f30f3f1c-2115-4f36-8be3-c0fda62a78aa",
  "date": "2020-01-02",
  "...": "..."
}

The encoding of the data must be in UTF-8.

Additionally, the data has to be compliant with the JSON schema (see https://json-schema.org/). The D&D schema can be found under the following URLs:

Any particular payload should be validated against the schema by using a JSON schema validator (eg. JSON Schema Validator). Invalid job objects will not be processed by Bettermile Data Gateway.

Example

This is an example of import file, representing a Job object.

Copy
Copied
{
    "id" : "54365964-xyz",
    "date" : "2021-12-07",
    "created" : "2021-12-06T17:25:51.443-08:00",
    "source" : "manifest",
    "depot" : "ORC",
    "type" : "delivery",
    "shipper" : {
      "names" : [
        "Thalia Bücher GMBH"
      ]
    },
    "consignee" : {
      "type": "private",
      "names" : [
        "Firstname Lastname"
      ],
      "address" : {
        "street" : "4400 MacArthur BLVD",
        "postalCode" : "92660",
        "locality" : "NEWPORT BEACH",
        "province" : "CA",
        "country" : "US"
      },
      "email" : "user@foo.com",
      "phone" : "+4916012345678",
      "timeFrames" : [
        {
          "type" : "required",
          "earliest" : "09:00:00",
          "latest" : "14:00:00",
          "timezone" : "Europe/Brussels"
        }
     ]
   },
    "assignment" : {
      "scantime" : "2021-12-06T17:25:51.443-08:00",
      "properties" : {
        "route" : "4711"
      }
    },
    "services" : [
      {
        "acronym" : "PRI",
        "description" : "Priority Delivery"
      },
      {
        "acronym" : "SIG",
        "description" : "Adult Signature Required"
      }
    ],
    "physicalProperties" : [
      {
        "property" : "quantity",
        "value" : 1
      },
      {
        "property" : "weight",
        "value" : 12.0
      }
    ]
 }

Types

Job

A job contains everything that is necessary for a driver to perform a task. Most of the time, it is about delivering a parcel to a particular address.

Name Mandatory Description
id yes Identifier for this job. It must be unique for at least 30 days in the tenants systems. Typically this is a parcel id. There is no restriction on the format (e.g. a UUID or a number) but provided as STRING in the JSON.
date yes Expected delivery, pickup or collection date. Date in YYYY-MM-DD format. For master data this does not need to be the final delivery date. But when transmitting assignments for a job, this needs to be the date the parcel will be physically present in the last mile vehicle.
created no (but recommended!) When was the data created (e.g. when did some automatic process create this data set). RFC 3339 section 5.6 timestamp, for example: 2022-05-12T08:00:13.623Z or 2022-05-12T10:00:13.623+02:00

Used for a last one wins approach if conflicting data is sent to Bettermile.
source yes A predefined constant that describes in which process this job description was generated. Possible values: "master", "manifest", "assignment", "scan".
depot yes Tenant specific identifier that assigns the data to a particular depot.
type no delivery, pickup, collection. Classification of this job.
realtimeTracking no (yes for Real-time Tracking usage) See RealtimeTracking. It contains information that controls Real-time Tracking behavior for this job.
shipperReference no Shipper’s reference. Example: “Amazon Order #12345678”. Might be shown to the consignee within Real-time Tracking.
shipper no (yes for pickup/collection) See Contact. This is the delivery sender or pickup/collection contact.
consignee no (yes for delivery) See Contact. This is the object representing the recipient and it contains the delivery address.
redirectContact no See Contact. If a redirectContact is provided, its address will be used instead of shipper or consignee by Better Route to determine the waypoint coordinates for this job.
Typical use case is a planned redirect to a parcel shop.
services no A list of service and products. See Services. Examples are
“Euro Business Small Parcel”, “G24”, “Flex Delivery“. This can mean that the product adheres to size and weight conventions (small business parcel) or has a special service to perform “ident“ or “cash on delivery“. The driver knows what it means, so this is worth displaying.
physicalProperties no Physical properties like weight, height, length, volume, etc.
statusChanges no A list of state changes that reflect what happened (or just happened) in the delivery process. See StatusChange.
assignment no See Assignment. The assignment assigns a job to a particular driver, route or vehicle. This is a crucial piece of information, so that the correct jobs, which are relevant for a particular driver, can be retrieved for example in the Bettermile App."
unassignment no An optional Unssignment of a job to rollback a previous assignment.

Assignment

Note - Currently, an assignment has no specific source and date referred to it directly. This information is specified in the containing job object.

Name Mandatory Description
properties yes Object with property “vehicle”, “route” or “driver”, … Choose an assignment property that is established in the tenants IT systems and that is also known by the driver/user of Bettermile App. The string value provided with the chosen property will be the identifier a driver needs to select his/her route in the Bettermile App.
scantime no Time when a job was scanned by the driver or the prepicker. RFC 3339 section 5.6 timestamp for example 2022-05-12T08:00:13.623Z or 2022-05-12T10:00:13.623+02:00
priorityGroup no An integer number. A priority group number is used to prestructure the Better Route optimized sequence. First all jobs assigned with the lowest group number will be considered for the Better Route sequence, then all jobs with the next higher group number. Jobs with different priorityGroup will not be combined in one waypoint.
If the job also has timeFrames, they can be in conflict with the priorityGroup and might be ignored.
assignmentTags no Object with key-value pairs for optional information on the current assignment properties. These tags are intended solely for informational purposes and do not define or affect the mandatory assignment properties object.

Assignment Tags

Assignment tags allow Bettermile to receive custom tenant-specific fields to enrich the required assignment property values. Assignment tags are enabled on a tenant-by-tenant basis and serve complimentary details to various Bettermile platform components such as Route, RTT, and Backoffice on tenant-specific operational contexts surrounding the submitted assignment values.

Assignment tags have the same lifespan as the parent assignment object: they expire when a new assignment for the Job is received or at midnight local time.

Name Mandatory Description
driverName no A string field with the driver's name. If enabled for a tenant, this information will be presented in the Bettermile Backoffice alongside the assignment properties for Cloudtracking tours.
tourGroup no A string field designating the tour number. If enabled for a tenant, this information will be presented in the Bettermile Backoffice alongside the actual assignment properties (e.g."driver").
loadingZone no A string field designating the loading zone for a specific job. If enabled for a tenant, this information will be presented to the drivers on the Bettermile app loading screen.
subcontractorName no A string field with the subcontractor name. If enabled for a tenant, this information will be presented in the Bettermile Backoffice alongside the assignment properties for Cloudtracking tours.

Example

Copy
Copied
{
    "id": "624717089",
    "date": "2021-09-01",
    "created": "2021-09-01T14:03:08.190+02:00",
    "depot": "687",
    "source": "assignment",
    "assignment": {
        "scantime": "2021-09-01T02:34:00Z",
        "priorityGroup": 1,
        "properties": {
            "vehicle": "2003"
        },
    "assignmentTags": {
        "driverName": "Jane Doe",
        "loadingZone": "Zone 2",
        "tourGroup": "5001",
        "subcontractorName": "John Doe"
    }
  }
}

Unassignment

Note - Currently, an unassignment has no specific source and date referred to it directly. This information is specified in the containing job object.

Name Mandatory Description
unassignment yes Specifies which assignment to remove from the job ID (see Assignment).

Example

Copy
Copied
{
  "id": "5743897964",
  "date": "2022-05-12",
  "created": "2022-05-12T13:11:23.264+02:00",
  "depot": "CT",
  "source": "assignment",
  "unassignment": {
    "assignment": {
      "properties": {
        "vehicle": "2003"
      }
    }
  }
}

Contact

Name Mandatory Description
address no The postal address.
email no Email address.
phone no A telephone number. E.164 format (https://en.wikipedia.org/wiki/E.164)
names no List of identifying names for the contact, e.g. "Microsoft", "Sales department", "c/o Jane Doe" or simply just one element like "John Doe".
hints no A list of helpful driver hints (for display only): “2nd backyard”, “Laderampe 5”, “deliver at back entrance only“, “pickups from ramp only“, …
timeFrames no A list of Timeframe objects. A timeframe is a temporal constraint for the job that will be considered in sequence calculation.
type no business, private, parcel_locker, parcel_shop.
id no A unique contact ID. This may be used to group jobs into contact specific groups or may be required for shipper contacts for Real-time Tracking. For a shipper contact this may be for example “72645-Adidas”
language no Preferred language of contact when contacted digitally for example within Real-time Tracking. Consists of language identifier and optional country code. For example: es, en, en_IE, en_US etc. (ISO 639-1 language codes and ISO-3166-1 alpha 2 country codes). If not provided, the language defaults to the depot/tenant language.

Address

Name Mandatory Description
street yes The street address including house numbers (if available) in country specific formats: “10 Downing Street”, “Harzer Str. 39”, “Via Garibaldi 374”. Do not include information that is irrelevant for geocoding. Additional delivery instructions to the driver should be send as “hints” property instead.
postalCode yes Postal code.
locality no E.g. the city.
province no Optional hint in which province, county, district or region an address is located.
country yes Alpha 2 country code: https://en.wikipedia.org/wiki/ISO_3166-1.
geoCoordinates no List of WGS84 lat/lngs. It is optional, since Bettermile performs the geocoding of the supplied address, but may be set as a fallback.

GeoCoordinates

Geo coordinates can be sent in one of the following data structures:

Name Mandatory Description
type no E.g. “rooftop”, “parking stop”, “street coordinates”, “handover”.
latitude yes WGS 84 latitude. At least 5 digits precision after the comma, like 52.53526 (1.1m accuracy)
longitude yes WGS 84 longitude. At least 5 digits precision after the comma, like 13.24351 (1.1m accuracy)
Name Mandatory Description
type no E.g. “rooftop”, “parking stop”, “street coordinates”, “handover”.
w3w yes A what3word address as a string. It must be three words separated with dots or a japanese middle dot character (・)

Timeframe

Name Mandatory Description
type yes Can only be “required”.
earliest yes Earliest time for delivery or collection. Format is HH:MM:SS. (24h) It is meant to refer to the tenant’s default timezone or the one that is specified here in attribute timezone.
It refers to the date of the job.
latest yes Latest time for delivery or collection. Must be later than earliest time. Format is HH:MM:SS. (24h) It is meant to refer to the tenant’s timezone or the one that is specified here in attributetimezone.
It refers to the date of the job.
timezone no The timezone the timeframe is in. If not specified, the default timezone of the tenant is assumed. It must be one of https://en.wikipedia.org/wiki/List_of_tz_database_time_zones (e.g. Europe/Brussels). For countries with more than one timezone this property is mandatory. The timezone explicity defined here should be the timezone where the contact is located.

Services

Name Mandatory Description
acronym yes Acronym of a service (for instance: "ESBP").
description yes Complete name or description of the service (for instance: “European Small Business Parcel”).

Physical Property

Name Mandatory Description
property yes weight, height, length, width, volume, quantity. Units are predefined:
  • weight: gram
  • height/length: cm
  • volume: cm³
value yes Decimal value, provided as JSON number (not string!) For example, 20.6.

RealtimeTracking

The realtimeTracking (RTT) object contains additional configuration data required specifically for Better Tracking services.

Name Mandatory Description
enabled no true/false: enables/disables RTT for the specific job. If a tenant is using RTT, the default is true, otherwise RTT will not be enabled anyway.
notification no Notification details for this job. See Notification below.
redirect no Real-time Tracking parcel redirect options for example depending on service type. Contains the attributes neighbor, deposit and parcelShop to set permissions for this job, wether the delivery may ad-hoc be redirected to a neighbor or be deposited at a consignee location or be handed over to a parcel shop.
Example:
"redirect" : {
"neighbor": true,
"deposit": false,
"parcelshop": true
}

Defaults: false for all fields.

Notification

Describes how and when to contact the consignee via Real-Time Tracking.

Name Mandatory Description
invite no How to send the “Invite” to the consignee. Contains the attributes email and sms (true/false) to define whether or not to send invite messages via these channels.

Example:

"invite": {
"email": true,
"sms": false
}
reminder no How to send the reminder to the consignee. Contains the attributes email and sms (true/false) to define whether or not to send reminder messages via these channels.

Example:

"reminder": {
"email": true,
"sms": false
}

Full example

Copy
Copied
{
  "enabled": true,
  "notification": {
      "invite": {
        "email": true,
        "sms": false
      },
      "reminder": {
        "email": true,
        "sms": false
      }
  },
  "redirect": {
      "neighbor": true,
      "deposit": false,
      "parcelShop": true
  }
}

StatusChange

Name Mandatory Description
state yes
  • “processed”: the job was either successfully or unsuccessfully completed by the driver (see "outcome")
  • “unprocessed”: a previous “processed” state gets reverted. For example, the parcel is again out for delivery.
A job that is processed will be removed from the Better Route optimized route.
timestamp yes Date and time of status change most likely determined on the driver's scanning device. RFC 3339 section 5.6 timestamp, for example 2022-05-12T08:00:13.623Z or 2022-05-12T10:00:13.623+02:00
outcome no “success”, “unsuccessful” (parcel was delivered or not, pickup was collected or not). Should be set for “processed” events so a problem view in the Bettermile App will contain unsuccessful delivery attempts. Also the driver may reopen a waypoint containing a job with an unsuccessful delivery attempt.
outcomeDetails no See OutcomeDetails below. Further details about redirects or delivery failures
onLocation no true, false: whether the driver was at the waypoint or not. Currently unused.
description no A textual description of the event to be displayed in the BetterRoute conflict view.
geoCoordinates no WGS84 lat/lngs of the location where the handscanner event took place. See GeoCoordinates.

Example

Copy
Copied
{
  "id": "9200313150",
  "date": "2022-05-23",
  "source": "scan",
  "created": "2022-05-23T09:21:58.123+02:00",
  "statusChanges": [
    {
      "state": "processed",
      "timestamp": "2022-05-23T09:17:12.876+02:00",
      "outcome": "success",
      "outcomeDetails": {
        "type": "neighbor",
        "names": [
          "Beauty Hair Berlin",
          "c/o Jane Doe"        ]
      },
      "description": "to neighbour",
      "geoCoordinates": {
        "latitude": 37.72525,
        "longitude": 15.19114      }
    }
  ]
}

StatusChange - OutcomeDetails

The information here is largely used for Bettermile Real-time Tracking

Name Mandatory Description
type yes A categorisation of different outcomes. Used primarily in Better Tracking.
  • successful outcomes
    • “normal“ ==> Standard outcome. For example delivery was handed over to consignee
    • “pickedup“ ==> Parcel has been returned to the shipper from a parcel shop
    • “parcel\shop” ==> delivery ended up in parcel shop. In this case names and address ought to be set.
    • “neighbor” ==> delivery was handed over to neighbor. In this case names ought to be set.
    • “deposit” ==> delivery was deposited at specified location. Further “hint” may be set in this case.
  • unsuccessful outcomes
    • “not_accepted” ==> the delivery was not accepted by the consignee/was refused.
    • “absent” ==> Consignee/Sender was absent.
    • “address_problem” ==> there was a problem with the address.
    • “traffic_problems” ==> driver was unable to reach the destination due to traffic.
  • undefined type.
    • “other” ==> There was either a successful or unsuccessful outcome not covered here.
hint no Free text to further enhance the outcome type. It is shown on Better Tracking website. This may contain information like where the parcel was finally deposited (“deposited in garage”, “deposited on terrace”, etc.)
names no List of identifying names, e.g. "Beauty Hair Berlin", "c/o Jane Doe" or simply just one element like "John Doe".
address no See Address. The exact address, for example of the parcel shop.

Outcome Details - Parcel shop example

Copy
Copied
"outcomeDetails": {
  "type": "parcel_shop",
  "names": [
    "Kiosk & Bakery"
  ],
  "address": {
    "street": "Gubener Str. 23",
    "postalCode": "10243",
    "locality": "Berlin",
    "province": "BE",
    "country": "DE"
  }
}

Outcome Details - Neighbor example

Copy
Copied
"outcomeDetails": {
  "type": "neighbor",
  "names": [
    "Beauty Hair Berlin",
    "c/o Jane Doe"
  ]
}

Outcome Details - Deposit example

Copy
Copied
"outcomeDetails": {
  "type": "deposit",
  "hint": "on the terrace"
}

Outcome Details - Unsuccessful outcome because parcel was refused

Copy
Copied
"outcomeDetails": {
  "type": "not_accepted"
}

Notes for the types

  • Mandatory means that it must be present and not empty.
  • Date and times must follow the RFC 3339 section 5.6 standard . Timestamps must be UTC or include a timezone to be unambiguous.