VGM Public API

Table of Contents

Base URLs

Test: https://dev-bookingsystemapi.motasoftvgm.co.uk

Request an Authorisation Token

End Point:
/token

Example code snippet:

$http.post({baseUrl}/token,
"grant_type=client_credentials&client_id=xxxx&client_secret=xxxxxxxx" , {
headers: { 'Content-Type': 'application/x-www-form-urlencoded' } })

Example result:

{
    "access_token": "xxx-xxx-xx-xxx-xxx",
    "token_type": "bearer",
    "expires_in": 1199,
    "as:client_id": "xxx-xxx-xx-xxx-xxx",
    "clientGuid": "xxx-xxx-xx-xxx-xxx",
    ".issued": "Mon, 09 Oct 2023 14:13:53 GMT",
    ".expires": "Mon, 09 Oct 2023 14:33:53 GMT"
}

Once you have requested an authorisation token, you can send requests to the server until the token expires. If the token has expired or your access level is not sufficient the server will throw a 403 forbidden error.

The access token must be added to the header of every request to the server:

config.headers.Authorization = 'Bearer xxx-xxx-xx-xxx-xxx';

Get Slot Types

This Get method will bring back all available slot types which can be booked online. There are optional parameters that can be passed in which will calculate vehicle specific pricing for service type slots.

End Point:
/Api/SlotTypes/Get

Example request:
$http.get({baseUrl}/Api/SlotTypes/Get?branchGuid=xxxx-xxx-xx-xxx-xxx)

Result format:

[
  {
    "fullPrice": {
      "type": 3,
      "label": "Full Price",
      "value": 30
    },
    "discountedPrice": null,
    "nextAvailableDateTime": "0001-01-01T00:00:00",
    "type": 2,
    "id": 1234,
    "shortDescription": "Air Con Service",
    "longDescription": "A Full air con service inc. re-gas",
    "pricePrefix": "",
    "priceSuffix": "",
    "priceOverwrite": "",
    "addToBasketMessage": "",
    "allowBookingToDiary": true,
    "completeBookingText": "",
    "image": "http://theme4.motasoftumbraco.co.uk/branchresources/global/images/slottypes/icons/iconset1/blue/air_con.png",
    "vehicleCategories": [],
    "onlinePaymentEnabled": false
  }
]

Get Available Dates

Once you have the Slot Types, you can use this method to get the dates that have availability for the specified slot type combination. You must pass in the slot type IDs as a comma separated list. This is a post request to enable passing in a list of tyres as part of the request payload, however this functionality is outside of the scope of this project, so please just pass in an empty array for this parameter.

End Point:
/Api/AvailableSlotDates/Get

Example request:
$http.post('{baseUrl}/Api/AvailableSlotDates/Get?branchGuid=xxxx-xxx-xx-xxx-xxx&dateFrom=2023-10-10&dateTo=2023-10-12&slotTypeIDs=1234,5678', [])

Result format:

