Documentacion API
Referencia completa de la API MCP de reservas hoteleras de LockTrip. 15 herramientas que cubren busqueda, reserva, pago y gestion.
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 →
Autenticacion
La API utiliza tokens Bearer JWT. Las herramientas de busqueda y navegacion no requieren autenticacion. Las herramientas de reserva y gestion requieren un token valido.
Obtener un token
Usa guest_login (solo correo, instantaneo) o login (correo + contrasena) para obtener un token JWT.
Usar el token
Authorization: Bearer eyJhbGciOiJIUzUxMiJ9...
OAuth 2.1 (clientes MCP)
Los clientes MCP (por ejemplo Claude, ChatGPT) se autentican automáticamente mediante OAuth 2.1 con PKCE: no tienes que configurarlo. Ante un 401, el cliente descubre el servidor en https://locktrip.com/.well-known/oauth-authorization-server, se registra dinámicamente (POST /register) y luego ejecuta el flujo de código de autorización: /authorize (consentimiento del usuario, protegido por Cloudflare Turnstile) → /token. Scopes: "mcp" (más "offline_access" para un token de actualización). Para integración directa por REST/curl, usa en su lugar un Bearer token manual (ver arriba).
Per-call auth: sessionToken
Para llamadas REST o JSON-RPC directas, las herramientas autenticadas también aceptan un argumento sessionToken como alternativa a la cabecera Authorization. Un token de guest_login (solo correo — sin contraseña, instantáneo) crea una sesión de INVITADO, y una sesión de INVITADO funciona ÚNICAMENTE con prepare_booking y create_checkout. get_payment_url, list_bookings, get_booking_details, cancel_booking y confirm_booking requieren todas una cuenta registrada: obtén ese token con login (correo + contraseña). Un socio B2B con línea de crédito debe autenticarse con login, nunca con guest_login: una sesión de invitado no tiene línea de crédito, por lo que confirm_booking la rechaza. Si una llamada devuelve AUTH_INSUFFICIENT_ROLE (HTTP 403), el token es válido y lo incorrecto es su rol: cambia a login en lugar de pedir otro token de guest_login.
Clasificacion de herramientas
| Publico (sin autenticacion) | Autenticado (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 |
URL base y transportes
Todos los endpoints se sirven desde https://locktrip.com/mcp/. Se admiten tres modos de transporte:
| Transporte | Metodo | 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 |
Endpoints de descubrimiento
| URL | Descripcion |
|---|---|
| GET /mcp/openapi.json | Especificacion OpenAPI 3.1 |
| GET /mcp/tools | Listar todas las herramientas con esquemas |
| GET /mcp/discovery | Documento de descubrimiento MCP |
Content-Type: application/json para todas las solicitudes POST.
Gestion de errores
Errores REST
| Estado | Significado |
|---|---|
| 200 | Exito |
| 400 | Error de validacion (datos incorrectos) |
| 401 | Bearer token ausente o invalido |
| 403 | Autenticado, pero esta sesion carece del rol necesario: usa login, no guest_login |
| 404 | Nombre de herramienta desconocido |
| 429 | Limite de velocidad excedido |
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.
Errores JSON-RPC
{
"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"
}
}
}| Codigo | Significado |
|---|---|
| -32700 | JSON con formato incorrecto — no se pudo analizar el cuerpo de la solicitud |
| -32600 | Solicitud JSON-RPC invalida |
| -32601 | Herramienta desconocida / metodo no encontrado |
| -32001 | Autenticacion requerida o token invalido |
| -32009 | Autenticado, pero esta sesion carece del rol necesario: usa login, no guest_login |
| -32007 | Limite de velocidad excedido |
| -32603 | Error interno del servidor |
Limites de velocidad
Limites de velocidad deslizantes por IP (anonimo) o por ID de usuario (autenticado). Superar los limites devuelve HTTP 429 o el codigo de error JSON-RPC -32007.
| Herramienta | Anonimo | Autenticado |
|---|---|---|
| hotel_search | 5/ minuto | 20/ minuto |
| Todas las demas herramientas | 30/ minuto | 120/ minuto |
Referencia de herramientas
15 herramientas listadas en el orden de flujo de trabajo recomendado.
search_location
PublicoBusca ubicaciones (ciudades, regiones, hoteles) para obtener sus IDs para la busqueda de hoteles. Devuelve ubicaciones coincidentes con tipo y nombre completo.
Solicitud
| Campo | Tipo | Req. | Descripcion |
|---|---|---|---|
| query | string | Yes | Search query (city name, region, or hotel name) |
| language | string | No | Language code (default: "en") |
Respuesta
| Campo | Tipo | Descripcion | |
|---|---|---|---|
| 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 |
Ejemplo
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
PublicoInicia una busqueda hotelera. Proporciona un regionId de search_location o coordenadas de latitud/longitud. Devuelve un searchKey para consultar con get_search_results. La busqueda se ejecuta de forma asincrona.
Solicitud
| Campo | Tipo | Req. | Descripcion |
|---|---|---|---|
| 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. |
Respuesta
| Campo | Tipo | Descripcion | |
|---|---|---|---|
| searchKey | string | Key to poll results with get_search_results | |
| sessionId | string | Internal session identifier | |
| status | string | Search status (e.g., "IN_PROGRESS") |
Ejemplo
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": "CNX-3f9a1c7e2b5d4a6f8e0c1b2d",
"status": "IN_PROGRESS"
}get_search_results
PublicoObtien resultados paginados de la busqueda hotelera. Consulta hasta que searchStatus sea "COMPLETED". Permite filtrar por precio, estrellas, servicios y tipos de comida. Ordenacion por precio, valoracion o distancia.
Inteligencia de precios
Cada resultado de hotel incluye un discountScore, la puntuacion propietaria de aprendizaje automatico de LockTrip que calcula cuanto mas barata es la oferta en comparacion con otros sitios de viajes. El modelo ML V8 analiza datos de precios en tiempo real de multiples proveedores hoteleros para predecir ahorros. Usa minPrice (precio de LockTrip) y originalPrice (ultimo mejor precio en sitios de la competencia) junto con discountScore para mostrar las mejores ofertas a los usuarios.
Solicitud
| Campo | Tipo | Req. | Descripcion |
|---|---|---|---|
| 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 |
Respuesta
| Campo | Tipo | Descripcion | |
|---|---|---|---|
| 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" |
Ejemplo
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://static.locktrip.com/hotel-photos/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
PublicoObtien los paquetes de habitaciones disponibles para un hotel especifico. Devuelve los quoteIds necesarios para la reserva. Cada paquete incluye precio, tipo de comida, servicios e informacion de cancelacion.
Solicitud
| Campo | Tipo | Req. | Descripcion |
|---|---|---|---|
| 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") |
Respuesta
| Campo | Tipo | Descripcion | |
|---|---|---|---|
| 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 |
Ejemplo
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
PublicoObtien informacion detallada del hotel, incluyendo descripcion, servicios, resenas, fotos y ubicacion. Usalo despues de la busqueda para obtener informacion completa antes de reservar.
Solicitud
| Campo | Tipo | Req. | Descripcion |
|---|---|---|---|
| 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) |
Respuesta
| Campo | Tipo | Descripcion | |
|---|---|---|---|
| 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) |
Ejemplo
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": "https://static.locktrip.com/hotel-photos/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
PublicoObtien la politica de cancelacion detallada para paquetes de habitaciones. Muestra el plazo de cancelacion gratuita y las penalizaciones por rango de fechas.
Solicitud
| Campo | Tipo | Req. | Descripcion |
|---|---|---|---|
| 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. |
Respuesta
| Campo | Tipo | Descripcion | |
|---|---|---|---|
| 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 | Exact instant free cancellation ends, ISO 8601 UTC (e.g. 2027-04-12T22:00:00.000Z); cancel before it. Same format in get_booking_details. | |
| 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 |
Ejemplo
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-12T22:00:00.000Z",
"fees": [{"fromDate":"2027-04-12","toDate":"2027-04-15","amount":77.53,"currency":"EUR","percentage":100}],
"remarks": ["Room: Standard, 3 Beds", "Board: Room Only"]
}]
}guest_login
PublicoRegistrate o inicia sesion como invitado con solo una direccion de correo. Devuelve un Bearer token para herramientas autenticadas. CADA llamada envia un correo de verificacion a esa direccion, incluso para una cuenta ya existente: solicita el token una vez y reutilizalo. El resultado es una sesion de INVITADO.
Solicitud
| Campo | Tipo | Req. | Descripcion |
|---|---|---|---|
| string | Yes | User email address |
Respuesta
| Campo | Tipo | Descripcion | |
|---|---|---|---|
| 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 |
Ejemplo
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
PublicoInicia sesion con correo y contrasena para obtener un Bearer token. Para usuarios registrados con cuentas confirmadas.
Solicitud
| Campo | Tipo | Req. | Descripcion |
|---|---|---|---|
| string | Yes | User email address | |
| password | string | Yes | User password |
Respuesta
| Campo | Tipo | Descripcion | |
|---|---|---|---|
| token | string | JWT Bearer token for authenticated API calls | |
| userId | number | Numeric user ID | |
| string | User email address |
Ejemplo
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
Requiere autenticacionCrea una reserva con datos del huesped. Devuelve un preparedBookingId para la confirmacion. Una reserva preparada no tiene caducidad fija; lo que caduca es la sesion de busqueda asociada a su quoteId. El numero de huespedes por habitacion debe coincidir con el numero de adultos de la busqueda.
Solicitud
| Campo | Tipo | Req. | Descripcion |
|---|---|---|---|
| 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 |
Respuesta
| Campo | Tipo | Descripcion | |
|---|---|---|---|
| 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 |
Ejemplo
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
Requiere autenticacionConfirma y paga una reserva preparada mediante la linea de credito B2B. Devuelve la confirmacion con URL del voucher. Para pagos de consumidores, usa create_checkout o get_payment_url.
Solicitud
| Campo | Tipo | Req. | Descripcion |
|---|---|---|---|
| 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) |
Respuesta
| Campo | Tipo | Descripcion | |
|---|---|---|---|
| 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. |
Ejemplo
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
Requiere autenticacionCrea una URL de pago Revolut para una reserva preparada. Devuelve un enlace de pago alojado en el que el usuario puede hacer clic para pagar. Tras completar el pago, la reserva se confirma automaticamente via webhook. Usalo para consumidores B2C.
Solicitud
| Campo | Tipo | Req. | Descripcion |
|---|---|---|---|
| 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 |
Respuesta
| Campo | Tipo | Descripcion | |
|---|---|---|---|
| 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 |
Ejemplo
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
Requiere autenticacionObtien una URL de pago Stripe para una reserva preparada. Devuelve una URL para redirigir al cliente al pago con tarjeta.
Solicitud
| Campo | Tipo | Req. | Descripcion |
|---|---|---|---|
| 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 |
Respuesta
| Campo | Tipo | Descripcion | |
|---|---|---|---|
| url | string | Stripe checkout URL to redirect customer to | |
| sessionId | string | Stripe session ID for tracking |
Ejemplo
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
Requiere autenticacionLista las reservas del usuario autenticado. Filtra por estado: UPCOMING, COMPLETED, CANCELLED o PENDING.
Solicitud
| Campo | Tipo | Req. | Descripcion |
|---|---|---|---|
| type | string | No | "UPCOMING", "COMPLETED", "CANCELLED", or "PENDING" (default: "UPCOMING") |
| page | number | No | Page number, 0-based. Omit page and size to get the whole filtered list in one response. |
| size | number | No | Bookings per page, 1–100 (default 100 when only page is sent). |
Respuesta
| Campo | Tipo | Descripcion | |
|---|---|---|---|
| bookings | BookingSummary[] | Array of booking summaries | |
| bookings[].bookingId | string | Booking identifier | |
| bookings[].bookingReferenceId | string | LockTrip booking reference | |
| 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 | number | No | The booking price as recorded on the booking. Omitted (never defaulted) when the booking records none, which includes legacy bookings. |
| bookings[].currency | string | No | Currency of totalPrice, e.g. EUR. Present only together with totalPrice. |
| 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 matching type, across all pages. | |
| page | number | The page returned, 0-based (0 when no paging was requested). | |
| pageSize | number | The page size used (the number of bookings returned when no paging was requested). |
Ejemplo
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","totalPrice":154.2,"currency":"EUR","guestName":"Guest","roomCount":1,"createdAt":"2026-02-28T09:35:00.000Z","hotelPhoto":"https://static.locktrip.com/hotel-photos/full/d174a039-ebf9-4e42-8b42-5e31a6950b0e.jpeg"}],"totalCount":1,"page":0,"pageSize":1}
# NOTE: this endpoint is a summary index, not a detail view. hotelCity and guestName are not
# populated by the list record. Fetch a bookingId with get_booking_details for guests, city
# and the full price breakdown. Page with {"page":0,"size":20}, then page 1, 2, ...get_booking_details
Requiere autenticacionObtien los detalles completos de una reserva especifica, incluyendo informacion del hotel, huespedes, habitaciones, estado del pago y politica de cancelacion.
Solicitud
| Campo | Tipo | Req. | Descripcion |
|---|---|---|---|
| bookingId | string | Yes | Booking ID to retrieve |
Respuesta
| Campo | Tipo | Descripcion | |
|---|---|---|---|
| bookingId | string | Booking identifier | |
| bookingReferenceId | string | LockTrip booking reference | |
| 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, or CREDIT_LINE for a confirmed B2B booking charged to your credit line; settlement is per statement: GET /api/b2b/credit-line/statement rows carry paymentStatus paid / partially_paid / unpaid) | |
| cancellationPolicy | object|null | Cancellation policy with fees and deadlines | |
| createdAt | string | Booking creation date | |
| confirmedAt | string|null | Confirmation date (null if pending) |
Ejemplo
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
Requiere autenticacionSolicita la cancelacion de una reserva. Llamar con `confirmed=false` no cambia nada y no devuelve cargos: consulta primero las condiciones con `get_booking_details`. Llama con `confirmed=true` para ejecutarla. Si tiene exito, se devuelve el cargo de cancelacion cobrado por el proveedor cuando este lo informa; los reembolsos se procesan por separado.
Solicitud
| Campo | Tipo | Req. | Descripcion |
|---|---|---|---|
| bookingId | string | Yes | Booking ID to cancel |
| confirmed | boolean | Yes | Set true to execute cancellation |
| reason | string | No | Reason for cancellation |
Respuesta
| Campo | Tipo | Descripcion | |
|---|---|---|---|
| success | boolean | Whether the cancellation was accepted | |
| message | string | Status message (dry run, confirmation, or why it was not accepted) | |
| cancellationFee | number | No | On success: the cancellation fee the supplier charged, as recorded on the booking. Omitted when the supplier reported none (not zero). Refunds are processed separately and are not returned here. |
| cancellationFeeCurrency | string | No | Currency of cancellationFee. |
| failureReason | string | No | When success is false: NOT_FOUND, AFTER_CHECK_IN, NOT_CANCELLABLE_STATUS, SUPPLIER_NOT_CONFIRMED (submitted and under review: do not rebook or retry) or ERROR (not processed: the booking was not cancelled; try again later or contact support). |
Ejemplo
# Step 1: Dry run (changes nothing, returns no fees)
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 with cancellation."}
# Step 1 changes nothing and returns no penalty figures. Check the terms first with
# check_cancellation_policy (before booking) or get_booking_details -> cancellationPolicy.
# 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 cancellation requested successfully.","cancellationFee":0,"cancellationFeeCurrency":"EUR"}
# Not accepted, e.g. after the check-in date:
{"success":false,"message":"This booking can no longer be cancelled online: the check-in date has been reached.","failureReason":"AFTER_CHECK_IN"}get_credit_line_statement
Requiere autenticacionThe signed-in partner's own credit-line statement: the real-time balance and the booking rows due in a date window. Partner credit-line accounts only; it takes no account identifier, the line is always your own.
Solicitud
| Campo | Tipo | Req. | Descripcion |
|---|---|---|---|
| from | string | No | First due date to include, YYYY-MM-DD. Pass with to; omit both for the current month. |
| to | string | No | Last due date to include, YYYY-MM-DD, at most 93 days after from. |
Respuesta
| Campo | Tipo | Descripcion | |
|---|---|---|---|
| balance | object | due, pending, availableCredit: always for the whole credit line, never filtered by from/to. | |
| bookingsMatured / bookingsPending | object | Rows in the window: bookingReferenceId, hotelName, guestName, dates, amount, currency, bucket (current = due, pending = not due yet), dueDate, paid, outstanding, paymentStatus, settledBy, lineType. | |
| rows[].lineType | string | booking, or cancellation_fee for a late-cancellation charge. | |
| paymentsReceived | object | Payments received on the line. |
Errors: AUTH_INSUFFICIENT_ROLE (not a credit-line account), AUTH_TOKEN_EXPIRED (sign in again), VALIDATION_ERROR (bad dates or a window over 93 days), PROVIDER_ERROR with serviceUnavailable: true (retry shortly). Limit: 6 calls per minute.
list_settlements
Requiere autenticacionThe partner's own bank-transfer settlements of the credit line. This is the list of transfers, not per-booking payment state (that is on each statement row). Takes no arguments.
Respuesta
| Campo | Tipo | Descripcion | |
|---|---|---|---|
| settlements[] | array | reference, status, amount, currency, createdAt, expiresAt, and receivedAmount / receivedAt once the transfer arrived. | |
| payable[] | array | Transfers still awaiting funds. | |
| bank | object | The account to pay into (beneficiary, IBAN, BIC). | |
| notice | string | Show this to the user exactly as given: anything sent above the outstanding balance is held as credit, not refunded. |
Limit: 20 calls per minute. Creating or cancelling a transfer is not available through MCP.
get_statement_document
Requiere autenticacionThe partner's own monthly statement of account, exactly as it was sent. Statements exist only for months already issued; any other month returns RESOURCE_NOT_FOUND.
Solicitud
| Campo | Tipo | Req. | Descripcion |
|---|---|---|---|
| period | string | Yes | Statement month, YYYY-MM. |
| format | string | No | pdf (default) or csv. |
Respuesta
| Campo | Tipo | Descripcion | |
|---|---|---|---|
| filename / mimeType | string | The document name and type. | |
| csv | string | No | format=csv: the CSV as text. |
| (embedded resource) | resource | No | format=pdf over MCP: the PDF as an embedded resource (base64). Over REST POST /mcp/tools/get_statement_document the PDF is in contentBase64. |
Limit: 6 calls per minute.
Especificaciones legibles por maquina: OpenAPI 3.1 | Tool List | MCP Discovery | GraphQL B2B Docs
LockTrip Hotel Booking MCP API v1.0.0