Connect your application to Booking.com's dedicated endpoint, discover the tools available to your account, and call them through the Model Context Protocol (MCP).
Follow these steps:
- Configure the endpoint and authentication headers.
- Initialise an MCP client and negotiate the protocol version.
- Discover the available tools and inspect their schemas.
- Call a tool with validated arguments.
- Handle results and errors.
The server uses MCP over Streamable HTTP with JSON-RPC 2.0 messages.
The endpoint is stateless. Requests do not require a persistent server-side MCP session, but your client must still complete the MCP initialisation and protocol version negotiation sequence before calling tools.
The tools and other MCP capabilities available to your application depend on your affiliate configuration.
Every request to the endpoint must include your affiliate ID and Demand API key.
- The MCP application validates the key without checking an IP allowlist for the requests.
- Network access restrictions outside the application are separate; confirm the endpoint access during onboarding.
Obtain or confirm these credentials with your Account Manager during the onboarding process:
- Affiliate ID – Identifies your Booking.com partner account and attributes requests to it.
- Demand API key – Authenticates your requests. Keep it out of version control, logs, screenshots and support messages.
Send MCP requests to:
POST https://demandapi-mcp.booking.com/v1/sp/mcp/- Keep the trailing slash.
- Send your affiliate ID in a header; do not append it to the URL.
- Use
POSTfor MCP operations.GETandDELETEare not supported by this stateless endpoint and return405 Method Not Allowed.
The separate /v1/mcp/:affiliateId endpoint is for AI Platform Partner integrations. Use the MCP dedicated endpoint for the instructions in this guide.
Send exactly one value for each partner header with every request, including initialisation and tool discovery:
x-booking-affiliate-id: <your-affiliate-id>
x-booking-authorization: <your-demand-api-key>x-booking-affiliate-idmust contain only digits. Keep it as a string, including any leading zeroes.x-booking-authorizationmust contain your issued Demand API key unchanged. Do not add aBearerprefix.- An
Authorization: Bearer ...header is not a substitute for these headers.
For JSON-RPC POST requests, also send these transport headers. MCP clients normally set them for you:
Content-Type: application/json
Accept: application/json, text/event-streamMissing or invalid partner headers and failed API key validation return HTTP 401 Unauthorized with this JSON-RPC error:
{
"jsonrpc": "2.0",
"error": { "code": -32001, "message": "Unauthorized" },
"id": null
}If authentication continues to fail after you have checked both headers, contact your Booking.com support representative. Do not include your Demand API key in the support request.
Use an MCP SDK to manage the MCP transport, initialisation and protocol version negotiation.
Before calling tools/list or tools/call, your client must:
- Send an
initializerequest. - Negotiate a supported MCP protocol version.
- Send the
notifications/initializednotification. - Include the negotiated protocol version in subsequent HTTP requests, as required by the MCP transport.
MCP SDKs and compatible clients normally handle this sequence automatically.
A simplified initialize request has the following structure:
{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "<supported-protocol-version>",
"capabilities": {},
"clientInfo": {
"name": "example-client",
"version": "1.0.0"
}
}
}The request must be sent as an HTTP POST to the MCP endpoint with the required authentication and transport headers.
For development and debugging, MCP Inspector lets you connect, inspect tool schemas, and test calls without building a client first. Its user interface and CLI require Node.js, npm, and npx.
To open the Inspector user interface:
npx @modelcontextprotocol/inspectorSelect Streamable HTTP, enter:
https://demandapi-mcp.booking.com/v1/sp/mcp/
Add both required partner headers before connecting. Inspector shows the tools and schemas exposed to your account.
The CLI examples below use environment variables. Set:
BOOKING_AFFILIATE_IDBOOKING_DEMAND_API_KEY
using your approved credential-management method.
Do not paste real keys into shared scripts or shell history. These CLI commands expand the key into a process argument. Run them on a trusted machine and do not share process listings containing the key.
Call tools/list to retrieve the tool names and input schemas available to your account. Always use this response as the source of truth for tool names, arguments and validation rules.
npx @modelcontextprotocol/inspector --cli \
https://demandapi-mcp.booking.com/v1/sp/mcp/ \
--transport http \
--method tools/list \
--header "x-booking-affiliate-id: ${BOOKING_AFFILIATE_ID}" \
--header "x-booking-authorization: ${BOOKING_DEMAND_API_KEY}"The following tool names are examples only. The tools available to your account may differ and can change over time. The response from tools/list is authoritative:
accommodations_searchaccommodations_room_searchattractions_searchcars_searchflights_searchanswer_property_qa_by_ids_v2.
If the response includes nextCursor, call tools/list again with that cursor until no cursor is returned. Do not assume that one response contains every available tool.
If the list is empty or an expected tool is missing, confirm the capabilities enabled for your affiliate account with your Account Manager.
Each tool's inputSchema describes its arguments, types, required fields, and constraints.
When a tool provides an outputSchema, use it to validate and process its structuredContent. If structuredContent is not present, handle the returned content blocks instead.
Inspect these schemas directly from tools/list. There is no separate schema-retrieval step.
Choose a tool from the discovery response and invoke it with tools/call.
A tool call has the following JSON-RPC structure:
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "<tool-name>",
"arguments": {
"<argument-name>": "<value>"
}
}
}Validate the
argumentsagainst the tool's currentinputSchemabefore sending the request.In Inspector CLI, pass the exact tool name with
--tool-nameand its arguments with--tool-arg. Start with a minimal valid request, then add optional parameters.
Use this example if your account exposes accommodations_search with the fields shown below.
Otherwise, adapt the name and arguments to the current schema returned by tools/list.
Set CHECKIN_DATE and CHECKOUT_DATE to future dates in YYYY-MM-DD format, with checkout after check-in.
This request searches for two adults and one room in Paris, using gb as the user country code and GBP as the currency.
npx @modelcontextprotocol/inspector --cli \
https://demandapi-mcp.booking.com/v1/sp/mcp/ \
--transport http \
--method tools/call \
--tool-name accommodations_search \
--header "x-booking-affiliate-id: ${BOOKING_AFFILIATE_ID}" \
--header "x-booking-authorization: ${BOOKING_DEMAND_API_KEY}" \
--tool-arg 'destination=Paris' \
--tool-arg "checkin_date=${CHECKIN_DATE}" \
--tool-arg "checkout_date=${CHECKOUT_DATE}" \
--tool-arg 'number_of_adults=2' \
--tool-arg 'number_of_rooms=1' \
--tool-arg 'user_country_code=gb' \
--tool-arg 'user_locale=en-GB' \
--tool-arg 'currency=GBP'Check both the HTTP response and the MCP message. An HTTP success status alone does not mean that a tool call succeeded.
| Check | Meaning | What to do |
|---|---|---|
| HTTP error status | The HTTP request was rejected or could not be processed, for example because of authentication, rate limiting or a server error. | Read the response body and use the troubleshooting table. |
Top-level JSON-RPC error | The MCP request failed instead of returning a result. | Inspect error.code and error.message. Correct the request or handle the reported failure. |
result.isError: true | The tool call reported a failure. | Read the content blocks and follow the tool's recovery guidance. Do not assume that structuredContent is present. |
| Successful tool result | The tool call returned successfully. | Process structuredContent when present, using the tool's outputSchema. Otherwise, process the returned content blocks. |
contentcontains MCP content blocks, such as text, images, resource links or embedded resources. It can be empty, and text blocks are not always JSON._metamay contain additional metadata. Do not rely on fields in_metaunless they are documented for the specific tool.
For the current accommodations_search implementation, a search with no matching accommodations is returned as a tool execution error.
Its text content contains a JSON error payload rather than a successful result with an empty accommodations array.
The following shows the text payload decoded for readability, not the outer JSON-RPC response:
{
"type": "not_found",
"message": "No accommodations found for the given search parameters in Booking.com inventory",
"details": [],
"suggestedAction": "Ask the user to change the search parameters",
"retryGuidance": "Suggest possible changes users can apply: different check-in and check-out dates, nearby regions to the destination, relaxing specific facility requirements, etc. Do not change any parameters yourself, only change based on user feedback. If user gives the same exact parameters like the previous request, do not send the same request again. In that case, refer the user to the previous search results."
}- Surface the suggested action and retry guidance to the calling application or assistant.
- Do not silently relax the traveller's criteria or repeat the same request without a change.
| Status | Cause | Resolution |
|---|---|---|
400 Bad Request | The server rejected the HTTP or JSON-RPC request format, for example because of malformed JSON or invalid transport headers. | Read the response error and check the JSON-RPC message and transport headers. |
401 Unauthorized | Partner headers are missing or invalid, the Demand API key failed validation, or the authentication service is unavailable. | Check both x-booking-* headers, the digit-only affiliate ID and the unchanged Demand API key. If valid credentials still fail, contact support. |
403 Forbidden | The credentials are valid, but the affiliate account is not enabled for the Demand partner endpoint. | Confirm that the affiliate account has been enabled during onboarding. |
404 Not Found | The endpoint path is incorrect. | Use /v1/sp/mcp/, including the trailing slash and without an affiliate ID suffix. |
405 Method Not Allowed | An unsupported HTTP method was used. | Use POST for MCP operations. |
429 Too Many Requests | The rate limit was exceeded. | Retry according to the guidance in Rate limiting. |
5xx Server Error | A temporary server or dependency failure occurred. | Retry transient failures with bounded backoff. If the problem persists, contact support and include the request ID if one is available. Do not include credentials. |
After a 429 response, retry with exponential backoff and jitter. Respect any Retry-After value and apply a maximum retry count.
Do not retry 400, 401, 403, 404 or 405 responses unless you correct the request.
A search with no results is not a rate-limit failure. Surface the returned guidance and ask the traveller or calling application whether the search criteria should change.
✅ Validate tool arguments against the current inputSchema returned by tools/list.
✅ Validate structuredContent against the tool's outputSchema when an output schema is provided.
✅ Handle content-only responses and tool execution errors.
✅ Implement timeouts for MCP requests.
✅ Handle 429 responses with bounded exponential backoff, jitter and Retry-After support.
✅ Test authentication, disabled affiliates, missing tools, invalid arguments, tool errors and rate limiting as separate cases.
✅ Log enough request context to diagnose failures, but exclude API keys, authentication headers and other credentials.
✅ If your application uses an LLM, show users when tools are available and when they are invoked. Keep the user in control of sensitive operations.
✅ Monitor schema changes and revalidate your integration when the available tools or their schemas change.