HTS Airline API

The Hopper Technology Solutions Airline API lets airlines embed Hopper's ancillary fintech products — Cancel For Any Reason (CFAR) and Disruption Guarantee (DG) — directly into their booking flow. Airlines call the API to create a user session, request CFAR or DG offers for an itinerary, bind an offer into a contract, take payment, update itinerary slices, and later exercise the contract (cancel, refund, or rebook) on behalf of the customer. The API is OAuth2 Client Credentials authenticated, uses an HC-Session-ID correlation header, and exposes 23 operations under https://airlines-api.hopper.com/airline/v1.1.

HTS Airline API is published by Hopper on the APIs.io network, described by a machine-readable OpenAPI specification.

Tagged areas include Airlines, Travel Fintech, Cancel For Any Reason, Disruption Guarantee, and Ancillary Revenue. The published artifact set on APIs.io includes an OpenAPI specification, API documentation, and SDKs.

OpenAPI Specification

hopper-airlines-openapi.yml Raw ↑
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