[
  {
    "date": "2023-10-10T00:00:00"
  },
  {
    "date": "2023-10-11T00:00:00"
  },
  {
    "date": "2023-10-12T00:00:00"
]

Get Available Times

Once you’ve found an available date, you can then use this request to get available times for the selected date.

End Point:
/Api/AvailableSlotTimes/Get

Example request:
$http.post({baseUrl}/Api/AvailableSlotTimes/Get?branchGuid=xxxx-xxx-xx-xxx-xxx&date=2023-10-10&slotTypeIDs=1234,5678, [])

Result format:

[
  {
    "startTime": "1900-01-01T09:00:00",
    "endTime": "1900-01-01T09:30:00",
    "slots": [
      {
        "slotStartTime": "1900-01-01T09:00:00",
        "slotEndTime": "1900-01-01T09:30:00",
        "slotTypeShortDescription": "Air Con Service",
        "slotID": 5678,
        "slotTypeID": 1234,
        "bayID": 0,
        "technicianID": 0,
        "slotLength": 30
      }
    ]
  },
  {
    "startTime": "1900-01-01T10:00:00",
    "endTime": "1900-01-01T10:30:00",
    "slots": [
      {
        "slotStartTime": "1900-01-01T10:00:00",
        "slotEndTime": "1900-01-01T10:30:00",
        "slotTypeShortDescription": "Air Con Service",
        "slotID": 5678,
        "slotTypeID": 1234,
        "bayID": 0,
        "technicianID": 0,
        "slotLength": 30
      }
    ]
  }
]

The result set here we call a slot range, and will outline all of the available times for the slot combination and the full range of time that the slots will cover.

Submit Booking

Once the desired slot types, date and time have been selected, a booking can be submitted. You will need to build up an object with the following properties to create a successful booking, I will break it up into sections and explain each part:

End Point:
/Api/SubmitBooking/Post

When submitting the customer details, please ensure the guestAccount property is set to ‘1’ this is to bypass having to login to an existing or creating a new account

"customer": {
        "title": "Mr",
        "firstName": "API",
        "surname": "Test",
        "mobile": "07908458089",
        "address1": "Origin Work Space",
        "address2": "",
        "address3": "",
        "townCity": "Bristol",
        "county": "Bristol",
        "postcode": "BS81HP",
        "email": "test12345@motasoft.co.uk",
        "guestAccount": 1
    }

Below are the required vehicle fields, you can use the /API/FuelTypes/Get end point to populate the fuelTypeID field

 "vehicle": {
        "registrationNumber": "MW17WKC",
        "make": "BMW",
        "model": "M2",
        "fuelTypeID": 1,
        "engineCC": "3000"
    }

The Slot Range object must be populated using the Get Available end point:

"slotRange": {
        "startTime": "1900-01-01T10:00:00",
        "endTime": "1900-01-01T10:00:00",
        "slots": [
            {
                "slotStartTime": "1900-01-01T10:00:00",
                "slotEndTime": "1900-01-01T10:00:00",
                "slotTypeShortDescription": "Air Con Service",
                "slotID": 5678,
                "slotTypeID": 1234,
                "bayID": 0,
                "technicianID": 0,
                "slotLength": 30
            }
        ]
    }

The code below shows an example of how to populate the onlineShoppingBasket object, for this integration we’re really only interested in populating the slotTypes object which is retrieved by calling the Get Slot Types end point:

"onlineShoppingBasket": {
    "tyres": [],
    "slotTypes": [
      {
        "fullPrice": {
            "type": 3,
            "label": "Full Price",
            "value": 30.00
        },
        "discountedPrice": null,
        "nextAvailableDateTime": "0001-01-01T00:00:00",
        "type": 2,
        "id": 1234,
        "shortDescription": "Air Con Service",
        "longDescription": "A Full air con service inc. re-gas",
        "pricePrefix": "",
        "priceSuffix": "",
        "priceOverwrite": "",
        "addToBasketMessage": "",
        "allowBookingToDiary": true,
        "completeBookingText": "",
        "image": "http://theme4.motasoftumbraco.co.uk/branchresources/global/images/slottypes/icons/iconset1/blue/air_con.png",
        "vehicleCategories": [],
        "onlinePaymentEnabled": false
    }
    ],
    "specialOffers": [],
    "extras": [],
    "response": [],
      "id": 0,
    "applicationID": 0,
    "items": null
  }

Lastly, you will need to populate the bookingDate property and you can optionally add some notes:

  "bookingDate": "2023-10-10T12:37:32.157Z",
  "notes": "Some notes for an example booking submission"

Result format:
An onlineShoppingBasket object will be returned from the API in response to the post operation. This does not guarantee that a booking has been placed successfully. Below is an example of a response to a request that didn’t submit a booking object:

{
  "tyres": [],
  "slotTypes": [],
  "specialOffers": [],
  "extras": [],
  "response": [
    {
      "issueType": 0,
      "issueDescription": "No Booking submitted"
    }
  ],
  "allowBookingToDiary": true,
  "shoppingBasketTotal": 0,
  "id": 0,
  "applicationID": 0,
  "items": null
}

When a booking has been placed successfully, there will be no response object and the id property will have a value that’s greater than zero, below is an example of a successful online shopping basket response:

{
    "tyres": [],
    "slotTypes": [
        {
            "fullPrice": {
                "type": 3,
                "label": "Full Price",
                "value": 30.00
            },
            "discountedPrice": null,
            "nextAvailableDateTime": "0001-01-01T00:00:00",
            "type": 2,
            "id": 1234,
            "shortDescription": "Air Con Service",
            "longDescription": "A Full air con service inc. re-gas",
            "pricePrefix": "",
            "priceSuffix": "",
            "priceOverwrite": "",
            "addToBasketMessage": "",
            "allowBookingToDiary": true,
            "completeBookingText": "",
            "image": "http://theme4.motasoftumbraco.co.uk/branchresources/global/images/slottypes/icons/iconset1/blue/air_con.png",
            "vehicleCategories": [],
            "onlinePaymentEnabled": false
        }
    ],
    "specialOffers": [],
    "extras": [],
    "response": [],
    "allowBookingToDiary": true,
    "shoppingBasketTotal": 30.00,
    "id": 116335,
    "applicationID": 0,
    "items": null
}