Quick start
1 and 2. Put the selected provider number in every flight endpoint.Response examples show realistic frontend-facing data. Large arrays and deeply nested details are shortened to one representative item.
- Log in once and save
access_token. - Send it as the
x-api-tokenheader on all flight and hotel requests. - Keep the IDs and keys returned by each step; the next request must use those exact values.
- Never decode, edit, or construct fare keys, session UUIDs, hotel IDs, package IDs, or room allocation IDs.
Authentication
Exchange the provided API account credentials for a short-lived access token.
/api/api-auth/loginNo token requiredRequest
{
"username": "YOUR_API_USERNAME",
"password": "YOUR_API_PASSWORD"
}Response
{
"access_token": "eyJ...",
"token_type": "bearer",
"expires_in": 3600
}Save access_token and send it as x-api-token. When the API returns an expired-token response, log in again and retry the original request once.
Customer login for “My bookings”
Log the customer in directly through Gita. This login call does not use the services API token. The two “My bookings” requests then send both the services API token and the signed-in customer's token.
https://gita.sa/api/auth/loginCustomer login{
"email": "customer@example.com",
"password": "CUSTOMER_PASSWORD"
}{
"access_token": "CUSTOMER_ACCESS_TOKEN",
"token_type": "Bearer",
"user": {
"id": 123,
"name": "John Smith",
"email": "customer@example.com"
}
}Keep this access_token separate from the API token. Send it as Authorization: Bearer CUSTOMER_ACCESS_TOKEN.
Common headers
| Header | Value | Purpose |
|---|---|---|
Content-Type | application/json | Required for POST bodies. |
x-api-token | Token from login | Required for flight and hotel calls. |
Authorization | Bearer CUSTOMER_ACCESS_TOKEN | Required only for customer-specific endpoints such as “My bookings.” |
lng | en or ar | Response language. Defaults to English. |
x-country | ISO country code, e.g. EG | Customer country. |
x-currency | Currency code, e.g. EGP | Display/payment currency. |
const headers = {
"Content-Type": "application/json",
"x-api-token": accessToken,
"lng": "en",
"x-country": "EG",
"x-currency": "EGP"
};Flights
Use one provider for the complete flow. The frontend may show provider choices as Provider 1 and Provider 2; no supplier names are needed.
{provider} with 1 or 2 only. Use the response flight's endpoint if results from multiple providers are displayed together.1. Search flights
/api/{provider}/searchProvider: 1 or 2{
"fromAirport": "CAI",
"toAirport": "DXB",
"departureDate": "2026-10-20",
"returnDate": "2026-10-27",
"adults": 1,
"children": 0,
"infants": 0,
"cabinClass": "ECONOMY"
}| Field | Required | Notes |
|---|---|---|
fromAirport, toAirport | Yes | Different three-letter airport codes. |
departureDate | Yes | YYYY-MM-DD; today or later. |
returnDate | No | Omit for one-way; otherwise must be on/after departure. |
adults | Yes | At least 1. |
children, infants | No | Use 0 when none. |
cabinClass | Yes | ECONOMY or BUSINESS. |
Example response
{
"success": true,
"message": "Success",
"data": {
"departure_flights": [
{
"endpoint": "2",
"provider_key": "2|ATPCO",
"legs": [
{
"flight_number": "EK922",
"departure_info": {
"airport_code": "CAI",
"date": "2026-10-20 17:25:00",
"airport_name": "Cairo International Airport"
},
"arrival_info": {
"airport_code": "DXB",
"date": "2026-10-20 22:20:00",
"airport_name": "Dubai International Airport"
},
"airline_info": {
"carrier_code": "EK",
"carrier_name": "Emirates"
}
}
],
"fares": [
{
"fare_key": "W3sicGFja2FnZWQiOmZhbHNlLC4uLn1d",
"fare_info": {
"cabin_types": ["Y"],
"fare_detail": {
"currency_code": "EGP",
"price_info": { "total_fare": 14599 }
},
"free_seats": 9
}
}
],
"minimum_package_price": 14599,
"baggages_text": "2 Bag"
}
]
}
}Save from the response
departure_flights[].endpoint— provider number for the next request.departure_flights[].fares[].fare_key— send asdepartureFareKey.- For a return trip, save the chosen
return_flights[].fares[].fare_keyasreturnFareKey. - Use
legs,fare_info, baggage fields, andminimum_package_pricefor display.
EXPIRED_FLIGHTS, repeat the search.2. Revalidate the selected fare
/api/{endpoint}/fareUse the passenger counts from the search without changing them.
{
"departureFareKey": "FARE_KEY_FROM_SEARCH",
"returnFareKey": "RETURN_FARE_KEY_FROM_SEARCH",
"adults": 1,
"children": 0,
"infants": 0
}Omit returnFareKey for one-way travel.
Example response
{
"success": true,
"message": "Success",
"data": {
"fare_detail": {
"currency_code": "EGP",
"price_info": { "total_fare": 14599 },
"baggages_text": ["2 Bag"],
"cabin_baggages_text": ["1 Bag (7 Kg)"]
},
"offers": [
{
"offer_details": [
{ "name": "ECOSAVER", "descriptions": ["ECOSAVER"] }
],
"total_price": 14599,
"currency_code": "EGP",
"non_refundable": true,
"refundability_text": "Non Refundable",
"exchangeability_text": ["Exchangeable With Fees"],
"baggages_text": ["2 Bag"],
"cabin_baggages_text": ["1 Bag (7 Kg)"],
"meal_text": ["Meal"]
},
{
"offer_details": [
{ "name": "ECOFLEX", "descriptions": ["ECOFLEX"] }
],
"total_price": 17548,
"currency_code": "EGP",
"non_refundable": false,
"refundability_text": "Refundable With Fees"
}
],
"departure_flight": {
"endpoint": "2",
"provider_key": "2|ATPCO"
}
}
}Offers
If data.offers is present, show every offer to the user. Display its price and rules, then build the selected offer value from its detail names:
const selectedOffer = offer.offer_details
.map(detail => detail.name)
.join("|");
// Example: "ECOSAVER"
// A return/multi-part offer can look like: "ECOSAVER|ECOFLEX"| Offer field | Frontend use |
|---|---|
offer_details[].name | Value used to build the booking offer. |
offer_details[].descriptions | Customer-facing offer label/details. |
total_price, currency_code | Offer price. |
refundability_text, exchangeability_text | Rules to display. |
baggages_text, cabin_baggages_text, meal_text | Included services. |
If there is no offers array, continue with the base fare and omit offer from booking.
3. Create the flight booking
/api/{endpoint}/book{
"departureFareKey": "SAME_KEY_USED_FOR_FARE",
"returnFareKey": "SAME_RETURN_KEY_USED_FOR_FARE",
"offer": "ECOSAVER",
"paymentGateway": "paymob",
"redirectUrl": "https://your-app.example/payment-result",
"contact_info": {
"name": "John Smith",
"email": "john@example.com",
"country_code": "20",
"phone": "1000000000"
},
"paxList": [
{
"name": "John",
"lastName": "Smith",
"type": "ADULT",
"birthDate": "1990-01-01",
"gender": "MALE",
"identityInfo": {
"passport": {
"citizenshipCountry": "EG",
"endDate": "2030-01-01",
"no": "A12345678"
},
"notTurkishCitizen": true,
"notPakistanCitizen": true
}
}
],
"usePoints": false,
"useBalance": false
}- Omit
returnFareKeyfor one-way travel. - Omit
offerwhen fare revalidation returned no offers. paxListcounts and types must exactly match the search.- Passenger
type:ADULT,CHILD, orINFANT. gender:MALEorFEMALE.- Names use English letters and spaces. Passport numbers must be unique.
country_code + phonemust total 12 digits.
Successful response
{
"success": true,
"message": "Success",
"bookingId": "FS-...",
"redirectUrl": "https://payment-provider.example/...",
"price": 4232
}Save bookingId and send the browser to redirectUrl to continue payment.
Read flight bookings
Get one confirmed booking
/api/{provider}/bookings/{reference}Send the common headers and replace {reference} with the bookingId returned by the book request. A successful response returns the booking in data, including itinerary, passengers, status, price, and voucher information when available.
{
"success": true,
"data": {
"id": 178991,
"booking_number": "FS-1789910205287",
"booking_reference": "ABC123",
"status": "ticketed",
"finished": false,
"fromLocation": "CAI",
"toLocation": "DXB",
"adult": 1,
"child": 0,
"infant": 0,
"departure": "2026-10-20T00:00:00.000Z",
"return_date": null,
"type": "OneWay",
"currency": "EGP",
"price": 15340,
"cabin_class": "Y",
"chosen_offer": {
"offer_name": "ECOSAVER",
"baggages_text": ["2 Bag"],
"cabin_baggages_text": ["1 Bag (7 Kg)"]
},
"voucher": "https://gita.sa/api/flights-services/v1/public/voucher/FS-1789910205287"
}
}Get the signed-in customer's bookings
/api/{provider}/bookingsCustomer auth requiredSend both authentication headers:
x-api-token: API_ACCOUNT_ACCESS_TOKEN
Authorization: Bearer CUSTOMER_ACCESS_TOKENThe response contains confirmed bookings in data[]. Use each item's booking reference with the single-booking endpoint when a details screen needs a fresh copy.
{
"success": true,
"data": [
{
"id": 178991,
"booking_number": "FS-1789910205287",
"booking_reference": "ABC123",
"status": "ticketed",
"fromLocation": "CAI",
"toLocation": "DXB",
"departure": "2026-10-20T00:00:00.000Z",
"type": "OneWay",
"currency": "EGP",
"price": 15340,
"finished": false
}
]
}Hotels
Hotel searches create a temporary session. Keep the returned uuid unchanged through packages and booking.
/api/hotels/destinations?q=cairoUse this endpoint for destination autocomplete. Use one of the returned values to search:
cities[].latitudeandcities[].longitude→ search withlocation.hotels[].hotelId→ search withhotelIds: [hotelId].
For featured destinations use /api/hotels/destinations?top=1.
Example response
{
"cities": [
{
"nameEn": "Cairo",
"nameAr": "القاهرة",
"countryEn": "Egypt",
"countryAr": "مصر",
"countryCode": "EG",
"latitude": 30.0444,
"longitude": 31.2357,
"isTopCity": false
}
],
"hotels": [
{
"hotelId": 12345,
"nameEn": "Cairo Marriott Hotel",
"nameAr": "فندق ماريوت القاهرة",
"cityName": "Cairo",
"countryLabel": "Egypt",
"starRating": 5
}
],
"landmarks": []
}1. Search hotels
/api/hotels/b2c/search-hotels{
"location": {
"latitude": 30.0444,
"longitude": 31.2357
},
"checkIn": "2026-10-20",
"checkOut": "2026-10-23",
"rooms": [
{
"AdultsCount": 2,
"KidsAges": [7]
}
]
}Example response
{
"errors": [],
"searchId": "80584621",
"uuid": "86cd0d97-4471-45bf-926e-217be17d7ef1",
"data": [
{
"id": 12345,
"address": "16 Saray El Gezira Street, Cairo",
"propertyType": "Hotel",
"displayName": "Cairo Marriott Hotel",
"defaultImage": "https://gita.sa/storage/hotels/12345/main.jpg",
"location": {
"latitude": 30.0571,
"longitude": 31.2241
},
"starRating": 5,
"currency": "EGP",
"price": 6850
}
]
}Supply exactly one destination style:
// Exact hotel(s)
{ "hotelIds": [12345] }
// Coordinates
{ "location": { "latitude": 30.0444, "longitude": 31.2357 } }checkIn and checkOut use YYYY-MM-DD. Each room needs at least one adult; use an empty KidsAges array when there are no children.
Save from the response
uuid— required by all following hotel requests.data[].id— selected hotel ID.- Use
displayName,defaultImage,starRating,price,currency, andlocationfor the results UI.
2. Load hotel details and packages
/api/hotels/b2c/packages{
"uuid": "UUID_FROM_HOTEL_SEARCH",
"hotelID": 12345
}Example response
{
"errors": [],
"uuid": "86cd0d97-4471-45bf-926e-217be17d7ef1",
"packages": [
{
"hotelId": 12345,
"packageId": "PKG-982731",
"price": {
"currency": "EGP",
"finalPrice": 20550,
"originalPrice": 19800,
"taxesAndFees": 750
},
"refundability": 1,
"refundabilityNew": true,
"refundableUntil": "2026-10-17",
"rooms": [
{
"id": "ROOM-1-DBL",
"adultsCount": 2,
"kidsAges": [7],
"availability": 3,
"roomBasisCode": "Bed and Breakfast BB",
"roomBasis": "Bed and Breakfast BB",
"roomName": "Deluxe Nile View Room"
}
],
"remarks": []
}
],
"hotelContent": {
"descriptions": [
{ "title": "Hotel", "description": "Five-star hotel in central Cairo.", "language": "en" }
],
"facilities": [
{ "facility": "Free WiFi", "facilityType": "General" }
],
"images": ["https://gita.sa/storage/hotels/12345/1.jpg"]
}
}The response includes hotelContent and a packages array. For the booking form, save:
packages[].packageId→packageID.packages[].rooms[].id→ each passenger'sAllocation.- Room adult counts and child ages determine the exact passenger list required at booking.
- Use package price, rooms, meal/board, and refundability fields for display.
If content is needed separately:
/api/hotels/b2c/hotel-content{
"uuid": "UUID_FROM_HOTEL_SEARCH",
"hotelID": 12345
}Example response
{
"data": {
"descriptions": [
{
"title": "Hotel",
"description": "Five-star hotel in central Cairo.",
"language": "en",
"line": 1
}
],
"facilities": [
{
"facility": "Free WiFi",
"facilityIcon": "https://gita.sa/storage/hotel-facilities/Free%20WiFi.svg",
"facilityType": "General"
}
],
"images": ["https://gita.sa/storage/hotels/12345/1.jpg"]
}
}3. Create the hotel booking
/api/hotels/b2c/book{
"uuid": "UUID_FROM_HOTEL_SEARCH",
"hotelID": 12345,
"packageID": "PACKAGE_ID_FROM_PACKAGES",
"leadPaxID": "guest-1",
"leadPaxAllocation": "ROOM_ID_FROM_PACKAGE",
"paymentGateway": "paymob",
"redirectUrl": "https://your-app.example/payment-result",
"passengers": [
{
"Id": "guest-1",
"Allocation": "ROOM_ID_FROM_PACKAGE",
"PersonDetails": {
"Name": {
"GivenName": "John",
"Surname": "Smith",
"NamePrefix": "Mr"
},
"Type": 0
},
"Email": { "Value": "john@example.com" },
"Telephone": { "PhoneNumber": "201000000000" }
},
{
"Id": "guest-2",
"Allocation": "ROOM_ID_FROM_PACKAGE",
"PersonDetails": {
"Name": {
"GivenName": "Jane",
"Surname": "Smith",
"NamePrefix": "Miss"
},
"Type": 1,
"Age": 7
}
}
],
"usePoints": false,
"useBalance": false
}| Rule | Requirement |
|---|---|
| Passenger IDs | Frontend-generated unique strings. leadPaxID must match one passenger's Id. |
| Allocation | Must be an actual room id from the selected package. Lead passenger allocation must equal leadPaxAllocation. |
| Type | 0 = adult, 1 = child. The lead passenger must be an adult. |
| Child age | Required for children and must match an age requested for that room. |
| Adult contact | Adults require a valid email and a 12-digit international phone number without +. |
| Occupancy | Passenger count, types, ages, and room allocations must exactly match the selected package. |
Successful response
{
"success": true,
"message": "Booking created and payment session initialized successfully",
"bookingId": 123,
"redirectUrl": "https://payment-provider.example/...",
"paymentId": 456,
"price": 2500
}Read hotel bookings
Get one confirmed booking
/api/hotels/b2c/bookings/{reference}Send the common headers and replace {reference} with the hotel bookingId or confirmed provider reference. The response returns the booking in data, including hotel, stay, package, guests, payment status, confirmation number, and voucher URL when available.
{
"success": true,
"data": {
"id": 123,
"hotel_id": 12345,
"hotel_name": "Cairo Marriott Hotel",
"amount": 20550,
"amount_to_pay": 21578,
"currency": "EGP",
"status": "confirmed",
"payment_status": "paid",
"adults": 2,
"children": 1,
"customer_name": "John Smith",
"provider_reference": "HTL-849271",
"booking_status": "confirmed",
"confirmation_number": "HTL-849271",
"search_data": {
"checkIn": "2026-10-20",
"checkOut": "2026-10-23",
"location": { "latitude": 30.0444, "longitude": 31.2357 }
},
"package": {
"packageId": "PKG-982731",
"nights": 3,
"rooms": [
{ "id": "ROOM-1-DBL", "roomName": "Deluxe Nile View Room" }
]
},
"voucher": "https://gita.sa/api/booking-node/voucher?providerReference=HTL-849271"
}
}Get the signed-in customer's bookings
/api/hotels/b2c/bookingsCustomer auth requiredSend both authentication headers:
x-api-token: API_ACCOUNT_ACCESS_TOKEN
Authorization: Bearer CUSTOMER_ACCESS_TOKENThe response contains paid hotel bookings in data[]. Useful list fields include id, hotel_name, search_data, package, amount_to_pay, currency, status, finished, and voucher.
{
"success": true,
"data": [
{
"id": 123,
"hotel_id": 12345,
"hotel_name": "Cairo Marriott Hotel",
"amount_to_pay": 21578,
"currency": "EGP",
"status": "confirmed",
"payment_status": "paid",
"adults": 2,
"children": 1,
"finished": false,
"search_data": {
"checkIn": "2026-10-20",
"checkOut": "2026-10-23"
},
"voucher": "https://gita.sa/api/booking-node/voucher?providerReference=HTL-849271"
}
]
}Error handling
| Status / code | Frontend action |
|---|---|
401 / 403 | Check the API token. If expired, log in again and retry once. |
400 | Show message; the request or selected item is invalid. |
422 | Use the errors object to display field validation messages. |
EXPIRED_FLIGHTS | Restart from flight search. |
EXPIRED_HOTELS | Restart from hotel search to obtain a new uuid. |
EXPIRED_COUNTRY / EXPIRED_CURRENCY | Correct the corresponding request header. |