How to use Karhoo APIs

📘

Detailed information and examples of how to use Karhoo's APIs can be found in the Karhoo API Explorer.

📘

Karhoo's API design follows RESTful standards which will be familiar to developers accustomed to working with modern web APIs.

The Karhoo APIs follow consistent patterns for usage:

Requests

HTTP Headers

Valid API requests provide the following two HTTP header fields with each request:

  • Content-Type
  • Authorization

Content-Type: application/json

The API consumes and produces JSON. This means that you should always set the Content-Type header to application/json to ensure that your requests are properly accepted and processed by the API.

Authorization; bearer {token}

Karhoo API calls are authenticated using an Access Token. This token is a string of random characters generated by the server in response to a Request. Refer to Auth for details on working with these tokens.

Responses

Karhoo APIs responses are in JSON format and include

HTTP Status Codes

All RESTful API calls return a valid HTTP status code.

Status Code

Description

200

OK. Everything worked as expected.

201

Created. We will return a 201 after a successful POST where a resource was created.

302

Retry request on given redirect URI.

400

Malformed request.

401

Unauthorised. The request requires user authentication (not logged in).

403

Forbidden. Used for unauthorised requests where your permissions restrict the request.
or
User not allowed. User is banned and is not permitted to request a ride.

404

Resource not found.

406

Unacceptable content type. Client sent an accepts header for a content type which does not exist on the server. Body includes a list of acceptable content types, such as “Unacceptable content type. Request resource as: application/json.

409

A conflict needs to be resolved before the request can be made.

422

Invalid request. The request body is parse-able however with invalid content or there are issues with a rider’s user account.

429

Too Many Requests. Exceeded the rate limit for requests.

500

Internal Server Error. Something has gone wrong on the website’s server, but the server could not be more specific on what the exact problem is.

503

The service is not available.

Errors

Rich errors are returned for API-specific errors. See Interpreting errors for more details

Rate limiting

The APIs enforce rate limits. These limits are specific to each endpoint. If usage exceeds the rate limit for a given endpoint, requests will receive a response with an HTTP Status Code of 429. You will continue to receive these responses until your rate of requests has dropped below the acceptable threshold for that endpoint.

Localization

Timezones

All timezones in the API are expressed in UTC and it is the responsibility of the client to localize.

Currency

The API does not explicitly define a currency. However, each fleet may quote in a different currency for a geological area. So, when requesting a quote you should allow for a quote list with multiple currency units . These will be provided in standard ISO 4217 format (e.g. USD, GBP or JPY). For instance you may get quotes from fleets from different countries who quote for the same trip with their own currencies (especially if the journey crosses a national border).

Pagination

Some API requests may return bulk results (like getting a listing of an organisation’s bookings). These bulk fetches will be sorted in reverse chronological order with the most recent data first. They share two common parameters which allow you to cursor through the data:

Paramter

Function

pagination_offset

Starting row for the results

pagination_row_count

Number or records to return in one go. Large requests have a greater chance of timing out. The default and maximum value is set to 1000

Example

Calling a paginated API endpoint with these parameters would return records 201-400.

{
  pagination_offset: 200,
  pagination_row_count: 200
}

Note

If you are paginating through results, making consecutive calls, you should make allowances for duplicate rows. This is because the records are returned with the most recent data at the top. If new records are added to the database whilst you requesting the data set, because of the time lapse between two requests, you will see overlapping result sets. So, in the example above which returns records 201-400, if a new record was added (it becomes row 0), and resending the same API request means the returned data would be shunted down by 1 row. Row 201 would be row 202, row 201 would be row 202, and so on. The previous row 400 would no longer be returned in that request but you will see it on the subsequent request for a pagination_offset of 400.