API Developer Guide
Overview
Welcome to the API Developer Guide. Please use the sandbox URL for testing purposes. When using the production version, ensure you have the production key and access. If you would like to opt into the program, please contact info@coachhire.com.
Authentication
To access the API, you must first log in using your credentials. The login URL is:
POST /api/auth/login
Request
URL: /api/auth/login
Method: POST
Content-Type: application/json
Body Parameters:
username(string): Your username.password(string): Your password.
Example Request
{
"username": "your_username",
"password": "your_password"
}
Successful Response:
{
"token": "your_token_here"
}
Example Response:
{
"token": "abc123xyz456"
}
Using the Token
Once you have the token, you need to include it in the header of your API requests. Use the following format:
Authorization: Bearer your_token_hereExample of an Authenticated Request
GET /api/your_endpoint
Host: api.yourdomain.com
Authorization: Bearer abc123xyz456
Make sure to replace abc123xyz456 with the actual token received from the login endpoint.
Requesting a Quote
To request a quote, you need to send a request to the /api/booking/request endpoint. This request requires authentication with the token, an AccessKey, and the following body parameters.
Request
URL: /api/booking/request
Method: POST
Content-Type: application/json
Headers:
Authorization: Bearer your_token_here
AccessKey: your_secret_key_here
Body Parameters:
pickupDateTime(string): The date and time for pickup (format: "YYYY-MM-DD HH: MM").pickupAddress(string): The pickup address.pickupLat(float): The latitude of the pickup location.pickupLng(float): The longitude of the pickup location.extraDrop(array): An array of additional drop-off locations. Each object should contain:Address(string): The address of the extra drop.Lat(float): The latitude of the extra drop location.Lng(float): The longitude of the extra drop location.TravelType(string): The type of journey (Outward Journey, Return Journey, Both Journeys).
dropoffAddress(string): The dropoff address.dropoffLat(float): The latitude of the dropoff location.dropoffLng(float): The longitude of the dropoff location.NumberOfPassenger(int): The number of passengers.LuggageType(string): The type of luggage.VehicleType(string): The type of vehicle.JourneyType(string): The type of journey.returnTrip(boolean): Indicates if it is a return trip.returnDateTime(string): The date and time for the return trip (format: "YYYY-MM-DD HH:MM").passengerInfo(object): An object containing passenger information.name(string): The passenger's name.email(string): The passenger's email address.phonenumber(string): The passenger's phone number.
extRef(string): The external reference number. (optional)notesCustomers(string): Additional notes for the customer. (optional)
Example Request for Quote
{
"pickupDateTime": "2024-05-12 15:00",
"pickupAddress": "Tower of London",
"pickupLat": 51.5085985,
"pickupLng": -0.07633,
"extraDrop" : [
{
"Address" : "London Transport Museum",
"Lat": 51.5121233,
"Lng": -0.1212471;,
"TravelType": "Outward Journey"
},
{
"Address" : "Central London",
"Lat": 51.5001524,
"Lng": -0.1262362;,
"TravelType": "Return Journey"
},
{
"Address" : "Museum of London",
"Lat": 51.5177777,
"Lng": -0.0965835,
"TravelType": "Both Journeys"
}
],
"dropoffAddress": "London Bridge",
"dropoffLat": 51.5059213,
"dropoffLng": -0.0874807,
"NumberOfPassenger": 9,
"LuggageType": "No luggage.",
"VehicleType": "9-13 Seat Standard Mini Bus",
"JourneyType": "Business Travel",
"returnTrip": true,
"returnDateTime": "2024-05-15 07:00",
"passengerInfo" : {
"name" : "Yui Lau",
"email" : "xxx@email.com",
"phonenumber" : "xxxxxxxxxx"
},
"extRef" : "123456",
"notesCustomers" : "customer notes"
}
Example Response for Quote
{
"quote_id": 1003787,
"status": 1,
"message": "Quote created",
"error": false,
"priceInfo" : {
"vehiclePrice": 1530.66,
"vehiclePriceTotal": 1684,
"vat": "10.00",
"status": 1,
"message": "journey price found"
}
}
Get Available Vehicle Types
To find out what types of vehicles are available based on the number of passengers, use the following endpoint:
Request
URL: /api/booking/availableVehicleTypes/:NumberOfPassenger
Method: GET
Content-Type: application/json
Headers:
Authorization: Bearer your_token_here
AccessKey: your_secret_key_here
Path Variables:
NumberOfPassenger(string): The number of passengers.
Example Request
GET /api/booking/availableVehicleTypes/2
Example Response:
{
"count": 1,
"result":[
{
"car_id": "2",
"car_name": "9-13 Seat Standard Mini Bus",
"short_des": "**Typically Toyota Hiace or similar.",
"long_des":"* CD Audio System* Seatbelts* Air Conditioning* Window Tint* PA",
"bagList": [
{
"bag_id": "1",
"bag_des": "No luggage."
"bag_size": "0.00"
},
{
"bag_id": "2",
"bag_des": "1.00"
},
{
"bag_id": "3",
"bag_des": "2.00"
},
{
"bag_id": "4",
"bag_des": "3.00"
}
]
}
]
}
User extension number
To find out what user extension number based on customer phone number, use the following endpoint:
Request
URL: /api/customer/extension/:phoneNumber
Method: GET
Content-Type: application/json
Headers:
Authorization: Bearer your_token_here
AccessKey: your_secret_key_here
Path Variables:
phoneNumber(string): The number of phone number.
Example Request
GET /api/customer/extension/xxxxxxxxxx
Example Response:
{
"name": "Yui Lau",
"ext_number": "xxxx"
}
Get Quote
To retrieve the details of an existing quote, send a request to the /api/booking/{quote_id} endpoint. This request requires authentication with the token and an AccessKey.
Request
URL: /api/booking/:quote_id
Method: GET
Content-Type: application/json
Headers:
Authorization: Bearer your_token_here
AccessKey: your_secret_key_here
Path Variables:
quote_id(integer): The ID of the quote to retrieve.
Example Request
GET /api/booking/1003787
Example Response:
{
"status": 1,
"error": false,
"quote_id": 1003787,
"status_re": "Quote",
"passenger_info": {
"name": "Yui Lau",
"email": "xxx@email.com",
"phone_number": "xxxxxxxxxx"
},
"journey_type": "Business Travel",
"num_of_passenger": 9,
"vehicle_type": "9-13 Seat Standard Mini Bus",
"luggage": "No luggage.",
"ext_ref": "123456",
"comment": "customer notes",
"journey_info": [
{
"movement_id": 2070,
"journey_order": 1,
"movement_order": 1,
"is_start": true,
"pickup_date": "2024-05-12",
"pickup_time": "15:00:00",
"pickup_datetime": "2024-05-12 15:00:00",
"collection": {
"address": "Tower of London",
"notes": "",
"lat": "51.5085985",
"lng": "-0.0763300"
},
"destination": {
"address": "London Transport Museum",
"notes": "",
"lat": "51.5121233",
"lng": "-0.1212471"
},
"num_of_passenger": 9,
"vehicle_type": "9-13 Seat Standard Mini Bus",
"luggage": "No luggage.",
"journey_type": "Business Travel"
},
{
"movement_id": 2091,
"journey_order": 1,
"movement_order": 2,
"is_start": false,
"pickup_date": "2024-05-12",
"pickup_time": "16:00:00",
"pickup_datetime": "2024-05-12 16:00:00",
"collection": {
"address": "London Transport Museum",
"notes": "",
"lat": "51.5121233",
"lng": "-0.1212471"
},
"destination": {
"address": "London Bridge",
"notes": "",
"lat": "51.5059213",
"lng": "-0.0874807"
},
"num_of_passenger": 9,
"vehicle_type": "9-13 Seat Standard Mini Bus",
"luggage": "No luggage.",
"journey_type": "Business Travel"
}
]
}
Edit Quote
To edit an existing quote, send a request to the /api/booking/request/{quote_id} endpoint. This request requires authentication with the token, an AccessKey, and the following body parameters. Only quotes in status Q (Quote) or B (Booking) may be edited.
Request
URL: /api/booking/request/:quote_id
Method: PUT
Content-Type: application/json
Headers:
Authorization: Bearer your_token_here
AccessKey: your_secret_key_here
Path Variables:
quote_id(integer): The ID of the quote to edit.
Body Parameters:
pickupDateTime(string): The date and time for pickup (format: "YYYY-MM-DD HH:MM").pickupAddress(string): The pickup address.pickupLat(float): The latitude of the pickup location.pickupLng(float): The longitude of the pickup location.extraDrop(array): An array of additional drop-off locations. Each object should contain:Address(string): The address of the extra drop.Lat(float): The latitude of the extra drop location.Lng(float): The longitude of the extra drop location.TravelType(string): The type of journey (Outward Journey, Return Journey, Both Journeys).
dropoffAddress(string): The dropoff address.dropoffLat(float): The latitude of the dropoff location.dropoffLng(float): The longitude of the dropoff location.NumberOfPassenger(int): The number of passengers.LuggageType(string): The type of luggage.VehicleType(string): The type of vehicle.JourneyType(string): The type of journey.returnTrip(boolean): Indicates if it is a return trip.returnDateTime(string): The date and time for the return trip (format: "YYYY-MM-DD HH:MM").passengerInfo(object): An object containing passenger information.name(string): The passenger's name.email(string): The passenger's email address.phonenumber(string): The passenger's phone number.
extRef(string): The external reference number. (optional)notesCustomers(string): Additional notes for the customer. (optional)movementIds(array): Existing movement IDs to keep, in order. IDs not listed are deleted; append 0 to create a new movement.
Example Request for Edit Quote
{
"pickupDateTime": "2026-08-15 09:30",
"pickupAddress": "Tower of London",
"pickupLat": 51.5085985,
"pickupLng": -0.07633,
"extraDrop": [
{
"Address": "London Transport Museum",
"Lat": 51.5121233,
"Lng": -0.1212471,
"TravelType": "Outward Journey"
}
],
"dropoffAddress": "London Bridge",
"dropoffLat": 51.5059213,
"dropoffLng": -0.0874807,
"NumberOfPassenger": 6,
"LuggageType": "No luggage.",
"VehicleType": "9-13 Seat Standard Mini Bus",
"JourneyType": "Business Travel",
"returnTrip": false,
"returnDateTime": "",
"passengerInfo": {
"name": "Yui Lau",
"email": "xxx@email.com",
"phonenumber": "xxxxxxxxxx"
},
"extRef": "123456",
"notesCustomers": "customer notes",
"movementIds": [2070, 2091, 0]
}
Example Response for Edit Quote
{
"quote_id": 1003787,
"status": 1,
"message": "Quote updated",
"error": false,
"priceInfo": {
"vehiclePrice": 1530.66,
"vehiclePriceTotal": 1684,
"vat": "10.00",
"status": 1,
"message": "journey price found"
}
}
Edit Complex Quote
To edit an existing quote at the individual movement level, send a request to the /api/booking/edit/{quote_id} endpoint. Unlike Edit Quote, this endpoint accepts a flat movements array where each movement carries its own operation flag (new, update, or delete). Every existing movement on the quote must appear in the payload as either update or delete. Only quotes in status Q (Quote) or B (Booking) may be edited.
Request
URL: /api/booking/edit/:quote_id
Method: PUT
Content-Type: application/json
Headers:
Authorization: Bearer your_token_here
AccessKey: your_secret_key_here
Path Variables:
quote_id(integer): The ID of the quote to edit.
Body Parameters:
number_of_passenger(int): The number of passengers.vehicle_type(string): The type of vehicle.luggage_type(string): The type of luggage.journey_type(string): The type of journey.passenger_info(object, optional): Lead passenger information.name(string): The passenger's name.email(string): The passenger's email address.phone_number(string): The passenger's phone number.
ext_ref(string): The external reference number. (optional)notes_customers(string): Additional notes for the customer. (optional)movements(array): A flat array of movement operations. Each object should contain:op(string): The operation ânew,update, ordelete.movement_id(int): Required forupdateanddelete; omit fornew.journey_order(int): Positive integer; movements sharing the same value form one journey. Required fornewandupdate.collection_address(string): The pickup address. Required fornewandupdate.collection_lat(float): The latitude of the pickup location. Required fornewandupdate.collection_lng(float): The longitude of the pickup location. Required fornewandupdate.destination_address(string): The drop-off address. Required fornewandupdate.destination_lat(float): The latitude of the drop-off location. Required fornewandupdate.destination_lng(float): The longitude of the drop-off location. Required fornewandupdate.pickup_date_time(string): The pickup date and time (format: "YYYY-MM-DD HH:MM:SS"). Required fornewandupdate.notes(string, optional): Movement-level notes.number_of_passenger(int, optional): Per-movement passenger count override.vehicle_type(string, optional): Per-movement vehicle type override.luggage_type(string, optional): Per-movement luggage type override.journey_type(string, optional): Per-movement journey type override.passenger(object, optional): Per-movement passenger details.name(string)email(string)phone_number(string)
Example Request for Edit Complex Quote
{
"number_of_passenger": 4,
"vehicle_type": "Executive",
"luggage_type": "Small luggage",
"journey_type": "Airport Transfer",
"passenger_info": {
"name": "Yui Lau",
"email": "xxx@email.com",
"phone_number": "xxxxxxxxxx"
},
"ext_ref": "123456",
"notes_customers": "customer notes",
"movements": [
{
"op": "update",
"movement_id": 1012,
"journey_order": 1,
"collection_address": "Heathrow Terminal 5, London, TW6 2GA",
"collection_lat": 51.4775,
"collection_lng": -0.4614,
"destination_address": "The Ritz London, 150 Piccadilly, W1J 9BR",
"destination_lat": 51.5067,
"destination_lng": -0.1419,
"pickup_date_time": "2026-07-15 14:30:00",
"notes": "Flight BA456"
},
{
"op": "new",
"journey_order": 2,
"collection_address": "The Ritz London, 150 Piccadilly, W1J 9BR",
"collection_lat": 51.5067,
"collection_lng": -0.1419,
"destination_address": "Gatwick Airport South Terminal, RH6 0NP",
"destination_lat": 51.1537,
"destination_lng": -0.1821,
"pickup_date_time": "2026-07-18 08:00:00",
"notes": "",
"number_of_passenger": 2,
"vehicle_type": "Saloon",
"luggage_type": "No luggage.",
"journey_type": "Birthday",
"passenger": {
"name": "Jane Smith",
"email": "jane.smith@example.com",
"phone_number": "07700900456"
}
},
{
"op": "delete",
"movement_id": 1013
}
]
}
Example Response for Edit Complex Quote
{
"quote_id": 1003787,
"status": 1,
"message": "Quote updated",
"error": false,
"summary": {
"movementsCreated": 1,
"movementsUpdated": 1,
"movementsDeleted": 1,
"journeys": 2
}
}
Required User Permissions
Some endpoints require the authenticated user to hold a specific permission within the system. If the user does not have the required permission, the API will return a 403 Forbidden response. The table below lists the permission required for each endpoint.
| API Name | Endpoint | Method | Required Permission |
|---|---|---|---|
| Get Quote | /api/booking/:quote_id |
GET | viewjobs |
| Edit Quote | /api/booking/request/:quote_id |
PUT | editjobs |
| Edit Complex Quote | /api/booking/edit/:quote_id |
PUT | editjobs |
Error Messages
- Missing required field: Ensure that all required fields are included in your request.
- Vehicle type is required: Please check our booking form for the available vehicle types and include the appropriate type in your request.
- Luggage type is required: Please check our booking form for the available luggage types and include the appropriate type in your request.
- Vehicle size not matching with your journey info: Ensure that the selected vehicle size is appropriate for the number of passengers and luggage specified in your request.




