Last updated

Error handling

Overview

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

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

  • The endpoint returns an HTTP error status code (4xx for a client-side error or 5xx for a server-side error). In some cases, there will be an accompanying response body continuing further details about the error.
  • A 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 Demand API endpoints, Booking.com may set a limit on the number of requests a particular partner account may send, per minute, to any of the Version 3 Demand API endpoints. (Contact your Account Manager for information about your partner account's rate limit.)

When any API user associated with the partner account sends a request to any Version 3 Demand API endpoint, the request counts towards this limit for the partner account.

If the limit is reached, access to the Demand API is temporarily blocked for the partner's API users, for a duration of 1 minute. While access is blocked, any request from an API user associated with the blocked partner account is rejected with a 429 response.

At the end of the minute, access is restored. The count of received requests is reset to zero and requests from all of the partner's API users are accepted again.

Design your integration to use the API endpoints efficiently

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

  • 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.

  • Use filters and (if provided) the extras field to optimise the data returned by each request, so that you get just the data you need. For an example of how you can do this for /accommodations/search requests, see Search for available properties.

  • Where a request supports pagination, use the rows field to optimize the number of results returned on each page.

Monitor and manage traffic increases

Booking.com sets rate limits to protect the availability of the Demand API endpoints, whilst allowing integrations to function normally with their intended, normal levels of traffic.

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 usage of your application.

Monitor your traffic usage and investigate the cause of all rate-limiting errors (429).

If you know that you will need to significantly increase the number of requests you make (by a factor of 2 or more), contact Booking.com as early as possible with details of your requirement.

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, it may have failed while the server was processing it, or it 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.

    If the request is still failing when the limit is reached, stop retrying and contact Booking.com for assistance.

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 make the situation worse.

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 for details of the response.


400 - Bad request

The request URL or body contains an error. The response body contains more information - for example:

{
   "request_id": "01gw5aaj8dkh7fvgwa7phs916x",
   "errors": [
       {
           "id": "missing_parameter",
           "code": 10003,
           "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. The errors.message field provides more details about the error.

Attention

The errors.id field replaces the errors.code and errors.name fields, which were previously used to identify the specific client error that has occurred. The errors.code and errors.name fields are still also returned, but are now deprecated. Both fields will be removed in a later release. You should migrate any error handling logic in your code that uses these fields to use errors.id instead.

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


401 - Unauthorized

Access to the endpoint is denied because the request does not identify a valid API user. See Authentication and authorisation.

Possible causes:

  • The Authentication header is missing, or is incorrectly specified, or is using an invalid API key - for example, one that has been revoked.

  • The X-Affiliate_id header is missing, or is incorrectly specified, or is using an invalid affiliate id.

Solution: Correct the Authentication and/or X-Affiliate_id headers and retry the request.


403 - Forbidden

The request does not have permission to access the endpoint.

The API user identified in the request does not have permission to access this endpoint. See Authentication and authorisation.

Possible causes:

  • The request is using the wrong affiliate id.

    Solution: Correct the request's X-Affiliate_id header to specify an API user that does have permission to use this endpoint. Then retry the request.

  • The API user is not configured correctly, or you need to give this API user permission to use this endpoint.

    Solution: Contact Booking.com and request access to the endpoint for this API user.


404 - Not found

The specified endpoint could not be found.

Possible causes:

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

Solution: Check and, if necessary, correct the URL. (See the endpoint's entry in the API Reference for details.) Then retry the request.


405 - Method not allowed

The request uses a method other than POST. You must use POST to call any Version 3.x Demand API endpoint. All other methods are not supported.

Solution:

Correct the request so that it uses the POST method, with appropriate content in the request body. (See the endpoint's entry in the API Reference for details.) Then retry the request.


406 - Not acceptable

The Accept header in the request does not include JSON as an acceptable format for the response. All Demand API endpoints return JSON responses.

Solution: Correct the Accept header to include JSON as an acceptable format (for example: Accept: */* or Accept: application/json). Then retry the request.


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: Correct the Content-Type header to include JSON as an acceptable format (for example: Content-Type: application/json). Then retry the request.


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 partner account associated with the API user making this call has sent too many requests to the Demand API in a given time period. As a result, all requests from this API user are currently being rejected with a 429 response. See 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).

If the request is still failing when the limit is reached, stop retrying and Contact Booking.com for assistance.

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 fulfil the request because it encountered a 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, so 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).

    If the request is still failing when the limit is reached, stop retrying and Contact Booking.com for assistance.

    CAUTION! - 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 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 for details of the affected parameters.

Example 1 - request: Conflicting parameters

curl -L -X POST 'https://demandapi-sandbox.booking.com/3.1/accommodations/search'
...
{
  "country": "nl",
  "city": -2140479,
  ...
}

Example 1 - response:

{
   "request_id": "01gw5m6dfme725bbvcthz0gde0",
   "errors": [
       {
           "id": "conflicting_parameters",
           "code": 10008,
           "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.

curl -L -X POST 'https://demandapi-sandbox.booking.com/3.1/accommodations/search'
...
{
  "city": -2140479,
  "page": "eyJhbGciOiJIUzI1NiJ9.eyJwIjp7ImNvdW50cnkiOiJ1cyIsImluZGV4IjoiS05LIn0sImF1ZCI6IkNPTU1PTl9MT0NBVElPTlNfQUlSUE9SVFMiLCJleHAiOjE2Nzk1NzIyMTF9.YDh-rCV9wuXtxQGUZG9aZ3G1oYrSjk6TSftWbV2Bbng",
  ...
}

Example 2 - response:

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

Example 3 - request: Conflicting parameter values

curl -L -X POST 'https://demandapi-sandbox.booking.com/3.1/accommodations/search'
...
{
  ...,
  "checkin": "2023-08-17",
  "checkout": "2023-08-16",
  ...
}

Example 3 - response:

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

Expired_token

The request body contains a pagination token that is not valid, because it has expired. This means that you cannot get any further pages of results for this request.

A pagination token expires 1 hour after it was generated.

Solution:

  1. Repeat your original call to the endpoint to get the first page of results. The response includes a new pagination token (in the next_page field) which you must use to get the next page.

  2. Within 1 hour, call the endpoint again to get the next page of results. Use the new pagination token from the previous response as the only parameter in the request (in the page field).

    If the response contains a next_page field, there are more results available. If there is no next_page field, you have reached the end of the results.

  3. Repeat step 2 until you have received all of the available results.

Example response:

{
   "request_id": "01gw74d6yddk07fa11g4psnfrb",
   "errors": [
       {
           "id": "expired_token",
           "code": 10102,
           "name": "Expired Token",
           "message": "Token 'page' has expired."
       }
   ]
}

Invalid_request

The request is invalid because of one of the following problems:

  • The request includes a request body but this endpoint does not use a request body.

    Solution: Remove the request body.

  • The request does not include a request body but this endpoint requires one.

    Solution: Include a request body with the required content. Refer to the endpoint's entry in the API Reference for details.

  • The request URL contains one or more query parameters in the request URL. Version 3 Demand API endpoints do not accept query parameters. You must pass all parameters as fields in the request body.

    Solution: Remove the query parameters. Check the endpoint's entry in the API Reference to see if and how you need to pass the data specified in the removed query parameters.

Example request: URL contains a query string, ?affiliate_id=123.

curl -L -X POST 'https://demandapi-sandbox.booking.com/3.1/accommodations/availability?affiliate_id=123'
...

Example response:

{
   "request_id": "01gw4mwegd1pbb66xbh0whtkaw",
   "errors": [
       {
           "id": "invalid_request",
           "code": 10002,
           "name": "Invalid Request",
           "message": "Query string provided but none expected."
       }
   ]
}

Invalid_token

The request body contains an invalid pagination token. The value sent does not match any generated token value.

Solution: Correct the token value. Make sure that it is exactly the same as the one returned in the next_page field in the previous response.

Example response:

{
   "request_id": "01gw6zzmcrnnjcaqzt95a1t171",
   "errors": [
       {
           "id": "invalid_token",
           "code": 10101,
           "name": "Invalid Token",
           "message": "Token 'page' is invalid."
       }
   ]
}

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 for details of the parameter.

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

curl -L -X POST 'https://demandapi-sandbox.booking.com/3.1/accommodations/search'
...{
  ...
  "guests": {
      "number_of_rooms": "3",
      "number_of_adults": 5,
      "children": [2,3,13,15]
      },
  ...
}

Example 1 - response:

{
   "request_id": "01gw5app387wfyk17nz74hy0vs",
   "errors": [
       {
           "id": "invalid_value",
           "code": 10007,
           "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

curl -L -X POST 'https://demandapi-sandbox.booking.com/3.1/accommodations/search'
...
{
  ...,
  "checkin": "23-08-15",
  "checkout": "2023-08-16",
  ...
}

Example 2 - response:

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

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

curl -L -X POST 'https://demandapi-sandbox.booking.com/3.1/accommodations/search'
...
{
  ...,
  "extras": ["products","rooms"],
  ...
}

Example 3 - response:

{
   "request_id": "01gw5btwz6k3b6ajprx36hm6d4",
   "errors": [
       {
           "id": "invalid_value",
           "code": 10007,
           "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.

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

Example response:

{
   "request_id": "01gw4zdfk13cbvbb1ktr679pbg",
   "errors": [
       {
           "id": "malformed_request",
           "code": 10001,
           "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 for details of the parameters.

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

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

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

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

Token_endpoint_mismatch

The request body contains a pagination token that is not valid, because it was generated by a different endpoint. A pagination token can only be used in a call to the same endpoint that generated it.

For example, a pagination token generated by the /accommodations/cities endpoint cannot be used in a call to the /accommodations/countries endpoint.

Solution: Replace the invalid pagination token with the one returned in the response to your last call to this endpoint.

If the correct pagination token is not available:

  1. Repeat your original call to the endpoint to get the first page of results. The response includes a new pagination token (in the next_page field) which you must use to get the next page.

  2. Within 1 hour, call the endpoint again to get the next page of results. Use the new pagination token from the previous response as the only parameter in the request (in the page field).

    If the response contains a next_page field, there are more results available. If there is no next_page field, you have reached the end of the results.

  3. Repeat step 2 until you have received all of the available results.

Example response:

{
   "request_id": "01gw6zjf8n3kvw68jt39g8kcxp",
   "errors": [
       {
           "id": "token_endpoint_mismatch",
           "code": 10103,
           "name": "Token-endpoint Mismatch",
           "message": "Token 'page' cannot be used in this endpoint."
       }
   ]
}

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 for details of the parameter.

Example response:

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