Getting started

Between the Karhoo Platform and DMS's are two distinct types of API endpoints:

  • Karhoo endpoints
    These are hosted by Karhoo and used by DMS's to push asynchronous updates to Karhoo.
  • DMS endpoints
    These are hosted by the Supply Partner for Karhoo to use to request vehicle availability, quotes and bookings.

Security

Authentication is handled differently for these two classes of endpoints.

Karhoo Hosted Endpoints

Endpoints hosted by karhoo are authenticated using the same mechanism as all Karhoo Platform APIs. See How to authenticate for details.

DMS Hosted Endpoints

For DMS endpoints Karhoo signs requests using a HMAC. The HMAC signature digest is computed on the payload content using the supplied secret key (Please contact us if you have not been provided a secret key). This SHA256 hash is sent as lowercase hexits in the x-karhoo-request-signature header and should be used to validate all requests from Karhoo.

🚧

Always check each request

It is important to verify each request body to avoid man-in-the-middle attacks or fake requests.

❗️

You must hash the entire request body

Failing to account for linefeed (LF) or new line (NL) characters when comparing hash signatures will result in a failed cryptographic check.

The following is copied from a golang playground example of how we would sign our X-Karhoo-Request-Signature header with the shared secret we will provide to you.

package main

import (
	"crypto/hmac"
	"crypto/sha256" //not to be confused with SHA512
	"encoding/hex"
	"fmt"
)

// Please do not set your key to this example in production
const (
	signature         string = "d8774cdffbf5aa103ebacecc4f99ca3f823df2397745ec72a67021ce17b74667"
	exampleSecretKey  string = "EAlOTQ1IHwansbPn0cUOPyQYrONmuOAu"
	sampleRequestBody string = `{"date_scheduled":"2024-01-10T03:05:00+01:00","external_info":{"fleet_id":"external_fleet_id"},"origin":{"address":{"country_code":"FR","city":"Paris","display_address":"Eiffel Tower, Champ de Mars, 5 Av. Anatole France, 75007 Paris, France","postal_code":"75007","region":"Île-de-France","building_number":"5","street_name":"Avenue Anatole France"},"details":{},"google_place_id":"o_W5013364","position":{"latitude":48.8583701,"longitude":2.2944813}},"destination":{"address":{"country_code":"FR","city":"Paris","display_address":"Louvre Museum, 75001 Paris, France","postal_code":"75001","region":"Île-de-France","street_name":"Passage de la Cour des Fontaines"},"details":{},"google_place_id":"o_R3262297","position":{"latitude":48.8606111,"longitude":2.337644}}}`
)

// HashRequestBody represents a function similiar to how we sign our signature
func HashRequestBody(body []byte, secretKey []byte) (string, error) {
	mac := hmac.New(sha256.New, secretKey)
	_, err := mac.Write(body)
	if err != nil {
		return "", err
	}

	return hex.EncodeToString(mac.Sum(nil)), nil
}

func main() {
	// we need to generate our own hash to compare against the signature
	hash, err := HashRequestBody([]byte(sampleRequestBody), []byte(exampleSecretKey))
	if err != nil {
		panic(err)
	}

	// will print true if the signature matches the hash we computed and our data is secure.
	fmt.Println(signature == hash)

}

Contact the Karhoo team for help with the above.

API endpoints

DMS API Endpoints

The minimum set of DMS Hosted APIs are Quotes , Booking, Trip Updates and Cancellation. These are implemented as webhooks within your platform.

📘

Availability and ETA are optional

These are only used when ETA is not included in your Quotes endpoint implementation and you would like to offer On Demand ASAP bookings.

NamePurposeLocationAPI Reference
Receive New TripsDMS hosted API endpoint for receiving Karhoo trip bookingsPOST /tripReceive New Trips
Provide Trip DetailsDMS Hosted endpoint to respond to Karhoo Trip Detail requestsGET /tripProvide Trip Details
Cancel TripDMS Hosted endpoint to respond to Karhoo Trip Cancellation requestsDELETE /tripCancel Trip
Quote RequestDMS hosted API endpoint for responding to quote requestsPOST /quoteQuote Request
ETA RequestDMS hosted API endpoint for responding to ETA requestsPOST /etaETA Request
Availability RequestKarhoo Availability Request to DMSPOST /availabilityAvailability

Karhoo hosted endpoints

Our Supply API provides an option for our supply partners to push Trip Updates to us directly instead of us requesting this data from their DMS API. This is optional but highly recommended to implement to reduce our polling rate and burden it may cause for your API.

NamePurposeLocationAPI Reference
AvailabilityStream fleet wide vehicle availability to KarhooPOST /availabilityAvailability
Trip StatusSend trip updates to Karhoo in real-time.POST /trip/statusTrip Status

Swagger Spec & Auto Generation

We've made the swagger spec available here which that defines our hosted endpoints as well as what we expect our Supply Partners to implement as webhooks.

We encourage you to use this to autogenerate as much boilerplate as is useful to reduce the workload of writing the integration.


What’s Next