# Error handling

## Overview

Your integration code should contain error-handling logic to gracefully handle any errors that can occur on a request to
a Connect API endpoint.

There are two main types of errors that your code should deal with:

* The endpoint returns an [HTTP error status code](#http-status-codes) (`4xx` for a client-side error or `5xx` for a
server-side error). In some cases, there will be an accompanying response body providing further details about the
error.
* A [network connection failure](#network-connection-failure) occurs before the client has received a response from the
endpoint—for example, a routing problem, outage, or timeout somewhere in the path between client and server.


## Rate limiting

To maintain the availability and stability of the Connect API endpoints, Booking.com may set a limit on the number of
requests per minute associated with a particular account.

If the limit is reached, requests will get throttled, which manifests as some requests being rejected with an HTTP
code [429](#429---too-many-requests).

### Design your integration to use the API endpoints efficiently

Design your integration flows and endpoint usage to minimize the number of requests you need to make to get just the
data you need. For example:

* If you are using a retry mechanism, ensure it does not negatively affect rate limiting.
* Define your caching strategy to avoid unnecessary requests. Determine what data you should cache, how to cache it, and
how often to refresh the cache. If building or updating the cache will cause a significant rise in the number of
requests, try to spread the load to lower and flatten the resulting spike.
* Where an endpoint supports pagination, optimize the number of results returned on each page.


### Monitor and manage traffic increases

There may be occasions when your integration needs to send significantly more requests than it does normally. Such
increases may occur as a one-off spike, on a regular basis, or as a sustained increase. For example, if you want to
build or update a large cache of static content data, or as a result of natural growth in the usage of your application,
ensure to monitor your traffic usage and investigate the cause of all rate-limiting
errors ([429](#429---too-many-requests)).

## Network connection failure

If the network connection fails before the client has received a response from the endpoint:

* You do not know at what point the request failed, so you must regard its status as indeterminate. The request may have
completed successfully, may have failed while the server was processing it, or may not have been received by the
endpoint.
* You should retry the request using a retry mechanism that incorporates an exponential backoff schedule and a limit on
the number of retries and/or the maximum duration between retries.


Warning
**Do not** retry the request *without* using exponential backoff. If you retry the request with either no delay or with
a simple fixed delay, it may increase the load on the endpoint and worsen the situation.

## Error reporting for compatibility endpoints

Connect API reports errors differently
for [Demand API V2 compatible endpoints](/metasearch/connect-api/open-api/demand-api-v2-compatible)
and [Demand API V3 compatible endpoints](/metasearch/connect-api/open-api/demand-api-v3-compatible). This sections covers these differences.

Attention
Throughout the document, examples are provided in the format of JSON responses for Demand API V3 compatible endpoints.
For Demand API V2 compatible endpoints, ensure to use the error structure as documented in
the [Demand API V2 compatible endpoints](#demand-api-v2-compatible-endpoints) section.

### Demand API V3 compatible endpoints

For the endpoints compatible with Demand API V3, the Connect API performs the following actions:

* Returns an HTTP error status code (`4xx` for client-side errors or `5xx` for server-side errors).
* Only returns a response body with an HTTP `400` code or with certain `5xx` `codes.
* Includes further details about the errors in the response body.


Example:


```json
{
  "request_id": "01gw5aaj8dkh7fvgwa7phs916x",
  "errors": [
    {
      "id": "missing_parameter",
      "name": "Missing Parameter",
      "message": "Parameter 'checkin' is missing."
    }
  ]
}
```

### Demand API V2 compatible endpoints

For endpoints compatible with Demand API V2, the Connect API returns the same errors, but the structure differs to match
Demand API V2 specifications. Instead of `request_id`, it uses `meta.ruid` to uniquely identify the response.

Example:


```json
{
  "meta": {
    "ruid": "0_YN8yQMRgWSkOimr7ggSA"
  },
  "errors": [
    {
      "id": "missing_parameter",
      "name": "Missing Parameter",
      "message": "Parameter 'checkin' is missing."
    }
  ]
}
```

## HTTP status codes

### 200 - OK

The request completed successfully and the response contains the requested data. See the endpoint's entry in
the [API Reference](/metasearch/connect-api/open-api) for details of the response.

### 400 - Bad Request

The request URL or body contains an error. The response body contains details, for example:


```json
{
  "request_id": "01gw5aaj8dkh7fvgwa7phs916x",
  "errors": [
    {
      "id": "missing_parameter",
      "name": "Missing Parameter",
      "message": "Parameter 'checkin' is missing."
    }
  ]
}
```

This response only identifies the first error found when processing the request; it does not mean that this is the only
error present. If there are further errors, the next one will be found and reported when you retry the request.

#### Cause

The `errors`.`id` field in the response identifies the specific client error that has occurred -
see [Client error IDs](#client-error-ids). The `errors.message` field provides more details about the error.

#### Solution

Correct the error in the URL or content and retry the request.

### 401 - Unauthorized

Access to the endpoint is denied because the request is not authorized.
See [Authentication and authorization](/metasearch/connect-api/development-guide/authentication).

#### Cause

The `Authentication` header is missing, or is incorrectly specified.

#### Solution

Ensure to send the valid `Authentication` header in every request.

### 403 - Forbidden

The API account specified in the request lacks permission to access this endpoint or a particular optional function
provided by the endpoint.

Contact your account manager if you require access to this endpoint or function.

### 404 - Not found

The specified endpoint could not be found.

#### Possible causes

* The request URL is incorrect.
* The request URL is correct but the requested endpoint cannot currently be found.


#### Solution

Check and, if necessary, correct the URL to match the [API Specification](/metasearch/connect-api/open-api).

### 405 - Method not allowed

The request uses a wrong HTTP method to call an endpoint.

#### Solution

Correct the request so that it uses the supported HTTP method according to the [API Specification](/metasearch/connect-api/open-api).

### 406 - Not acceptable

The `Accept` header in the request does not specify JSON (or XML in certain cases) as an acceptable format for the
response.

#### Solution

Correct the `Accept` header to include JSON (or XML in certain cases) as an acceptable format. For example:


```
Accept: application/json
```

### 415 - Unsupported media type

The request payload is in an unsupported format.

#### Cause

The `Content-Type` header is missing or does not include JSON as an acceptable format for the request.

#### Solution

Add or correct the `Content-Type` header to specify the format of the request. For example:


```
Content-Type: application/json
```

### 429 - Too many requests

The request cannot be accepted because you have sent too many requests in a given amount of time ("rate limiting").

#### Cause

The account associated with the request has sent too many requests to the Connect
API in a given time period. As a result, some requests can be rejected with a `429`
response. See [Rate limiting](#rate-limiting) for more information.

#### Solution

Retry the request, using a retry mechanism that incorporates an exponential backoff schedule and a limit
on the number of retries (and/or the maximum duration between retries).

Warning
**Do** **not** retry the request *without* using exponential backoff. If you retry the request with either no delay, or
with a simple fixed delay, it is likely to just increase the load on the endpoint and make the situation worse.

### 5xx - Server Error

The server could not fulfill the request due to an encountered problem.

#### Cause

These errors cover all server-side problems that may occur in the Booking.com system. Depending on the
problem, a response body containing more details may or may not be returned.

You do not know at what point the request failed, therefore you must regard its status as indeterminate.

#### Solution

1. If the response contains specific instructions on how to deal with the error, follow those instructions.
2. Otherwise, retry the request using a retry mechanism that incorporates an exponential backoff schedule and a limit on
the number of retries and/or the maximum duration between retries.


Warning
**Do** **not** retry the request *without* using exponential backoff. If you retry the request with either no delay, or
with a simple fixed delay, it is likely to just increase the load on the endpoint and make the situation worse.

## Client error IDs

The following sections provide more detail about the specific error responses that are returned when a request fails
with an [HTTP 400](#400---bad-request) status code.

### conflicting_parameters

The request body contains one of the following problems:

* One or more parameters that cannot be used together in the same request.
**Solution**: Remove the conflicting parameter(s).
* Two parameters that have conflicting values.
**Solution**: Correct the parameter values.


Refer to the endpoint's entry in the [API Reference](/metasearch/connect-api/open-api) for details of the affected
parameters.

**Example 1 - request**: Conflicting parameters


```bash
curl -L -X POST 'https://metasearch-connect-api.booking.com/demand-api-v3-compatible/search'
...
{
  "country": "nl",
  "city": -2140479,
  ...
}
```

**Example 1 - response**:


```json
{
  "request_id": "01gw5m6dfme725bbvcthz0gde0",
  "errors": [
    {
      "id": "conflicting_parameters",
      "name": "Conflicting Parameters",
      "message": "Parameters city and country are mutually exclusive."
    }
  ]
}
```

**Example 2 - request**: When a `page` parameter (field) is used the request must contain no other parameters.


```json
curl -L -X POST 'https://metasearch-connect-api.booking.com/demand-api-v3-compatible/search'
...
{
  "city": -2140479,
  "page": "eyJhbGciOiJIUzI1NiJ9.eyJwIjp7ImNvdW50cnkiOiJ1cyIsImluZGV4IjoiS05LIn0sImF1ZCI6IkNPTU1PTl9MT0NBVElPTlNfQUlSUE9SVFMiLCJleHAiOjE2Nzk1NzIyMTF9.YDh-rCV9wuXtxQGUZG9aZ3G1oYrSjk6TSftWbV2Bbng",
  ...
}
```

**Example 2 - response**:


```json
{
  "request_id": "01gw6zpn448k8vm60wpbqtg8vn",
  "errors": [
    {
      "id": "conflicting_parameters",
      "name": "Conflicting Parameters",
      "message": "Parameter 'page' is exclusive with all other parameters."
    }
  ]
}
```

**Example 3 - request**: Conflicting parameter values


```bash
curl -L -X POST 'https://metasearch-connect-api.booking.com/demand-api-v3-compatible/search'
...
{
  ...,
  "checkin": "2023-08-17",
  "checkout": "2023-08-16",
  ...
}
```

**Example 3 - response**:


```json
{
  "request_id": "01gw57qeem57a92f4z8dgfsc3t",
  "errors": [
    {
      "id": "conflicting_parameters",
      "name": "Conflicting Parameters",
      "message": "Parameters 'checkin' and 'checkout' have conflicting values. The checkout date must be after the checkin date."
    }
  ]
}
```

### invalid_value

The request body contains a parameter (field) with an invalid value. The value may have been defined as the wrong type,
in the wrong format, or may be an invalid enum in an enumerated list.

**Solution**: Correct the parameter value. Refer to the endpoint's entry in
the [API Reference](/metasearch/connect-api/open-api) for details of the parameter.

**Example 1 - request**: Parameter with the wrong type - an integer defined as a string.


```json
curl -L -X POST 'https://metasearch-connect-api.booking.com/demand-api-v3-compatible/search'
...{
  ...
  "guests": {
    "number_of_rooms": "3",
    "number_of_adults": 5,
    "children": [
      2,
      3,
      13,
      15
    ]
  },
  ...
}
```

**Example 1 - response**:


```json
{
  "request_id": "01gw5app387wfyk17nz74hy0vs",
  "errors": [
    {
      "id": "invalid_value",
      "name": "Invalid Value",
      "message": "Parameter 'guests.number_of_rooms' is invalid. Expected: integer. Actual: string."
    }
  ]
}
```

**Example 2 - request**: Parameter with an invalid format for the `checkin` date


```json
curl -L -X POST 'https://metasearch-connect-api.booking.com/demand-api-v3-compatible/search'
...
{
  ...,
  "checkin": "23-08-15",
  "checkout": "2023-08-16",
  ...
}
```

**Example 2 - response**:


```json
{
  "request_id": "01gw7p7mp43dccs5zje3gezwkc",
  "errors": [
    {
      "id": "invalid_value",
      "name": "Invalid Value",
      "message": "Parameter 'checkin' is invalid."
    }
  ]
}
```

**Example 3 - request**: Invalid enum (`rooms`) in an enumerated list


```json
curl -L -X POST 'https://metasearch-connect-api.booking.com/demand-api-v3-compatible/search'
...
{
  ...,
  "extras": [
    "products",
    "rooms"
  ],
  ...
}
```

**Example 3 - response**:


```json
{
  "request_id": "01gw5btwz6k3b6ajprx36hm6d4",
  "errors": [
    {
      "id": "invalid_value",
      "name": "Invalid Value",
      "message": "Parameter 'extras[1]' is invalid."
    }
  ]
}
```

### malformed_request

The request body contains one or more syntax errors, making the JSON object invalid.

**Solution**: Correct and validate the JSON syntax.

**Example request**: A comma is missing after `"AMS"`. The comma is needed to separate the `airport` and `languages`
objects.


```json
{
  "airport": "AMS"
  "languages": [
    "en-gb",
    "zh-cn"
  ]
}
```

**Example response**:


```json
{
  "request_id": "01gw4zdfk13cbvbb1ktr679pbg",
  "errors": [
    {
      "id": "malformed_request",
      "name": "Malformed Request",
      "message": "Unexpected character ('\"' (code 34)): was expecting comma to separate Object entries."
    }
  ]
}
```

### missing_parameter

The request body does not contain a parameter (field) that is required. This may be:

* a specific, named parameter.
* one of the parameters from a mutually exclusive set.


**Solution**: Add the required parameter. Refer to the endpoint's entry in
the [API Reference](/metasearch/connect-api/open-api) for details of the parameters.

**Example 1 - response**: Request has left out a specific parameter


```json
{
  "request_id": "01gw5aaj8dkh7fvgwa7phs916x",
  "errors": [
    {
      "id": "missing_parameter",
      "name": "Missing Parameter",
      "message": "Parameter 'checkin' is missing."
    }
  ]
}
```

**Example 2 - response**: Request has left out a parameter from a mutually exclusive set


```json
{
  "request_id": "01gw59jvtytrkn653tzq0nggcq",
  "errors": [
    {
      "id": "missing_parameter",
      "name": "Missing Parameter",
      "message": "One of the parameters in the list '[accommodations, airport, city, coordinates, country, district, landmark, region]' is missing."
    }
  ]
}
```

### unknown_parameter

The request body contains a parameter (field) name that does not match any parameter name in the endpoint's request body
schema.

**Solution**: Correct the parameter name. Refer to the endpoint's entry in
the [API Reference](/metasearch/connect-api/open-api) for details of the parameter.

**Example response**:


```json
{
  "request_id": "01gw5ahxqve7gsd7k62ps3bswv",
  "errors": [
    {
      "id": "unknown_parameter",
      "name": "Unknown Parameter",
      "message": "Parameter 'accommodation' does not exist."
    }
  ]
}
```