Reservations
Developers (API)REST API v1
Reservations are how every booking reaches Effective Tours. Availability is computed from units and reservations, so every booking made in your system must be written here. This page covers the seven reservation operations. Response bodies are abbreviated and use fictional values.
Write calls are real. There is no sandbox. A reservation you create, change or cancel is saved at once and triggers an availability update to the connected channels.
A reservation written through the API does not send a guest voucher or confirmation e-mail, and does not notify the owner. Your system is responsible for those communications.
Who sees guest data
- The hotel owner sees guest data on every reservation.
- An agent or distributor company sees guest data only on reservations it created itself. On all others
first_name,last_nameandclientarenullandcommentis"". Dates, room, rate, status, head count and price stay. - The basic list (
full=false, the default) carries no guest data for anyone.
List reservations
GET /hotels/{hotel_id}/reservations takes the query parameters full, start and end (dates as YYYY-MM-DD). With full=true you get the detailed form with guest and price data, subject to the rule above.
There is no pagination and no cap. Without start you get the stays that end after today. Without end there is no upper bound. Always send both start and end, and read in windows.
curl -s "https://api.effectivetours.com/v1/hotels/{hotel_id}/reservations?full=true&start=2027-03-01&end=2027-03-31" \
-H "Authorization: Bearer $ET_API_KEY"Example response (full form, abbreviated to one reservation):
[
{
"id": 9001,
"checkin": "2027-03-10",
"checkout": "2027-03-12",
"is_accepted": true,
"adults": 2,
"children": 0,
"is_fake": false,
"room": {
"id": 2001,
"name": "Double Room",
"sgl": true,
"dbl": true,
"tpl": false,
"apartment": false,
"is_virtual": false
},
"rate": {
"id": 6001,
"name": "Standard",
"food": "room_only"
},
"channel": null,
"first_name": "Jane",
"last_name": "Example",
"price": "240.00",
"revenue": "240.00",
"comment": "",
"reference_code": "PMS-2027-0001",
"client": {
"id": 9501,
"name": "Jane Example",
"first_name": "Jane",
"last_name": "Example",
"email": "[email protected]",
"phone": "+000000000"
}
}
]The basic form has only id, checkin, checkout, is_accepted, adults, children, is_fake, room, rate and channel. For a booking that came from a channel, channel holds the channel booking id, the name and the rate_plan_id.
Create a reservation
POST /hotels/{hotel_id}/reservations creates a reservation and answers 201. Required fields are accommodation, checkin and checkout. accommodation is sgl, dbl, tpl or full (lower case; full is the whole unit). The OpenAPI document types it as a plain string and lists no values; any other value is refused with 422. Book a specific room with room_id. Or omit room_id and give rate_id (the room type), and the server picks an available room for the dates.
Set your own booking id in reference. It is the idempotency key. The spec says: when a non-empty reference is supplied and a live reservation already exists for that company and reference, the existing reservation is returned with status 200 instead of creating a duplicate, and a replay never double-books. Another company's reservation with the same reference is never returned.
curl -s -X POST "https://api.effectivetours.com/v1/hotels/{hotel_id}/reservations" \
-H "Authorization: Bearer $ET_API_KEY" \
-H "Content-Type: application/json" \
-d '{"room_id": 2001, "accommodation": "dbl", "checkin": "2027-03-10", "checkout": "2027-03-12", "adults": 2, "children": 0, "reference": "PMS-2027-0001", "first_name": "Jane", "last_name": "Example", "email": "[email protected]", "price": "240.00"}'Example response:
{
"id": 9001,
"checkin": "2027-03-10",
"checkout": "2027-03-12",
"is_accepted": false,
"adults": 2,
"children": 0,
"is_fake": false,
"room": {
"id": 2001,
"name": "Double Room",
"sgl": true,
"dbl": true,
"tpl": false,
"apartment": false,
"is_virtual": false
},
"rate": {
"id": 6001,
"name": "Standard",
"food": "room_only"
},
"channel": null,
"first_name": "Jane",
"last_name": "Example",
"price": "240.00",
"revenue": null,
"comment": "",
"reference_code": "PMS-2027-0001",
"client": null
}The reservation records your company as its author. Only the author may cancel it. Optional fields are children, is_accepted, phone, comment and revenue.
Get one reservation
GET /hotels/{hotel_id}/reservations/{id} returns one reservation in the detailed form, with the same guest-data rule.
curl -s "https://api.effectivetours.com/v1/hotels/{hotel_id}/reservations/{id}" \
-H "Authorization: Bearer $ET_API_KEY"The example response has the same shape as one item of the full list above.
Change a reservation
PATCH /hotels/{hotel_id}/reservations/{reservation_id} updates only the fields you send. The id in the body is required and must match the reservation_id in the URL. You can change guest fields, room_id, rate_id, accommodation, dates, head count, reference, comment and is_accepted.
Only the company that owns the reservation's room (the hotel owner) may update it. For any other company the reservation answers 404, as if it did not exist. An agent that owns the room also needs full access to the hotel, or the answer is 403.
curl -s -X PATCH "https://api.effectivetours.com/v1/hotels/{hotel_id}/reservations/{reservation_id}" \
-H "Authorization: Bearer $ET_API_KEY" \
-H "Content-Type: application/json" \
-d '{"id": 9001, "checkin": "2027-03-11", "checkout": "2027-03-13", "is_accepted": true}'The example response has the same shape as the create response, with the new values.
Cancel by id
DELETE /hotels/{hotel_id}/reservations/{reservation_id} is a soft delete: the data stays for audit, and direct child reservations are cancelled too. Only the company that created the reservation may delete it. Cancelling an already cancelled reservation is a success no-op (200), so a retry is safe.
curl -s -X DELETE "https://api.effectivetours.com/v1/hotels/{hotel_id}/reservations/{reservation_id}" \
-H "Authorization: Bearer $ET_API_KEY"Example response:
{
"status": "OK"
}Cancel by reference
DELETE /hotels/{hotel_id}/reservations with the reference query parameter cancels every live reservation your company created with that reference, so you do not need to store the numeric id. Repeating the call after everything is cancelled is a success no-op (200). If your company never had a reservation with that reference, the answer is 404.
curl -s -X DELETE "https://api.effectivetours.com/v1/hotels/{hotel_id}/reservations?reference=PMS-2027-0001" \
-H "Authorization: Bearer $ET_API_KEY"Example response:
{
"status": "OK",
"cancelled": 1
}Cancelled channel bookings
When a guest cancels on a channel, the booking leaves the reservations list. GET /hotels/{hotel_id}/bookings/cancelled returns them. It takes start and end. With both, it returns bookings where checkin is before end and checkout is after start. With no dates, it returns bookings whose checkout is today or later. The hotel owner sees the guest data. For an agent or distributor company every guest field is empty, because channel bookings have no author on this API.
curl -s "https://api.effectivetours.com/v1/hotels/{hotel_id}/bookings/cancelled?start=2027-03-01&end=2027-03-31" \
-H "Authorization: Bearer $ET_API_KEY"Example response (abbreviated to one booking):
{
"bookings": [
{
"channel": "Example Channel",
"channel_id": "EX-1001",
"rate_plan_id": null,
"room_type": "Double Room",
"checkin": "2027-03-20",
"checkout": "2027-03-22",
"room_count": 1,
"adults": 2,
"children": 0,
"currency": "USD",
"tax": "0.00",
"fees": "0.00",
"price": "240.00",
"commission": "0.00",
"guest": {
"name": "Jane",
"surname": "Example",
"email": "[email protected]"
},
"booking_date": "2027-01-05",
"room_extra_info": null
}
]
}Errors
| Status | Body or meaning |
|---|---|
400 | {"detail":"Room is not available for this period"}, or invalid data on update. |
401 | {"detail":"Invalid API key"} (also an inactive company). |
403 | {"detail":"You are not allowed to access this hotel"} on a write without access. |
404 | {"detail":"Hotel not found"} on a read without access, or {"detail":"Reservation not found"}. |
409 | No room of the requested type is available for the dates when the server auto-assigns a room. detail is a list. Also {"error":"company_moved"}, which uses the key error. |
410 | {"detail":"Requested HotelID: <id> not found."} for a hotel of your company that was removed. |
422 | The standard validation error. |
503 | {"detail":"Authentication backend unavailable"}. Back off and retry. |
Related: Hotels, rooms and rates for the ids, Channel update to resend availability, and the overview.