API-documentatie
Volledige referentie voor de LockTrip Hotel Booking MCP API. 15 tools voor zoeken, boeken, betalen en beheer.
Integrating a backend service? The same product is available as a native GraphQL API with credit line billing for B2B partners. See the GraphQL B2B docs →
Authenticatie
De API gebruikt Bearer JWT tokens. Zoek- en browse-tools vereisen geen authenticatie. Boekings- en beheertools vereisen een geldig token.
Een Token Verkrijgen
Gebruik guest_login (alleen e-mail, direct) of login (e-mail + wachtwoord) om een JWT token te verkrijgen.
Het Token Gebruiken
Authorization: Bearer eyJhbGciOiJIUzUxMiJ9...
OAuth 2.1 (MCP-clients)
MCP-clients (bijvoorbeeld Claude, ChatGPT) authenticeren automatisch via OAuth 2.1 met PKCE — u configureert dit niet zelf. Bij een 401 ontdekt de client de server op https://locktrip.com/.well-known/oauth-authorization-server, registreert zich dynamisch (POST /register) en doorloopt vervolgens de authorization-code-flow: /authorize (toestemming van de gebruiker, beveiligd met Cloudflare Turnstile) → /token. Scopes: "mcp" (plus "offline_access" voor een refresh token). Gebruik voor directe REST-/curl-integratie in plaats daarvan een handmatig Bearer token (zie hierboven).
Per-call auth: sessionToken
Voor directe REST- of JSON-RPC-aanroepen accepteren geauthenticeerde tools ook een sessionToken-argument als alternatief voor de Authorization-header. Een guest_login-token (alleen e-mail — geen wachtwoord, direct) maakt een GAST-sessie, en een GAST-sessie werkt UITSLUITEND met prepare_booking en create_checkout. get_payment_url, list_bookings, get_booking_details, cancel_booking en confirm_booking vereisen allemaal een geregistreerd account — haal dat token op met login (e-mail + wachtwoord). Een B2B-partner met een kredietlijn moet zich authenticeren met login, nooit met guest_login: een gastsessie heeft geen kredietlijn, dus confirm_booking wijst hem af. Geeft een aanroep AUTH_INSUFFICIENT_ROLE (HTTP 403), dan is het token geldig en klopt alleen de rol niet — schakel over naar login in plaats van nog een guest_login-token aan te vragen.
Toolclassificatie
| Publiek (geen auth) | Geauthenticeerd (Bearer token) |
|---|---|
| search_location, hotel_search, get_search_results, get_hotel_rooms, get_hotel_details, check_cancellation_policy, login, guest_login | prepare_booking, confirm_booking, create_checkout, get_payment_url, list_bookings, get_booking_details, cancel_booking |
Basis-URL & Transporten
Alle endpoints worden geserveerd vanaf https://locktrip.com/mcp/. Drie transportmodi worden ondersteund:
| Transport | Methode | Endpoint |
|---|---|---|
| REST | POST | https://locktrip.com/mcp/tools/{tool_name} |
| MCP Streamable HTTP | POST | https://locktrip.com/mcp/rpc |
| MCP Streamable HTTP (alias) | POST | https://locktrip.com/mcp/sse |
Discovery Endpoints
| URL | Beschrijving |
|---|---|
| GET /mcp/openapi.json | OpenAPI 3.1 specificatie |
| GET /mcp/tools | Alle tools met schema's weergeven |
| GET /mcp/discovery | MCP discovery-document |
Content-Type: application/json voor alle POST-verzoeken.
Foutafhandeling
REST-fouten
| Status | Betekenis |
|---|---|
| 200 | Succes |
| 400 | Validatiefout (ongeldige invoer) |
| 401 | Ontbrekend of ongeldig Bearer token |
| 403 | Geauthenticeerd, maar deze sessie mist de vereiste rol - gebruik login, niet guest_login |
| 404 | Onbekende toolnaam |
| 429 | Limiet overschreden |
The error envelope — read recoverable, not the message
Every classified error carries the same envelope. mcpCode is the stable machine-readable class — branch on it, never on the message text. recoverable is behavioural guidance and the field an autonomous agent should act on: true means the caller can fix the request and retry (bad input, expired search session, rate limit); false means retrying the same call is futile — change something first. A recoverable: false with AUTH_INSUFFICIENT_ROLE specifically means your token is valid but its role is wrong: switch to login, and do NOT fetch another guest_login token.
// REST — the HTTP status carries the class, and the body repeats it
HTTP 403
{
"error": {
"code": -32009,
"message": "This tool requires a registered account. ...",
"data": { "mcpCode": "AUTH_INSUFFICIENT_ROLE", "recoverable": false, "details": { ... } }
}
}Transports differ, deliberately. On /mcp/tools/* (REST) a failure returns a real HTTP status — 400, 401, 403, 404, 409, 429, 500, 502. On /mcp/rpc and /mcp/sse a failure returns HTTP 200 with the error inside the JSON-RPC body, as the JSON-RPC spec requires. If you put a circuit breaker or retry policy on HTTP status alone, it will see the RPC transport as permanently healthy — branch on data.mcpCode and data.recoverable instead.
JSON-RPC-fouten
{
"jsonrpc": "2.0",
"id": 1,
"error": {
"code": -32001,
"message": "Authentication required for this tool.",
"data": {
"loginUrl": "https://users.locktrip.com/api/auth/login",
"signupTool": "guest_login"
}
}
}| Code | Betekenis |
|---|---|
| -32700 | Onjuiste JSON — de aanvraagtekst kon niet worden verwerkt |
| -32600 | Ongeldig JSON-RPC verzoek |
| -32601 | Onbekende tool / methode niet gevonden |
| -32001 | Authenticatie vereist of ongeldig token |
| -32009 | Geauthenticeerd, maar deze sessie mist de vereiste rol - gebruik login, niet guest_login |
| -32007 | Limiet overschreden |
| -32603 | Interne serverfout |
Limieten
Sliding-window limieten per IP (anoniem) of per gebruikers-ID (geauthenticeerd). Overschrijding resulteert in HTTP 429 of JSON-RPC foutcode -32007.
| Tool | Anoniem | Geauthenticeerd |
|---|---|---|
| hotel_search | 5/ minuut | 20/ minuut |
| Alle andere tools | 30/ minuut | 120/ minuut |
Tool Referentie
15 tools in aanbevolen werkstroomvolgorde.
search_location
PubliekZoek naar locaties (steden, regio's, hotels) om hun ID's te verkrijgen voor hotelzoekopdrachten. Geeft overeenkomende locaties terug met type en volledige naam.
Verzoek
| Veld | Type | Verpl. | Beschrijving |
|---|---|---|---|
| query | string | Yes | Search query (city name, region, or hotel name) |
| language | string | No | Language code (default: "en") |
Antwoord
| Veld | Type | Beschrijving | |
|---|---|---|---|
| locations | Location[] | Array of matching locations | |
| locations[].id | string | Location ID (use as regionId in hotel_search) | |
| locations[].name | string | Location name | |
| locations[].type | string | Location type (e.g., "CITY") | |
| locations[].fullName | string | Full location name with country | |
| locations[].country | string | Country name | |
| totalCount | number | Total number of matches returned |
Voorbeeld
curl -X POST https://locktrip.com/mcp/tools/search_location \
-H "Content-Type: application/json" \
-d '{"query": "Paris"}'
# Response (200 OK):
{
"locations": [
{
"id": "5f078e431fd614748f9037f9",
"name": "Paris, France",
"country": "",
"type": "CITY",
"fullName": "Paris, France"
},
{
"id": "5f080b92b8f3040a9045c3e8",
"name": "Disneyland Paris, Boulevard de Parc, Coupvray, France",
"country": "",
"type": "CITY",
"fullName": "Disneyland Paris, Boulevard de Parc, Coupvray, France"
}
],
"totalCount": 10
}hotel_search
PubliekStart een hotelzoekopdracht. Geef regionId op van search_location of breedte-/lengtecoördinaten. Geeft een searchKey terug om te pollen met get_search_results. Zoekopdracht draait asynchroon.
Verzoek
| Veld | Type | Verpl. | Beschrijving |
|---|---|---|---|
| regionId | string | No | Location ID from search_location. Required unless lat/lng provided. |
| startDate | string | Yes | Check-in date (YYYY-MM-DD). MUST be in the future — a past date is rejected with "Check-in date cannot be in the past". The dates in the examples are illustrative; substitute your own future window. |
| endDate | string | Yes | Check-out date (YYYY-MM-DD) |
| currency | string | No | Currency code (default: "USD") |
| rooms | Room[] | Yes | Room configurations |
| rooms[].adults | number | Yes | Number of adults (1-4) |
| rooms[].childrenAges | number[] | No | Ages of children (0-17) |
| nationality | string | Yes | 2-letter country code (e.g., US, GB) |
| latitude | number | No | Latitude (-90 to 90). Use with longitude instead of regionId. |
| longitude | number | No | Longitude (-180 to 180). Use with latitude instead of regionId. |
| radiusInMeters | number | No | Search radius in meters (default: 30000, max: 100000). Only with lat/lng. |
Antwoord
| Veld | Type | Beschrijving | |
|---|---|---|---|
| searchKey | string | Key to poll results with get_search_results | |
| sessionId | string | Internal session identifier | |
| status | string | Search status (e.g., "IN_PROGRESS") |
Voorbeeld
curl -X POST https://locktrip.com/mcp/tools/hotel_search \
-H "Content-Type: application/json" \
-d '{
"regionId": "5f078e431fd614748f9037f9",
"startDate": "2027-04-15",
"endDate": "2027-04-17",
"currency": "EUR",
"rooms": [{"adults": 2}],
"nationality": "US"
}'
# Response (200 OK):
{
"searchKey": "47de06e3262ea3822bdc384a04470783",
"sessionId": "/280/137970/D20260228T093158/4fcf789dd1294b4194cdb2c263bdf264",
"status": "IN_PROGRESS"
}get_search_results
PubliekHaal gepagineerde hotelzoekresultaten op. Poll totdat searchStatus "COMPLETED" is. Ondersteunt filtering op prijs, sterren, voorzieningen en maaltijdtypen. Sortering op prijs, beoordeling of afstand.
Prijsintelligentie
Elk hotelresultaat bevat discountScore — LockTrip's eigen machine learning-score die berekent hoeveel goedkoper het aanbod is vergeleken met andere reiswebsites. Het V8 ML-model analyseert realtime prijsdata van meerdere hotelleveranciers om besparingen te voorspellen. Gebruik minPrice (LockTrip's prijs) en originalPrice (laatste beste prijs op concurrerende sites) samen met discountScore om de beste deals aan gebruikers te tonen.
Verzoek
| Veld | Type | Verpl. | Beschrijving |
|---|---|---|---|
| searchKey | string | Yes | Search key from hotel_search |
| page | number | No | Page number, 0-indexed (default: 0) |
| size | number | No | Results per page (default: 100, max: 5000) |
| currency | string | No | Currency code from hotel_search |
| sortBy | string | No | PRICE_ASC, PRICE_DESC, RATING_DESC, or DISTANCE |
| filters | object | No | Optional filters (see below) |
| filters.minPrice | number | No | Minimum price |
| filters.maxPrice | number | No | Maximum price |
| filters.starRatings | number[] | No | Star ratings to include (1-5) |
| filters.amenities | string[] | No | Required amenities |
| filters.mealTypes | string[] | No | Required meal types |
| filters.hotelName | string | No | Hotel name search |
Antwoord
| Veld | Type | Beschrijving | |
|---|---|---|---|
| hotels | Hotel[] | Array of matching hotels | |
| hotels[].hotelId | string | Hotel ID (use in get_hotel_rooms, get_hotel_details) | |
| hotels[].name | string | Hotel name | |
| hotels[].starRating | number | Star rating (1-5) | |
| hotels[].address | string | Street address | |
| hotels[].latitude | number | Latitude coordinate | |
| hotels[].longitude | number | Longitude coordinate | |
| hotels[].images | string[] | Hotel image URLs | |
| hotels[].amenities | string[] | Available amenities | |
| hotels[].minPrice | number | LockTrip's price for this hotel (lowest available rate) | |
| hotels[].originalPrice | number | Last best price found on competing travel websites (e.g. Booking.com, Expedia). When equal to minPrice, no discount was detected. | |
| hotels[].currency | string | Price currency code | |
| hotels[].discountScore | number | LockTrip's proprietary machine learning score indicating how much cheaper this offer is compared to other travel websites. Powered by a V8 ML model that analyzes real-time pricing data from multiple hotel suppliers. Higher = bigger savings. 0 means no significant discount was detected. RELATIVE, WITH NO FIXED UPPER BOUND — the model output is not clamped. Across millions of live results we observed a range of roughly 0 to 60, with about one result in ten above 10. Rank and compare results against each other; do NOT normalise against a constant maximum. | |
| hotels[].quality | number | Internal ranking scalar (the default sort key) derived from discountScore, distance and review score. RELATIVE, WITH NO FIXED UPPER BOUND and no absolute meaning — over the same data we observed roughly 0 to 23, with under a third above 1. 0 means the hotel has no discount score or no qualifying reviews. Use it to order results; do not display it as a rating or normalise it against a constant. | |
| hotels[].reviewScore | number | Guest review score (0-10). This is the one to show a user. | |
| hotels[].reviewCount | number|null | Number of guest reviews | |
| hotels[].hasFreeCancellation | boolean | Whether any room has free cancellation | |
| hotels[].isRefundable | boolean | Whether any room is refundable | |
| hotels[].refundableUntil | string|null | ISO date until which free cancellation is available | |
| hotels[].payment | string | Payment type (e.g., "Cash") | |
| hotels[].distance | number | Distance from search center (km) | |
| hotels[].boardType | string|null | Default board type | |
| hotels[].availableMealTypes | string[] | Available meal types | |
| totalCount | number | Total hotels matching search | |
| page | number | Current page number, 0-indexed — the SAME indexing as the request. Request page 0 and this echoes 0. To walk pages, request page + 1. | |
| pageSize | number | Results per page | |
| hasMore | boolean | Whether more pages are available | |
| searchStatus | string | "IN_PROGRESS" or "COMPLETED" |
Voorbeeld
curl -X POST https://locktrip.com/mcp/tools/get_search_results \
-H "Content-Type: application/json" \
-d '{
"searchKey": "47de06e3262ea3822bdc384a04470783",
"page": 0,
"size": 2
}'
# Response (200 OK):
{
"hotels": [
{
"hotelId": "4703420",
"name": "Premiere Classe Boissy Saint Leger",
"starRating": 1,
"address": "P.A De La Haie Griselle 4 Rue Pompadour, Boissy-Saint-Leger",
"latitude": 48.759967,
"longitude": 2.501443,
"images": [
"https://imagecontent.net/images/full/5a0d94a0-5f7e-4e4e-b457-5e0673a96a95.jpeg"
],
"amenities": ["Family rooms", "Free Wifi", "Parking", "Air conditioning"],
"minPrice": 71.51,
"originalPrice": 71.51,
"currency": "EUR",
"discountScore": 0,
"quality": 0.19,
"reviewScore": 2.5,
"reviewCount": null,
"hasFreeCancellation": false,
"isRefundable": false,
"refundableUntil": null,
"payment": "Cash",
"distance": 15.32,
"boardType": null,
"availableMealTypes": []
}
],
"totalCount": 2403,
"page": 0,
"pageSize": 2,
"hasMore": true,
"searchStatus": "COMPLETED"
}get_hotel_rooms
PubliekHaal beschikbare kamerpakketten op voor een specifiek hotel. Geeft quoteIds terug die nodig zijn voor boeking. Elk pakket bevat prijs, maaltijdtype, voorzieningen en annuleringsinformatie.
Verzoek
| Veld | Type | Verpl. | Beschrijving |
|---|---|---|---|
| hotelId | string | Yes | Hotel ID from search results |
| searchKey | string | Yes | Search key from hotel_search |
| startDate | string | Yes | Check-in date (YYYY-MM-DD). MUST be in the future — a past date is rejected with "Check-in date cannot be in the past". The dates in the examples are illustrative; substitute your own future window. |
| endDate | string | Yes | Check-out date (YYYY-MM-DD) |
| rooms | Room[] | Yes | Room occupancy (same as hotel_search) |
| nationality | string | Yes | 2-letter country code |
| regionId | string | Yes | Region ID from search_location |
| currency | string | No | Currency code (default: "USD") |
Antwoord
| Veld | Type | Beschrijving | |
|---|---|---|---|
| hotelId | string | Hotel ID | |
| hotelName | string | Hotel name | |
| checkIn | string | Check-in date (YYYY-MM-DD) | |
| checkOut | string | Check-out date (YYYY-MM-DD) | |
| packages | Package[] | Available room packages | |
| packages[].quoteId | string | Quote ID (use in prepare_booking) | |
| packages[].packageId | string | Package identifier | |
| packages[].roomName | string | Room type name (e.g., "Standard, 3 Beds") | |
| packages[].roomDescription | string | HTML description of room features | |
| packages[].mealType | string | "Room Only", "Breakfast Included", etc. | |
| packages[].mealDescription | string | Meal plan description | |
| packages[].maxOccupancy | number | Maximum guests per room | |
| packages[].amenities | string[] | Room amenities list | |
| packages[].price | number | Total price for all nights | |
| packages[].currency | string | Price currency | |
| packages[].pricePerNight | number | Price per night | |
| packages[].totalNights | number | Number of nights | |
| packages[].isRefundable | boolean | Whether room is refundable |
Voorbeeld
curl -X POST https://locktrip.com/mcp/tools/get_hotel_rooms \
-H "Content-Type: application/json" \
-d '{"hotelId":"4384127","searchKey":"47de06e3262ea3822bdc384a04470783","startDate":"2027-04-15","endDate":"2027-04-17","rooms":[{"adults":2}],"nationality":"US","regionId":"5f078e431fd614748f9037f9","currency":"EUR"}'
# Response (200 OK):
{
"hotelId": "4384127",
"hotelName": "",
"checkIn": "2027-04-15",
"checkOut": "2027-04-17",
"packages": [
{
"quoteId": "3e242771-1c15-4356-9a3b-1cd4bfc6d9fc_4384127",
"packageId": "3e242771-1c15-4356-9a3b-1cd4bfc6d9fc_4384127",
"roomName": "Standard, 3 Beds",
"mealType": "Room Only",
"price": 71.34,
"currency": "EUR",
"pricePerNight": 35.67,
"totalNights": 2,
"isRefundable": false
}
]
}get_hotel_details
PubliekHaal gedetailleerde hotelinformatie op inclusief beschrijving, voorzieningen, beoordelingen, foto's en locatie. Gebruik na zoeken om volledige hotelinfo te krijgen vóór boeking.
Verzoek
| Veld | Type | Verpl. | Beschrijving |
|---|---|---|---|
| hotelId | number | Yes | Hotel ID (numeric, from search results) |
| language | string | No | Language code (default: "en") |
| includeImages | boolean | No | Fetch additional images (default: false) |
| imageLimit | number | No | Max additional images (default: 20, max: 100) |
Antwoord
| Veld | Type | Beschrijving | |
|---|---|---|---|
| hotel | object | Hotel details object | |
| hotel.id | number | Hotel ID | |
| hotel.name | string | Hotel name | |
| hotel.country | string | Country | |
| hotel.city | string | City | |
| hotel.star | number | Star rating (1-5) | |
| hotel.address | string | Street address | |
| hotel.latitude | number | Latitude | |
| hotel.longitude | number | Longitude | |
| hotel.description | string | HTML description with sections | |
| hotel.phone | string|null | Phone number | |
| hotel.hotelPhotos | Photo[] | Photo URLs (relative paths) | |
| hotel.reviews | object | Review summary with score, count, keywords | |
| hotel.hotelAmenities | Category[] | Amenities grouped by category | |
| additionalImages | Photo[] | Extra images (if includeImages=true) |
Voorbeeld
curl -X POST https://locktrip.com/mcp/tools/get_hotel_details \
-H "Content-Type: application/json" \
-d '{"hotelId": 4384127}'
# Response (200 OK):
{
"hotel": {
"id": 4384127,
"name": "Premiere Classe Plaisir",
"country": "France",
"city": "Plaisir",
"star": 1,
"address": "Za De Sainte Apolline Rue Des Poiriers",
"description": "<h2>Hotel Details</h2><p>Property Location...</p>",
"hotelPhotos": [{"url": "/gmx/full/d174a039-ebf9-4e42-8b42-5e31a6950b0e.jpeg"}],
"reviews": {"scoreSummary": 0, "reviewsCount": 0, "keyWords": []},
"hotelAmenities": [{"categoryName": "Hotel Facilities & Services", "features": [{"name": "Free Wifi"}]}]
}
}check_cancellation_policy
PubliekHaal het gedetailleerde annuleringsbeleid op voor kamerpakketten. Toont de deadline voor gratis annulering en boetekosten per datumperiode.
Verzoek
| Veld | Type | Verpl. | Beschrijving |
|---|---|---|---|
| searchKey | string | Yes | Search key from hotel_search |
| hotelId | string | Yes | Hotel ID |
| packageIds | string[] | Yes | Package UUIDs, WITHOUT the _hotelId suffix — take the quoteId from get_hotel_rooms and truncate it: quoteId.split('_')[0]. Passing the full quoteId here fails with a misleading SESSION_EXPIRED even on a live session, because the policy lookup matches the bare UUID. |
Antwoord
| Veld | Type | Beschrijving | |
|---|---|---|---|
| hotelId | string | Hotel ID | |
| policies | Policy[] | Cancellation policy per package | |
| policies[].packageId | string | Package identifier | |
| policies[].isRefundable | boolean | Whether package is refundable | |
| policies[].freeCancellationUntil | string|null | Last date for free cancellation (YYYY-MM-DD) | |
| policies[].fees | Fee[] | Cancellation penalty fees | |
| policies[].fees[].fromDate | string | Penalty period start (YYYY-MM-DD) | |
| policies[].fees[].toDate | string|null | Penalty period end | |
| policies[].fees[].amount | number | Penalty amount | |
| policies[].fees[].currency | string|absent | The supplier's own currency for this penalty. OMITTED, never guessed, when the supplier states none — treat an absent currency as unpriced rather than assuming your search currency. (Before 2026-08 this field was hardcoded to USD and was wrong for every non-USD search.) | |
| policies[].fees[].percentage | number|null | Percentage of booking price | |
| policies[].remarks | string[]|null | Additional policy notes |
Voorbeeld
curl -X POST https://locktrip.com/mcp/tools/check_cancellation_policy \
-H "Content-Type: application/json" \
-d '{"searchKey":"47de06e3262ea3822bdc384a04470783","hotelId":"4384127","packageIds":["e3fca710-0a05-4b96-a472-a93c941a58fc"]}'
# NOTE the packageId has NO _4384127 suffix. Passing the full quoteId here returns
# 409 SESSION_EXPIRED even on a live session.
# Response (200 OK):
{
"hotelId": "4384127",
"policies": [{
"packageId": "e3fca710-0a05-4b96-a472-a93c941a58fc_4384127",
"isRefundable": true,
"freeCancellationUntil": "2027-04-13",
"fees": [{"fromDate":"2027-04-13","toDate":"2027-04-15","amount":77.53,"currency":"EUR","percentage":100}],
"remarks": ["Room: Standard, 3 Beds", "Board: Room Only"]
}]
}guest_login
PubliekRegistreer of log in als gast met alleen een e-mailadres. Geeft een Bearer token terug voor geauthenticeerde tools. ELKE aanroep verstuurt een verificatie-e-mail naar dat adres, ook voor een bestaand account — vraag het token eenmaal aan en hergebruik het. Het resultaat is een GAST-sessie.
Verzoek
| Veld | Type | Verpl. | Beschrijving |
|---|---|---|---|
| string | Yes | User email address |
Antwoord
| Veld | Type | Beschrijving | |
|---|---|---|---|
| token | string | JWT Bearer token for authenticated API calls | |
| userId | number | Numeric user ID | |
| string | User email address | ||
| isNewUser | boolean | Whether a new account was created |
Voorbeeld
curl -X POST https://locktrip.com/mcp/tools/guest_login \
-H "Content-Type: application/json" \
-d '{"email": "[email protected]"}'
# Response (200 OK):
{"token":"eyJhbGciOiJIUzUxMiJ9...","userId":413900,"email":"[email protected]","isNewUser":true}login
PubliekLog in met e-mail en wachtwoord om een Bearer token te verkrijgen. Voor geregistreerde gebruikers met bevestigde accounts.
Verzoek
| Veld | Type | Verpl. | Beschrijving |
|---|---|---|---|
| string | Yes | User email address | |
| password | string | Yes | User password |
Antwoord
| Veld | Type | Beschrijving | |
|---|---|---|---|
| token | string | JWT Bearer token for authenticated API calls | |
| userId | number | Numeric user ID | |
| string | User email address |
Voorbeeld
curl -X POST https://locktrip.com/mcp/tools/login \
-H "Content-Type: application/json" \
-d '{"email":"[email protected]","password":"yourpassword"}'
# Response (200 OK):
{"token":"eyJhbGciOiJIUzUxMiJ9...","userId":12345,"email":"[email protected]"}prepare_booking
Auth VereistMaak een boeking aan met gastgegevens. Geeft een preparedBookingId terug voor bevestiging. Een voorbereide boeking heeft geen vaste vervaltijd; wat verloopt is de zoeksessie achter de quoteId. Het aantal gasten per kamer moet overeenkomen met het aantal volwassenen uit de zoekopdracht.
Verzoek
| Veld | Type | Verpl. | Beschrijving |
|---|---|---|---|
| quoteId | string | Yes | Quote ID from get_hotel_rooms |
| searchKey | string | Yes | Search key from hotel_search — the SAME one used for get_hotel_rooms. REQUIRED: omitting it returns 400 VALIDATION_ERROR naming searchKey as the failing path. It warms the cancellation-policy cache the backend needs in order to book. |
| rooms | Room[] | Yes | Guest assignments per room |
| rooms[].roomIndex | number | Yes | Room index (0-based) |
| rooms[].guests | Guest[] | Yes | Adult guests in this room |
| rooms[].guests[].firstName | string | Yes | First name |
| rooms[].guests[].lastName | string | Yes | Last name |
| rooms[].guests[].title | string | No | "Mr", "Mrs", or "Ms" (default: "Mr") |
| rooms[].guests[].email | string | No | Email address |
| rooms[].guests[].phone | string | No | Phone number |
| rooms[].guests[].isLeadGuest | boolean | No | Whether this is the lead guest |
| rooms[].children | Child[] | No | Children in this room |
| rooms[].children[].firstName | string | Yes | First name |
| rooms[].children[].lastName | string | Yes | Last name |
| rooms[].children[].age | number | Yes | Child age (0-17) |
| contactPerson | object | Yes | Contact person details |
| contactPerson.firstName | string | Yes | First name |
| contactPerson.lastName | string | Yes | Last name |
| contactPerson.email | string | Yes | Email address |
| contactPerson.phone | string | Yes | Phone number (min 5 chars) |
| contactPerson.title | string | No | "Mr", "Mrs", or "Ms" |
| contactPerson.countryCode | string | No | 2-letter country code |
| specialRequests | string | No | Special requests for the hotel |
Antwoord
| Veld | Type | Beschrijving | |
|---|---|---|---|
| preparedBookingId | string | Booking ID for confirm_booking | |
| bookingInternalId | string | Internal booking identifier | |
| price | number | Total price | |
| currency | string | Price currency | |
| payment | string | Payment type (e.g., "Cash") | |
| discount | object | Discount details (amount, currency) | |
| taxes | Tax[] | Itemized taxes and fees | |
| essentialInformation | string[] | Check-in instructions, mandatory fees, policies |
Voorbeeld
curl -X POST https://locktrip.com/mcp/tools/prepare_booking \
-H "Content-Type: application/json" \
-H "Authorization: Bearer eyJhbGciOiJIUzUxMiJ9..." \
-d '{"quoteId":"3e242771-1c15-4356-9a3b-1cd4bfc6d9fc_4384127","searchKey":"47de06e3262ea3822bdc384a04470783","rooms":[{"roomIndex":0,"guests":[{"firstName":"John","lastName":"Smith","title":"Mr","email":"[email protected]","phone":"+1234567890","isLeadGuest":true}]}],"contactPerson":{"firstName":"John","lastName":"Smith","email":"[email protected]","phone":"+1234567890"}}'
# Response (200 OK):
{"preparedBookingId":"69a2b7540a93415a4b4dbf13","price":71.34,"currency":"EUR","payment":"Cash","discount":{"amount":0,"currency":"EUR"},"taxes":[{"feeTitle":"Taxes and Fees","value":"1.59","currency":"EUR","isIncludedInPrice":true}],"essentialInformation":["CheckIn instructions: ..."]}confirm_booking
Auth VereistBevestig en betaal een voorbereide boeking met B2B-kredietlijn. Geeft boekingsbevestiging met voucher-URL terug. Gebruik voor consumentenbetalingen create_checkout of get_payment_url.
Verzoek
| Veld | Type | Verpl. | Beschrijving |
|---|---|---|---|
| bookingInternalId | string | Yes | Booking ID from prepare_booking (preparedBookingId) |
| quoteId | string | Yes | Quote ID used in prepare_booking |
| paymentMethod | string | No | Payment method (default: "CREDIT_LINE" for B2B) |
Antwoord
| Veld | Type | Beschrijving | |
|---|---|---|---|
| accepted | boolean | Whether booking confirmation was accepted | |
| message | string|null | Confirmation status message | |
| voucherUrl | string|null | URL to booking voucher (if accepted) | |
| serviceUnavailable | boolean|absent | Present, and always true, ONLY when our credit service did not answer. Otherwise the key is OMITTED - test for PRESENCE, never for false (=== false never matches). Its absence is meaningful: the service answered, so accepted:false is a real refusal. See the warning below. |
Voorbeeld
curl -X POST https://locktrip.com/mcp/tools/confirm_booking \
-H "Content-Type: application/json" \
-H "Authorization: Bearer eyJhbGciOiJIUzUxMiJ9..." \
-d '{"bookingInternalId":"69a2b7540a93415a4b4dbf13","quoteId":"3e242771-1c15-4356-9a3b-1cd4bfc6d9fc_4384127"}'
# Response (200 OK):
{"accepted":true,"message":"Booking confirmed successfully","voucherUrl":"https://locktrip.com/booking/hotel/voucher/69a2b7540a93415a4b4dbf13"}A credit-line refusal is not an error. If your line has insufficient balance, this tool returns HTTP 200 with accepted: false and the reason in message — it does not raise an error code. Branch on accepted, not on the HTTP status.
Treat serviceUnavailable: true differently from a refusal. It means our credit service did not answer, so we cannot tell you whether the reservation was applied. It may already be held against your line. Do not blindly retry — the reserve call is not idempotent and a retry can reserve the amount twice. Re-check the booking with get_booking_details before any second attempt.
create_checkout
Auth VereistMaak een Revolut betaal-checkout-URL aan voor een voorbereide boeking. Geeft een gehoste checkout-link terug waarop de gebruiker kan klikken om te betalen. Na betaling wordt de boeking automatisch bevestigd via webhook. Gebruik voor B2C-consumenten.
Verzoek
| Veld | Type | Verpl. | Beschrijving |
|---|---|---|---|
| bookingId | string | Yes | Booking ID from prepare_booking (preparedBookingId) |
| currency | string | Yes | 3-letter currency code (e.g., USD, EUR, GBP) |
| backUrl | string | No | Cancel/back redirect URL (defaults to locktrip.com) |
| successUrl | string | No | Success redirect URL |
Antwoord
| Veld | Type | Beschrijving | |
|---|---|---|---|
| checkoutUrl | string | Revolut hosted checkout URL for payment | |
| checkoutToken | string | Payment token for tracking | |
| expiresInMinutes | number | Token expiration time (20 minutes) | |
| message | string | User instruction message |
Voorbeeld
curl -X POST https://locktrip.com/mcp/tools/create_checkout \
-H "Content-Type: application/json" \
-H "Authorization: Bearer eyJhbGciOiJIUzUxMiJ9..." \
-d '{"bookingId":"69a2b7540a93415a4b4dbf13","currency":"EUR"}'
# Response (200 OK):
{"checkoutUrl":"https://checkout.revolut.com/pay/abc123...","checkoutToken":"rev_tok_abc123...","expiresInMinutes":20,"message":"Payment checkout link created. Share this URL with the user to complete payment."}get_payment_url
Auth VereistHaal een Stripe checkout-URL op voor het betalen van een voorbereide boeking. Geeft een URL terug om de klant door te sturen voor creditcardbetaling.
Verzoek
| Veld | Type | Verpl. | Beschrijving |
|---|---|---|---|
| bookingId | string | Yes | Booking ID from prepare_booking (preparedBookingId) |
| currency | string | Yes | Payment currency code (e.g., USD, EUR) |
| backUrl | string | Yes | URL to redirect on cancel/back |
| successUrl | string | No | Custom URL to redirect on success |
Antwoord
| Veld | Type | Beschrijving | |
|---|---|---|---|
| url | string | Stripe checkout URL to redirect customer to | |
| sessionId | string | Stripe session ID for tracking |
Voorbeeld
curl -X POST https://locktrip.com/mcp/tools/get_payment_url \
-H "Content-Type: application/json" \
-H "Authorization: Bearer eyJhbGciOiJIUzUxMiJ9..." \
-d '{"bookingId":"69a2b7540a93415a4b4dbf13","currency":"EUR","backUrl":"https://example.com/cancel"}'
# Response (200 OK):
{"url":"https://checkout.stripe.com/c/pay/cs_live_abc123...","sessionId":"cs_live_abc123..."}list_bookings
Auth VereistLijst van boekingen voor de geauthenticeerde gebruiker. Filter op status: UPCOMING, COMPLETED, CANCELLED of PENDING.
Verzoek
| Veld | Type | Verpl. | Beschrijving |
|---|---|---|---|
| type | string | No | "UPCOMING", "COMPLETED", "CANCELLED", or "PENDING" (default: "UPCOMING") |
| page | ignored | No | NOT SUPPORTED — accepted by the transport but silently discarded; this tool does not paginate. |
| size | ignored | No | NOT SUPPORTED — silently discarded. list_bookings returns the whole filtered set in one response. |
Antwoord
| Veld | Type | Beschrijving | |
|---|---|---|---|
| bookings | BookingSummary[] | Array of booking summaries | |
| bookings[].bookingId | string | Booking identifier | |
| bookings[].bookingReferenceId | string | Provider reference ID | |
| bookings[].hotelName | string | Hotel name | |
| bookings[].hotelCity | string | ALWAYS an empty string — the upstream list record carries no city. Use get_booking_details for the hotel’s city. | |
| bookings[].checkIn | string | Check-in date (YYYY-MM-DD) | |
| bookings[].checkOut | string | Check-out date (YYYY-MM-DD) | |
| bookings[].status | string | Booking status (DONE, PENDING, CANCELLED) | |
| bookings[].totalPrice | absent | NOT RETURNED. The upstream booking-list record carries no price, so this field is omitted rather than filled with a placeholder. Call get_booking_details for the real amount. | |
| bookings[].currency | absent | NOT RETURNED, for the same reason. Call get_booking_details, which returns both totalPrice and currency. | |
| bookings[].guestName | string | ALWAYS the literal "Guest" — the upstream list record carries no guest name. Use get_booking_details for the real guests. | |
| bookings[].roomCount | number | Number of rooms | |
| bookings[].createdAt | string | Booking creation timestamp (ISO 8601) | |
| bookings[].hotelPhoto | string|null | Hotel image URL | |
| totalCount | number | Number of bookings in THIS response. There is no pagination, so this is the full filtered set. | |
| page | number | Always 0 — this tool does not paginate. | |
| pageSize | number | Equal to totalCount; present for shape compatibility only. |
Voorbeeld
curl -X POST https://locktrip.com/mcp/tools/list_bookings \
-H "Content-Type: application/json" \
-H "Authorization: Bearer eyJhbGciOiJIUzUxMiJ9..." \
-d '{"type": "UPCOMING"}'
# Response (200 OK):
{"bookings":[{"bookingId":"69a2b7540a93415a4b4dbf13","bookingReferenceId":"LT-2026-AB12CD","hotelName":"Premiere Classe Plaisir","hotelCity":"","checkIn":"2027-04-15","checkOut":"2027-04-17","status":"DONE","guestName":"Guest","roomCount":1,"createdAt":"2026-02-28T09:35:00.000Z","hotelPhoto":"https://imagecontent.net/images/full/d174a039.jpeg"}],"totalCount":1,"page":0,"pageSize":1}
# NOTE: this endpoint is a summary index, not a detail view. totalPrice and currency are
# absent, and hotelCity / guestName are not populated by the upstream list record.
# Fetch a bookingId with get_booking_details for price, currency, guests and city.get_booking_details
Auth VereistHaal volledige details op van een specifieke boeking inclusief hotelinformatie, gasten, kamers, betalingsstatus en annuleringsbeleid.
Verzoek
| Veld | Type | Verpl. | Beschrijving |
|---|---|---|---|
| bookingId | string | Yes | Booking ID to retrieve |
Antwoord
| Veld | Type | Beschrijving | |
|---|---|---|---|
| bookingId | string | Booking identifier | |
| bookingReferenceId | string | Provider reference ID | |
| status | string | Booking status (DONE, PENDING, CANCELLED) | |
| hotel | object | Hotel details | |
| hotel.name | string | Hotel name | |
| hotel.address | string | Street address | |
| hotel.city | string | City | |
| hotel.country | string | Country | |
| hotel.starRating | number | Star rating (1-5) | |
| checkIn | string | Check-in date (YYYY-MM-DD) | |
| checkOut | string | Check-out date (YYYY-MM-DD) | |
| rooms | Room[] | Booked rooms with guests | |
| contactPerson | object | Contact person (firstName, lastName, email, phone) | |
| totalPrice | number | Total booking price | |
| currency | string | Currency code | |
| paymentStatus | string | Payment status (PAID, PENDING) | |
| cancellationPolicy | object|null | Cancellation policy with fees and deadlines | |
| createdAt | string | Booking creation date | |
| confirmedAt | string|null | Confirmation date (null if pending) |
Voorbeeld
curl -X POST https://locktrip.com/mcp/tools/get_booking_details \
-H "Content-Type: application/json" \
-H "Authorization: Bearer eyJhbGciOiJIUzUxMiJ9..." \
-d '{"bookingId": "69a2b7540a93415a4b4dbf13"}'
# Response (200 OK):
{"bookingId":"69a2b7540a93415a4b4dbf13","bookingReferenceId":"LT-2026-AB12CD","status":"DONE","hotel":{"id":4384127,"name":"Premiere Classe Plaisir","city":"Plaisir","country":"France","starRating":1},"checkIn":"2027-04-15","checkOut":"2027-04-17","totalPrice":71.34,"currency":"EUR","paymentStatus":"PAID","createdAt":"2026-02-28","confirmedAt":"2026-02-28"}cancel_booking
Auth VereistVraag annulering van een boeking aan. Roep eerst aan met confirmed=false om annuleringskosten te bekijken, daarna met confirmed=true om uit te voeren. Geeft restitutiebedrag en annuleringskosten terug.
Verzoek
| Veld | Type | Verpl. | Beschrijving |
|---|---|---|---|
| bookingId | string | Yes | Booking ID to cancel |
| confirmed | boolean | Yes | Set true to execute cancellation |
| reason | string | No | Reason for cancellation |
Antwoord
| Veld | Type | Beschrijving | |
|---|---|---|---|
| success | boolean | Whether cancellation was executed | |
| message | string | Status message (preview or confirmation) |
Voorbeeld
# Step 1: Preview cancellation (dry run)
curl -X POST https://locktrip.com/mcp/tools/cancel_booking \
-H "Content-Type: application/json" \
-H "Authorization: Bearer eyJhbGciOiJIUzUxMiJ9..." \
-d '{"bookingId":"69a2b7540a93415a4b4dbf13","confirmed":false}'
# Response (200 OK):
{"success":false,"message":"Cancellation not confirmed. Set confirmed=true to proceed."}
# Step 2: Execute cancellation
curl -X POST https://locktrip.com/mcp/tools/cancel_booking \
-H "Content-Type: application/json" \
-H "Authorization: Bearer eyJhbGciOiJIUzUxMiJ9..." \
-d '{"bookingId":"69a2b7540a93415a4b4dbf13","confirmed":true,"reason":"Change of plans"}'
# Response (200 OK):
{"success":true,"message":"Booking cancelled successfully"}Machine-leesbare specificaties: OpenAPI 3.1 | Tool List | MCP Discovery | GraphQL B2B Docs
LockTrip Hotel Booking MCP API v1.0.0