API Reference
REST API endpoints for booking requests
API Reference
REST API endpoints for managing booking requests. All endpoints require authentication.
Base URLs
| Environment | URL |
|---|---|
| Development | http://localhost:4001/v1 |
| Staging | https://api-staging.rahal.app/v1 |
| Production | https://api.rahal.app/v1 |
User Endpoints
Endpoints for regular users to manage their own requests.
Create Booking Request
Create a new booking request.
POST /booking-requestsRequest Body:
{
"totalPrice": 1500.00,
"currency": "IQD",
"requestNotes": "Business trip to London",
"requestedForUserId": "user_123", // Optional: for delegation
"flightItems": [
{
"originLocationId": "loc_bgw",
"originLocationType": "airport",
"originCode": "BGW",
"originName": "Baghdad",
"destinationLocationId": "loc_lhr",
"destinationLocationType": "airport",
"destinationCode": "LHR",
"destinationName": "London Heathrow",
"departureDate": "2025-03-15",
"departureTime": "08:00",
"arrivalDate": "2025-03-15",
"arrivalTime": "14:00",
"airline": "Emirates",
"airlineCode": "EK",
"flightNumber": "EK102",
"cabinClass": "Economy",
"adultsCount": 1,
"childrenCount": 0,
"infantsCount": 0,
"price": 750.00,
"currency": "IQD"
}
],
"hotelItems": [
{
"cityId": "city_lon",
"cityCode": "LON",
"cityName": "London",
"hotelId": "hotel_123",
"hotelName": "Holiday Inn Express",
"hotelStars": 3,
"checkInDate": "2025-03-15",
"checkOutDate": "2025-03-18",
"price": 750.00,
"currency": "IQD",
"roomOccupancy": [
{
"roomName": "Standard Double",
"boardBasis": "BB",
"adultsCount": 1,
"childrenCount": 0,
"childrenAges": []
}
]
}
],
"travelers": [
{
"travelerId": "traveler_456",
"travelerTypeCode": "ADT"
}
]
}Response: 201 Created
{
"status": "success",
"data": {
"id": "req_abc123",
"status": "PENDING",
// ... full booking request object
}
}Errors:
| Status | Code | Description |
|---|---|---|
| 400 | BAD_REQUEST | Validation error (missing fields, invalid data) |
| 403 | FORBIDDEN | Policy blocks booking, budget blocks, or invalid delegation |
Get My Requests
List the current user's booking requests.
GET /booking-requests/my-requestsQuery Parameters:
| Parameter | Type | Description |
|---|---|---|
page | number | Page number (default: 1) |
perPage | number | Items per page (default: 20) |
status | string | Filter by status (comma-separated) |
search | string | Search by text |
startDate | ISO date | Filter by created date (from) |
endDate | ISO date | Filter by created date (to) |
delegationFilter | string | "all", "my_requests", "delegated" |
Response: 200 OK
{
"status": "success",
"data": {
"bookingRequests": [...],
"total": 42,
"page": 1,
"perPage": 20
}
}Get Request by ID
Get a single booking request by ID.
GET /booking-requests/:idResponse: 200 OK
{
"status": "success",
"data": {
"id": "req_abc123",
"companyId": "company_xyz",
"requestedByUserId": "user_456",
"totalPrice": 1500.00,
"currency": "IQD",
"status": "PENDING",
"requestNotes": "Business trip",
"createdAt": "2025-01-20T10:30:00Z",
"updatedAt": "2025-01-20T10:30:00Z",
"company": { ... },
"requestedBy": { ... },
"flightItems": [ ... ],
"hotelItems": [ ... ],
"travelers": [ ... ]
}
}Errors:
| Status | Code | Description |
|---|---|---|
| 403 | FORBIDDEN | Not authorized to view this request |
| 404 | NOT_FOUND | Request not found |
Cancel Request
Cancel a pending booking request.
POST /booking-requests/:id/cancelResponse: 200 OK
{
"status": "success",
"data": {
"id": "req_abc123",
"status": "CANCELLED",
// ... full booking request object
}
}Errors:
| Status | Code | Description |
|---|---|---|
| 400 | BAD_REQUEST | Only pending requests can be cancelled |
| 403 | FORBIDDEN | Not authorized to cancel this request |
| 404 | NOT_FOUND | Request not found |
Admin Endpoints
Endpoints for administrators to manage all company requests.
List All Requests
Get all booking requests (admin view).
GET /admin/booking-requestsQuery Parameters:
| Parameter | Type | Description |
|---|---|---|
page | number | Page number |
perPage | number | Items per page |
companyId | string | Filter by company |
status | string | Filter by status (comma-separated) |
search | string | Search by user name/email |
startDate | ISO date | Filter by created date (from) |
endDate | ISO date | Filter by created date (to) |
serviceType | string | "flights", "hotels" (comma-separated) |
minPrice | number | Minimum total price |
maxPrice | number | Maximum total price |
minTravelers | number | Minimum traveler count |
maxTravelers | number | Maximum traveler count |
sortBy | string | "createdAt", "totalPrice", "status" |
sortOrder | string | "asc", "desc" |
Response: 200 OK
{
"status": "success",
"data": {
"bookingRequests": [...],
"total": 156,
"page": 1,
"perPage": 20
}
}Update Request
Update a booking request's editable fields.
PATCH /admin/booking-requests/:idRequest Body:
{
"totalPrice": 1600.00,
"currency": "IQD",
"requestNotes": "Updated notes"
}Only totalPrice, currency, and requestNotes can be updated. For pending requests, all three are editable. For completed/cancelled, only notes.
Response: 200 OK
Update Status
Change a request's status (complete or cancel).
PATCH /admin/booking-requests/:id/statusRequest Body:
{
"status": "COMPLETED"
}Response: 200 OK
Errors:
| Status | Code | Description |
|---|---|---|
| 400 | BAD_REQUEST | Invalid status transition |
| 404 | NOT_FOUND | Request not found |
Flight Item Endpoints
Manage flight items within a booking request.
Add Flight Item
POST /admin/booking-requests/:id/flightsUpdate Flight Item
PATCH /admin/booking-requests/:id/flights/:flightIdDelete Flight Item
DELETE /admin/booking-requests/:id/flights/:flightIdHotel Item Endpoints
Manage hotel items within a booking request.
Add Hotel Item
POST /admin/booking-requests/:id/hotelsUpdate Hotel Item
PATCH /admin/booking-requests/:id/hotels/:hotelIdDelete Hotel Item
DELETE /admin/booking-requests/:id/hotels/:hotelIdTraveler Endpoints
Manage travelers within a booking request.
Add Traveler
POST /admin/booking-requests/:id/travelersRequest Body:
{
"travelerId": "traveler_789"
}Remove Traveler
DELETE /admin/booking-requests/:id/travelers/:travelerIdError Response Format
All errors follow the JSend format:
{
"status": "fail",
"message": "Human-readable error message",
"data": {
"field": "Specific field error"
}
}Or for server errors:
{
"status": "error",
"message": "Internal server error",
"requestId": "req_tracking_id"
}Authentication
All endpoints require a valid JWT token:
Authorization: Bearer <token>Admin endpoints additionally require appropriate permissions:
| Permission | Code | Required For |
|---|---|---|
| Read Booking Requests | READ_BOOKING_REQUESTS | List, get all company requests |
| Update Booking Requests | UPDATE_BOOKING_REQUESTS | Modify request details, add/edit items |
| Process Booking Requests | PROCESS_BOOKING_REQUESTS | Complete or cancel requests |
User endpoints use:
| Permission | Code | Required For |
|---|---|---|
| Read User Booking Requests | READ_USER_BOOKING_REQUESTS | View own requests |
| Write User Booking Requests | WRITE_USER_BOOKING_REQUESTS | Create and cancel own requests |