openapi: 3.0.3
info:
title: Airline API
version: v1.1
servers:
- url: https://airlines-api.hopper.com/airline/v1.1
tags:
- description: |-
**Hopper Technology Solutions (HTS) Ancillaries for Airlines**
HTS (Hopper Technology Solutions) is providing airlines with its ancillary services. Airlines can integrate these ancillaries within their booking flow to offer additional benefits to their customers. Not only do these ancillaries generate sizable incremental revenue to the airlines, but they also delight their customers by offering them more flexibility and peace of mind.
Two services are currently available through the HTS Ancillaries for Airlines API:
- Cancel For Any Reason™ (CFAR), enabling airlines to offer refundability as an ancillary with HTS powering the dynamic pricing and supporting the refund cost.
- Disruption Guarantee™ (DG), offering a premium disruption assistance service to customers in case of flight disruption, including rebooking options on any airline or a refund option.
name: HTS Ancillaries for Airlines
- description: |-
This API is authenticated with OAuth 2, Client Credentials grant.\
Clients should use their `client_id` and `client_secret` to obtain an `access_token`.\
The `access_token` should be included in every request, as a `Bearer` token on an `Authorization` header.\
Note that `access_token`s eventually expire, requiring a new token to be fetched.
see [authentication](#tag/Authentication)
name: Authentication
- description: "Hopper uses a unique ID to correlate API calls and events produced\
\ by a user's interaction with an airline application.\nThe duration of the user's\
\ interactions is called a \"session\", and the correlation ID is called a `session_id`.\n\
\nA session begins immediately before the airline’s first API call to Hopper,\
\ and the airline must call the Create a Session endpoint at this time. \nA `session_id`\
\ is returned from this call; it must be included with each subsequent API call\
\ via the `HC-Session-ID` header. \nNo airline action is required to end the session.\n"
name: Sessions
- description: |
**What is Cancel For Any Reason?**
Cancel For Any Reason (CFAR) enables airlines to offer refundability as an ancillary with HTS powering the dynamic pricing and supporting the refund cost.
****
**How it works**
There are two distinct flows for CFAR:
- The _purchase flow_, enabling customers to purchase the product within the airline’s booking flow.
- The _exercise flow_, enabling customers to cancel their booking and get a refund.
For each of these flows, the first step is to [Create a Session](#operation/postSessions)
Both the purchase and the exercise of CFAR should be tracked by the airline in the airline’s Passenger Name Record (PNR) according to the applicable industry standards.
****
**Purchase flow**
CFAR follows the industry standard of a two step purchase process.
1. Once the user is landing on the page displaying the CFAR offer, the airline will call the [Create CFAR Offers](#operation/postCfar_offers) endpoint. CFAR Offers can be created at multiple granular levels. The request must include a description of the Itinerary for which the offers are requested. The response will contain
- the price for the product (`premium`),
- the refundable amount (`coverage`),
- the UTC date and time until when the cancellation can be requested (`contract_expiry_date_time`)
- and the description of the offer in the available languages (`contents`).
2. If a user is attaching CFAR to his booking, the airline will call the [Create CFAR Contract](#operation/postCfar_contracts) endpoint. The request must include the selected `offer_id`(s) and a description of the Itinerary for which the contract is requested, which must match the one of the Offer(s). At this stage, the CFAR Contract is only _created_. It will be confirmed once the customer has made the payment, which can be done in two ways:
1. If the airline is the Merchant of Records (MoR), it will capture the payment for the total amount of the booking, including the CFAR fee amount. Upon a successful payment, the airline will call the Update CFAR Contract Status endpoint to set the CFAR contract to _confirmed_. The airline will track this purchase in its PNR following the industry standards that apply to ticketing or ticketless carriers.
2. If HTS is the Merchant of Records (MoR), the airline will capture the payment for the amount of the booking excluding the CFAR fee, while HTS will capture the payment for the CFAR fee amount. Upon a successful payment of its portion, the airline will call the Process CFAR Payment endpoint for HTS to capture the payment for the CFAR fee amount. Once successful, the CFAR contract will be set to _confirmed_. The airline will track this purchase in its PNR.
The details of a CFAR contract can be retrieved at any time through the Get a CFAR Contract endpoint.
****
**Exercise flow**
CFAR exercise follows a two step process.
1. The user will request the exercise from the “Manage My Bookings” (MMB) page of the airline, through a dedicated Call to action displayed based on the tracker added to the PNR at the time of booking. Once the user is requesting the exercise, the airline will call the [Create CFAR Exercise](#operation/postCfar_contract_exercises) endpoint to authorize the exercise. The request must include the Contract ID, the Itinerary at the time of the exercise request and some optional information on the refund option that may be offered by the airline. If eligible to the exercise, the response will contain the refundable amounts, both in cash and Future Travel Credit (FTC) if applicable.
2. Once the user has followed the steps of the refund portal and confirmed the cancellation request, HTS will make a call back to the airline to launch the PNR update flow on the airline’s end. The actual PNR update flow depends on each airline’s specifics and is not described here. Upon a successful update of the PNR, the airline will confirm the exercise to HTS by calling the [Complete CFAR Exercise](#operation/putCfar_contract_exercisesIdMark_completed) endpoint.
name: Cancel For Any Reason (CFAR)
- description: "**What is Disruption Guarantee?**\n\nDisruption Guarantee (DG) offers\
\ a premium disruption assistance service to customers in case of flight disruption,\
\ including rebooking options on any airline or a refund option.\n\n****\n\n**How\
\ it works**\n\nThere are two distinct flows for DG:\n\n- The _purchase flow_,\
\ enabling customers to purchase the product within the airline’s booking flow.\n\
- The _exercise flow_, enabling customers to benefit from the premium disruption\
\ assistance service in case of a flight disruption.\n\nFor the _purchase flow_,\
\ the first step is to [Create a Session](#operation/postSessions)\n\nBoth the\
\ purchase and the exercise of DG should be tracked by the airline in the airline’\
s Passenger Name Record (PNR) according to the applicable industry standards.\n\
\n****\n\n**Purchase flow**\n\nDG follows the industry standard of a two step\
\ purchase process.\n\n1. Once the user is landing on the page displaying the\
\ DG offer, the airline will call the [Create DG Offers](#operation/postDg_offers)\
\ endpoint. DG Offers can be created at multiple granular levels. The request\
\ must include a description of the Itinerary for which the offers are requested.\
\ The response will contain\n\n - the price for the product (`premium`),\n \
\ - the refundable amount (`coverage`),\n - the maximum price per passenger\
\ for a new flight (`service_cap`),\n - the delay threshold to trigger the policy\
\ (`min_minuted_delay`),\n - the start of the timeframe to trigger the policy\
\ (`max_hours_before_departure`)\n - and the description of the offer in the\
\ user’s language (`contents`).\n\n2. If a user is attaching DG to his booking,\
\ the airline will call the [Create DG Contract](#operation/postDg_contracts)\
\ endpoint. The request must include the selected offer\\_id(s) and a description\
\ of the Itinerary for which the contract is requested, which must match the one\
\ of the Offer. At this stage, the DG Contract is only _created_. It will be confirmed\
\ once the customer has made the payment, which can be done in two ways:\n\n \
\ 1. If the airline is the Merchant of Records (MoR), it will capture the payment\
\ for the total amount of the booking, including the DG fee amount. Upon a successful\
\ payment, the airline will call the Update DG Contract Status endpoint to set\
\ the DG contract to _confirmed_. The airline will track this purchase in its\
\ PNR following the industry standards that apply to ticketing or ticketless carriers.\n\
\ 2. If HTS is the Merchant of Records (MoR), the airline will capture the payment\
\ for the amount of the booking excluding the DG fee, while HTS will capture the\
\ payment for the DG fee amount. Upon a successful payment of its portion, the\
\ airline will call the Process DG Payment endpoint for HTS to capture the payment\
\ for the DG fee amount. Once successful, the DG contract will be set to _confirmed_.\
\ The airline will track this purchase in its PNR.\n \nThe details of a DG contract\
\ can be retrieved at any time through the [Get a DG Contract](#operation/getDg_contractsId)\
\ endpoint.\n\n****\n\n**Exercise flow**\n\nIn this version of the API, the DG\
\ exercise is powered by HTS as a standalone flow, without any endpoint publicly\
\ exposed.\\\nIn a future version of the API, the DG exercise will be initialized\
\ from the “Manage My Bookings” (MMB) page of the airline. New endpoints will\
\ be released to that purpose.\n"
name: Disruption Guarantee (DG)
- description: "In order to measure and continuously improve HTS Ancillaries performance,\
\ specific events occurring during a customer session can be sent by the partner\
\ airlines using some dedicated endpoints."
name: Analytics
paths:
/events:
post:
description: Events can be send directly from partner backend using the same
authentication as the other endpoints
operationId: postEvents
parameters:
- description: "The ID of the current airline session, see [Sessions](#tag/Sessions)"
example: 9fd3f2f9-e5aa-4128-ace9-3c4ee37b685f
explode: false
in: header
name: HC-Session-ID
required: true
schema:
type: string
style: simple
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/event'
required: true
responses:
"204":
description: The event has been successfully created
headers:
Expires:
explode: false
required: true
schema:
type: string
style: simple
Cache-Control:
explode: false
required: true
schema:
type: string
style: simple
"400":
content:
application/json:
schema:
$ref: '#/components/schemas/bad_request'
description: Syntactic errors were encountered while handling the request
"401":
description: The client could not be authenticated
"403":
description: The authenticated client does not have permission to call this
endpoint
"404":
description: The requested resource could not be found
"422":
content:
application/json:
schema:
$ref: '#/components/schemas/unprocessable_entity'
description: Semantic errors were encountered while handling the request
"500":
description: The server encountered an internal error
security:
- PartnerAuth: []
apiKeyAuth: []
summary: Send a Backend Event
tags:
- Analytics
/sessions:
post:
description: Create a new session for which events will be collected.
operationId: postSessions
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/create_airline_session_request'
required: true
responses:
"201":
content:
application/json:
schema:
$ref: '#/components/schemas/airline_session'
description: The created airline session
headers:
Expires:
explode: false
required: true
schema:
type: string
style: simple
Cache-Control:
explode: false
required: true
schema:
type: string
style: simple
"204":
description: The airline session creation request was not performed
headers:
Expires:
explode: false
required: true
schema:
type: string
style: simple
Cache-Control:
explode: false
required: true
schema:
type: string
style: simple
"400":
content:
application/json:
schema:
$ref: '#/components/schemas/bad_request'
description: Syntactic errors were encountered while handling the request
"401":
description: The client could not be authenticated
"403":
description: The authenticated client does not have permission to call this
endpoint
"404":
description: The requested resource could not be found
"422":
content:
application/json:
schema:
$ref: '#/components/schemas/unprocessable_entity'
description: Semantic errors were encountered while handling the request
"500":
description: The server encountered an internal error
security:
- PartnerAuth: []
apiKeyAuth: []
summary: Create a Session
tags:
- Sessions
/cfar_offers:
post:
description: Create CFAR offers for a user's trip
operationId: postCfar_offers
parameters:
- description: "The ID of the current airline session, see [Sessions](#tag/Sessions)"
example: 9fd3f2f9-e5aa-4128-ace9-3c4ee37b685f
explode: false
in: header
name: HC-Session-ID
required: false
schema:
type: string
style: simple
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/create_cfar_offer_request'
required: true
responses:
"201":
content:
application/json:
schema:
items:
$ref: '#/components/schemas/cfar_offer'
type: array
description: The created CFAR offers
headers:
Expires:
explode: false
required: true
schema:
type: string
style: simple
Cache-Control:
explode: false
required: true
schema:
type: string
style: simple
HTS-Session-ID:
description: "The ID of the current session, see [Sessions](#tag/Sessions)"
example: 9fd3f2f9-e5aa-4128-ace9-3c4ee37b685f
explode: false
required: true
schema:
type: string
style: simple
"400":
content:
application/json:
schema:
$ref: '#/components/schemas/bad_request'
description: Syntactic errors were encountered while handling the request
"401":
description: The client could not be authenticated
"403":
description: The authenticated client does not have permission to call this
endpoint
"404":
description: The requested resource could not be found
"422":
content:
application/json:
schema:
$ref: '#/components/schemas/unprocessable_entity'
description: Semantic errors were encountered while handling the request
"500":
description: The server encountered an internal error
security:
- PartnerAuth: []
apiKeyAuth: []
summary: Create CFAR Offers
tags:
- Cancel For Any Reason (CFAR)
/cfar_offers/external:
post:
description: Create a CFAR offer with externally provided pricing and coverage
details (temporal API for data migration)
operationId: postCfar_offersExternal
parameters:
- description: "The ID of the current airline session, see [Sessions](#tag/Sessions)"
example: 9fd3f2f9-e5aa-4128-ace9-3c4ee37b685f
explode: false
in: header
name: HC-Session-ID
required: false
schema:
type: string
style: simple
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/create_external_cfar_offer_request'
required: true
responses:
"201":
content:
application/json:
schema:
$ref: '#/components/schemas/cfar_offer'
description: The created CFAR offer
headers:
Expires:
explode: false
required: true
schema:
type: string
style: simple
Cache-Control:
explode: false
required: true
schema:
type: string
style: simple
HTS-Session-ID:
description: "The ID of the current session, see [Sessions](#tag/Sessions)"
example: 9fd3f2f9-e5aa-4128-ace9-3c4ee37b685f
explode: false
required: true
schema:
type: string
style: simple
"400":
content:
application/json:
schema:
$ref: '#/components/schemas/bad_request'
description: Syntactic errors were encountered while handling the request
"401":
description: The client could not be authenticated
"403":
description: The authenticated client does not have permission to call this
endpoint
"404":
description: The requested resource could not be found
"422":
content:
application/json:
schema:
$ref: '#/components/schemas/unprocessable_entity'
description: Semantic errors were encountered while handling the request
"500":
description: The server encountered an internal error
security:
- PartnerAuth: []
apiKeyAuth: []
summary: Create External CFAR Offer
tags:
- Cancel For Any Reason (CFAR)
/cfar_contracts:
post:
description: Create a CFAR contract from selected CFAR offer(s).
operationId: postCfar_contracts
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/create_cfar_contract_request'
required: true
responses:
"201":
content:
application/json:
schema:
$ref: '#/components/schemas/cfar_contract'
description: The created CFAR contract
headers:
Expires:
explode: false
required: true
schema:
type: string
style: simple
Cache-Control:
explode: false
required: true
schema:
type: string
style: simple
"204":
description: The CFAR contract creation request was successfully validated
but not performed
headers:
Expires:
explode: false
required: true
schema:
type: string
style: simple
Cache-Control:
explode: false
required: true
schema:
type: string
style: simple
"400":
content:
application/json:
schema:
$ref: '#/components/schemas/bad_request'
description: Syntactic errors were encountered while handling the request
"401":
description: The client could not be authenticated
"403":
description: The authenticated client does not have permission to call this
endpoint
"404":
description: The requested resource could not be found
"422":
content:
application/json:
schema:
$ref: '#/components/schemas/unprocessable_entity'
description: Semantic errors were encountered while handling the request
"500":
description: The server encountered an internal error
security:
- PartnerAuth: []
apiKeyAuth: []
summary: Create a CFAR Contract
tags:
- Cancel For Any Reason (CFAR)
/cfar_contracts/{id}:
get:
description: Get a CFAR contract
operationId: getCfar_contractsId
parameters:
- description: A unique identifier for a contract
explode: false
in: path
name: id
required: true
schema:
type: string
style: simple
- description: "The ID of the current airline session, see [Sessions](#tag/Sessions)"
example: 9fd3f2f9-e5aa-4128-ace9-3c4ee37b685f
explode: false
in: header
name: HC-Session-ID
required: false
schema:
type: string
style: simple
responses:
"200":
content:
application/json:
schema:
$ref: '#/components/schemas/cfar_contract'
description: The requested CFAR contract
headers:
Expires:
explode: false
required: true
schema:
type: string
style: simple
Cache-Control:
explode: false
required: true
schema:
type: string
style: simple
"400":
content:
application/json:
schema:
$ref: '#/components/schemas/bad_request'
description: Syntactic errors were encountered while handling the request
"401":
description: The client could not be authenticated
"403":
description: The authenticated client does not have permission to call this
endpoint
"404":
description: The requested resource could not be found
"422":
content:
application/json:
schema:
$ref: '#/components/schemas/unprocessable_entity'
description: Semantic errors were encountered while handling the request
"500":
description: The server encountered an internal error
security:
- PartnerAuth: []
apiKeyAuth: []
summary: Get a CFAR Contract
tags:
- Cancel For Any Reason (CFAR)
/cfar_contracts/{id}/update_status:
put:
description: Update the CFAR contract
operationId: putCfar_contractsIdUpdate_status
parameters:
- description: A unique identifier for a contract
explode: false
in: path
name: id
required: true
schema:
type: string
style: simple
- description: "The ID of the current airline session, see [Sessions](#tag/Sessions)"
example: 9fd3f2f9-e5aa-4128-ace9-3c4ee37b685f
explode: false
in: header
name: HC-Session-ID
required: false
schema:
type: string
style: simple
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/update_cfar_contract_request'
required: true
responses:
"200":
content:
application/json:
schema:
$ref: '#/components/schemas/cfar_contract'
description: The updated CFAR contract
headers:
Expires:
explode: false
required: true
schema:
type: string
style: simple
Cache-Control:
explode: false
required: true
schema:
type: string
style: simple
"204":
description: The CFAR contract status update request was successfully validated
but not performed
headers:
Expires:
explode: false
required: true
schema:
type: string
style: simple
Cache-Control:
explode: false
required: true
schema:
type: string
style: simple
"400":
content:
application/json:
schema:
$ref: '#/components/schemas/bad_request'
description: Syntactic errors were encountered while handling the request
"401":
description: The client could not be authenticated
"403":
description: The authenticated client does not have permission to call this
endpoint
"404":
description: The requested resource could not be found
"422":
content:
application/json:
schema:
$ref: '#/components/schemas/unprocessable_entity'
description: Semantic errors were encountered while handling the request
"500":
description: The server encountered an internal error
security:
- PartnerAuth: []
apiKeyAuth: []
summary: Update CFAR Contract Status
tags:
- Cancel For Any Reason (CFAR)
/cfar_contracts/{id}/forms_of_payment:
put:
description: Update forms of payment linked with a CFAR contract
operationId: putCfar_contractsIdForms_of_payment
parameters:
- description: A unique identifier for a contract
explode: false
in: path
name: id
required: true
schema:
type: string
style: simple
- description: "The ID of the current airline session, see [Sessions](#tag/Sessions)"
example: 9fd3f2f9-e5aa-4128-ace9-3c4ee37b685f
explode: false
in: header
name: HC-Session-ID
required: false
schema:
type: string
style: simple
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/update_cfar_form_of_payment_request'
required: true
responses:
"200":
content:
application/json:
schema:
$ref: '#/components/schemas/cfar_contract'
description: The updated CFAR contract
headers:
Expires:
explode: false
required: true
schema:
type: string
style: simple
Cache-Control:
explode: false
required: true
schema:
type: string
style: simple
"204":
description: Forms of payment update request was successfully validated
but not performed
headers:
Expires:
explode: false
required: true
schema:
type: string
style: simple
Cache-Control:
explode: false
required: true
schema:
type: string
style: simple
"400":
content:
application/json:
schema:
$ref: '#/components/schemas/bad_request'
description: Syntactic errors were encountered while handling the request
"401":
description: The client could not be authenticated
"403":
description: The authenticated client does not have permission to call this
endpoint
"404":
description: The requested resource could not be found
"422":
content:
application/json:
schema:
$ref: '#/components/schemas/unprocessable_entity'
description: Semantic errors were encountered while handling the request
"500":
description: The server encountered an internal error
security:
- PartnerAuth: []
apiKeyAuth: []
summary: Update forms of payment of a CFAR Contract
tags:
- Cancel For Any Reason (CFAR)
/cfar_contracts/{id}/payment:
post:
description: "When HTS is the Merchant of Record (MoR), the customer's credit\
\ card is charged by HTS for the CFAR fee.\n\nHTS is relying on an external\
\ payment gateway to process the payments, it allows the partner airline to\
\ tokenize the customer's credit card details and then pass the generated\
\ token in HTS Ancillaries for Airlines API payment endpoints in order to\
\ process the payment and confirm the contract related to the purchased product.\n\
\n**Token URL**: https://core.spreedly.com/v1/payment_methods.json\n \n**Example\
\ Token Request**: \n \n``` \ncurl --request POST --url https://core.spreedly.com/v1/payment_methods.json\
\ --header 'content-type: application/json' -u \"login:password\" --data\
\ '{\n\t\"payment_method\": {\n\t\t\"email\": \"[email protected]\",\n\t\t\"credit_card\"\
: {\n\t\t\t\"number\": \"4111111111111111\",\n\t\t\t\"month\": \"09\",\n\t\
\t\t\"year\": \"2029\",\n\t\t\t\"first_name\": \"John\",\n\t\t\t\"last_name\"\
: \"Smith\",\n\t\t\t\"address1\": \"123 12th St\",\n\t\t\t\"address2\": \"\
Building B\",\n\t\t\t\"city\": \"Quebec City\",\n\t\t\t\"state\": \"QC\",\n\
\t\t\t\"zip\": \"G1R 4S9\",\n\t\t\t\"country\": \"CA\",\n\t\t\t\"verification_value\"\
: \"123\"\n\t\t}\n\t}\n}'\n```\n**Example Token Response**: \n``` \n{\n\t\
\"transaction\": {\n\t\t\"token\": \"KtToV20m9qT1Yi8pbTeLNz0Ypns\",\n\t\t\
\"created_at\": \"2023-11-29T13:31:56Z\",\n\t\t\"updated_at\": \"2023-11-29T13:31:56Z\"\
,\n\t\t\"succeeded\": true,\n\t\t\"transaction_type\": \"AddPaymentMethod\"\
,\n\t\t\"retained\": false,\n\t\t\"state\": \"succeeded\",\n\t\t\"message_key\"\
: \"messages.transaction_succeeded\",\n\t\t\"message\": \"Succeeded!\",\n\
\t\t\"payment_method\": {\n\t\t\t\"token\": \"MxyYEhDK12CUAA18bJDkAq0ab3y\"\
,\n\t\t\t\"created_at\": \"2023-11-29T13:31:56Z\",\n\t\t\t\"updated_at\"\
: \"2023-11-29T13:31:56Z\",\n\t\t\t\"email\": \"[email protected]\",\n\t\t\t\"\
data\": null,\n\t\t\t\"storage_state\": \"cached\",\n\t\t\t\"test\": true,\n\
\t\t\t\"metadata\": null,\n\t\t\t\"callback_url\": null,\n\t\t\t\"last_four_digits\"\
: \"1111\",\n\t\t\t\"first_six_digits\": \"411111\",\n\t\t\t\"card_type\"\
: \"visa\",\n\t\t\t\"first_name\": \"John\",\n\t\t\t\"last_name\": \"Smith\"\
,\n\t\t\t\"month\": 9,\n\t\t\t\"year\": 2029,\n\t\t\t\"address1\": \"123\
\ 12th St\",\n\t\t\t\"address2\": \"Building B\",\n\t\t\t\"city\": \"Quebec\
\ City\",\n\t\t\t\"state\": \"QC\",\n\t\t\t\"zip\": \"G1R 4S9\",\n\t\t\t\
\"country\": \"CA\",\n\t\t\t\"phone_number\": null,\n\t\t\t\"company\":\
\ null,\n\t\t\t\"full_name\": \"John Smith\"
# --- truncated at 32 KB (260 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/hopper-com/refs/heads/main/openapi/hopper-airlines-openapi.yml