Hotel guides
Booking statuses
Creating a booking starts a process that doesn't always finish in one request. The booking's state tells you where it is and what, if anything, you need to do.
States at a glance
| State | Meaning | What to do |
|---|---|---|
confirmed | Booked and confirmed. | Show the confirmation; fetch the voucher. |
supplier_pending | Confirmation still in progress. Credit is reserved for a paid booking; a hold that is still pending has nothing paid yet. | Check again every 15 s (below). Don't book again. |
held | Room reserved without payment until a deadline. | Pay before order.held.paymentDeadline, or cancel. |
failed | Not booked. Nothing is charged. | Price-check and try again with a new idempotency key. |
manual_review | Our operations team needs to finish this booking by hand. | Don't rebook. We'll resolve it and update the state. |
cancel_requested | A cancellation is in progress. | Wait. It moves to cancelled, to manual_review if it can't be completed automatically, or back to confirmed. |
cancelled | Cancelled. | Nothing, unless a refund is due. |
refund_pending | Cancelled; a refund is being processed. | Nothing. |
refunded | Cancelled and refunded. | Nothing. |
You may briefly see price_checked or credit_approved on a booking that is still being created. Treat them like supplier_pending. New states may be added; treat any state you don't recognise as pending and check again.
What POST /bookings returns
The create call returns 201 with the booking's ID, your reference and its state:
{ "data": { "bookingId": "66f1d2c4e4b0c1d2e3f4b010", "orderRef": "RV-2026-4CD5ADB2", "state": "confirmed" }, "meta": {}, "error": null }Store bookingId (for API calls) and orderRef (the reference people use — quote it to our support team) against your own order before doing anything else with the response.
Waiting for confirmation
Most bookings confirm inside the create call. Some inventory confirms asynchronously, and a flight that is paid but not yet ticketed waits for its tickets; those return supplier_pending. Ask for an update with POST /bookings/:id/refresh-status, which checks with the inventory source and returns the latest state:
async function waitForConfirmation(bookingId) {
// Check every 15 s for up to 10 minutes.
for (let tries = 0; tries < 40; tries++) {
const { data } = await call('POST', '/bookings/' + bookingId + '/refresh-status');
if (data.state !== 'supplier_pending') return data.state;
await sleep(15_000);
}
return 'supplier_pending'; // keep checking GET /bookings/:id in the background
}- Poll every 15 seconds for up to 10 minutes. Many pending bookings settle within a few minutes, but some take longer.
- If it is still pending after that, tell the traveller confirmation is on its way and keep checking
GET /bookings/:idevery few minutes. If it is still pending close to travel, email support with theorderRef. - The API doesn't send webhooks. The booking's agent also gets an email when it is confirmed or fails — for bookings made with an API key, that is the admin who created the key. Travellers aren't emailed automatically.
Reading a booking
curl "https://api.roaveagents.com/api/v1/bookings/66f1d2c4e4b0c1d2e3f4b010" \
-H "X-API-Key: $ROAVE_API_KEY"{
"data": {
"order": {
"orderRef": "RV-2026-4CD5ADB2",
"state": "confirmed",
"paymentMethod": "credit",
"totalSell": { "amountMinor": 51120, "currency": "USD" },
"travelers": [ ... ]
},
"lineItems": [
{
"productType": "hotel",
"state": "confirmed",
"supplierConfirmationId": "4471902",
"sell": { "amountMinor": 51120, "currency": "USD" },
"details": { "hotelConfirmationRef": "88213540", ... }
}
],
"cancellationPolicy": { "refundable": true, "deadlines": [ ... ] },
"earnings": { ... }
},
"meta": {},
"error": null
}A booking is an order with one or more lineItems. For hotels, supplierConfirmationId is the booking reference with the inventory source. The property's own number — the one front desks recognise — is in the line item's details.hotelConfirmationRef, or details.hotelConfirmationRefs with one entry per room. If our operations team records a number, it appears as the line item's hotelConfirmationNumber. The simplest way to show it is the voucher's hotelConfirmationNumber, which resolves all of these. The hotel's number can arrive some time after the booking confirms, so read it again closer to arrival if it's missing.
Failed bookings
A failed booking was declined — most often because the room sold out between price-check and booking. Nothing is charged. order.failureReason, when present, is a short machine code such as supplier_rejected — log it, but don't parse it or show it to travellers; it doesn't carry the inventory source's reason, and other values may appear. The quote goes back to price-checked, so you can:
- price-check the same quote again (or pick another rate if it's gone), then
- book with a new
Idempotency-Key. Reusing the old key replays the failure.
Manual review
manual_review means the outcome needs a person: the inventory source gave an ambiguous answer, or a cancellation couldn't be completed automatically — most flight cancellations land here. Our operations team resolves these. Don't create a replacement booking — you could end up with two. If the traveller is travelling soon, email support@roaveagents.com with the orderRef.
Holds
A hold reserves a hotel room now and lets you pay later — useful while a client decides. Send hold: true when you book:
{
"quoteId": "66f1c0b8e4b0c1d2e3f4a7a2",
"paymentMethod": "credit",
"hold": true,
"travelers": [
{ "firstName": "Anna", "lastName": "Smith", "email": "anna.smith@example.com", "phone": "+447700900123", "roomIndex": 0 },
{ "firstName": "Ben", "lastName": "Smith", "roomIndex": 0 }
]
}- Hotels only, and only on fully refundable rates whose free-cancellation deadline is still in the future. Otherwise you get
400 hold_not_eligible. - The booking comes back
held.order.held.paymentDeadlineis 24 hours before the free-cancellation deadline. - Pay before the deadline with
POST /bookings/:id/pay. The agent on the booking gets reminder emails as it approaches. - Unpaid holds are cancelled automatically once the payment deadline passes, so the room is released before any cancellation charge applies. Paying after the deadline is refused.
curl -X POST "https://api.roaveagents.com/api/v1/bookings/66f1d2c4e4b0c1d2e3f4b010/pay" \
-H "X-API-Key: $ROAVE_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 2f5a1d8e-3c4b-4e6f-8a9b-7c1d2e3f4a5b" \
-d '{ "paymentMethod": "credit" }'Listing bookings
GET /bookings lists every booking your agency has made, newest first. Filter with state (confirmed, held, cancelled, failed), trip (upcoming, traveling, past), status (active, cancelled) and q (reference, guest or hotel name). See the reference for every option.
A trip filter on its own leaves out cancelled bookings — including those being cancelled or refunded. To list cancelled trips, add status=cancelled or state=cancelled.
curl "https://api.roaveagents.com/api/v1/bookings?state=confirmed&trip=upcoming&limit=50" \
-H "X-API-Key: $ROAVE_API_KEY"