# Making an air booking The steps below explain how to create a new air booking for a traveler. ## Prerequisites Before using the [get air itineraries](/docs/openapi/airapi#operation/airSearch) API (Step 1) you must: 1. have air travel enabled for your company. 2. have active airline suppliers configured for your company. 3. have a valid `companyId`. If you encounter a `500 Internal Server Error` when using the [get air itineraries](/docs/openapi/airapi#operation/airSearch) API, the following could be the possible causes: - Company not configured for air bookings in the environment - Missing airline content supplier configuration ## Workflow All APIs mentioned below are dependent on each other and the steps described in this section must be executed in the order specified. | Step | Name | Endpoint | Details | | --- | --- | --- | --- | | 1. | [Get air itineraries](/docs/openapi/airapi#operation/airSearch) | `/v2/air/search-flights` | Search for available flights. **Response will contain:** `searchId` `itineraryId` `paginationParameters` `metadata` **Other APIs will use:** `searchId` `itineraryId` | | 1. | [Get flight attributes](/docs/openapi/airapi#operation/airAttributes) | `/v2/air/flight-attributes` | Retrieve flight attributes such as amenities and fare rules for every flight displayed on a search result. **Request body requires:** `searchId` **Response will contain:** `searchId` `itineraryId` `paginationParameters` `metadata` **Other APIs will use:** `searchId` `itineraryId` | | 1. | [Get selected itinerary](/docs/openapi/airapi#operation/airSelectedItinerary) | `/v2/air/selected-itinerary` | View one selected itinerary and its respective details. **Request body requires:** `searchId` `itineraryId` **Response will contain:** Itinerary details for the `itineraryId` provided in the request. | | 1. | [Get flight checkout details](/docs/openapi/airapi#operation/airFlightCheckout) | `/v2/air/flight-checkout` | Get checkout related information for a selected itinerary from Step 3. **Request body requires:** `searchId` `itineraryId` **Response will contain:** `checkoutResponseId`, baggage information, ancillaries, other checkout parameters and supported payment options. **Other APIs will use:** `checkoutResponseId` | | 1. | [Get flight seat map](/docs/openapi/airapi#operation/airSeatMap) | `/v2/air/seat-map` | View the seat map for the selected itinerary from Step 3. **Request body requires:** `airItineraryId` (an object wrapper containing both `searchId` and `itineraryId` from Step 1) and traveler information. **Response will contain:** `seatMapResponseId` `travelerSeatMaps` `travelerId` `flightSeatMapIds` `seatMaps` `seatMapId` **Other APIs will use:** `seatMapResponseId` | | 1. | [List trips for a company](/docs/openapi/tripapi/trips/getcompanytripsummarieslist) (optional) | `/v3/trips/companies/{companyId}/list` | During the checkout process, you can use this API to choose a trip name from the list of existing names or create a new trip name in the next step. **Request body requires:** `paginationRequestParams`, `tripFilters`, `sortOptions > sortField` to specify start and end dates, and `sortOptions > sortOrder` to determine how to arrange the results. **URL path requires:** `companyId` **Response will contain:** `tripId` **Other APIs will use:** `tripId` | | 1. | [Create trip](/docs/openapi/tripapi#operation/createTrip) | `/v2/trips` | Trips act as a container to group one or more related PNRs (bookings). You must provide a unique value for the `tripName` parameter. If you've already picked an existing trip name in Step 6, you can skip this step. **Request body requires:** `tripName` **Response will contain:** `tripId` **Other APIs will use:** `tripId` | | 1. | [Initiate booking](/docs/openapi/airapi#operation/airInitiateBooking) | `/v2/air/initiate-booking` | Initiate the booking process for the new trip created in Step 7. **Request body requires:** `initiateBookingWorkflowIds > checkoutResponseId` from Step 4, `initiateBookingWorkflowIds > seatMapResponseId` from Step 5, traveler details, `bookingCharges`, and `bookingContact`. **Response will contain:** `initiateBookingResponseId` **Other APIs will use:** `initiateBookingResponseId` | | 1. | [Validate itinerary](/docs/openapi/airapi#operation/airRevalidateItinerary) | `/v2/air/revalidate-itinerary` | To finalize a reservation, the travelers must indicate their preferred seat, number of checked and carry-on bags, and select whether they want any ancillaries such as travel insurance or priority boarding (applied as additional booking charges). Use this API to validate your itinerary. **Request body requires:** `tripId` from Step 7, traveler details, `bookingCharges > paymentMethod > selectedPaymentSource > paymentSourceId`, and `workflowIds` containing the below parameters: ```json { "workflowIds": { "checkoutResponseId": "", "seatMapResponseId": "", "initiateBookingId": "" } } ``` ***Note:** Contact your Spotnana representative to obtain the* `paymentSourceId`. **Response will contain:** `bookingId`, fare breakdown, leg prices, and policy details. **Other APIs will use:** `bookingId` | | 1. | [Create air pnr](/docs/openapi/airapi#operation/airCreatePnr) | `/v2/air/create-pnr` | Create a new air booking (PNR) for your trip. **Request body requires:** `bookingId` from Step 9, `initiateBookingId` (i.e., the `initiateBookingResponseId` from Step 8.) **Response will contain:** `pnrId` `sourcePnrId` `pnrStatus` The `pnrId` generated by this API will be used in the [exchange](/docs/spotnana/air_exchange_workflow) and [cancel](/docs/spotnana/air_cancellation_workflow) booking workflows. |