3. API usage & integration

3.1 Which GraphQL calls handle creating, updating, and cancelling refunds?

  • Create: createQuote(request: [quoteRequest]!, isRequote?: Boolean, fetchFromGDS?: Boolean)
  • Update: updateQuote(request: quoteUpdateRequest!, requote?: Boolean)
  • Cancel: cancelQuote(ticketNum: String!): Boolean

3.2 What are the required vs. optional fields?

3.2.1 CreateQuote:

mutation CreateQuote($request: [quoteRequest]!) {
    createQuote(request: $request)
}

 Minimal variables:

{
    "request": [{ "ticketNum": "1282132019309" }]
}

Optional fields in quoteRequest include:

  • pnr: is a digital record of a passengers booking: flights, details, and services.
  • gds: is global network that distributes travel inventory and enables real-time booking.
  • agent: is the user or system that books travel through a GDS.
  • issueDate: the tickets creations date.
  • refundRequestDate: date refund was requested.
  • refundRequestedAt: timestamp when the refund request was logged in the system.
  • waiver: exception granted by the airline that overrides normal rules or penalties.
  • freeText: is an open field booking or ticket where agents can add notes or special instruction.
  • isEmd: stands for individual security electronic miscellaneous document used for security services.
  • metadata: data that describes other data.
  • iataCode: is the 2-3 letter identifier asign by IATA to airlines and airports.
  • clientData: is stored information about a customer, like name, contacts, and preferences (customer information record).

Example using more variables:

{
  "request": [
    {
      "ticketNum": "0192382929393",
      "gds": "sabre",
      "iataCode": "10839203"
    }
  ]
}

Using the Sync header

When you send a quote, you can control the response behavior using the Sync header.

  • No Sync header / Sync = false → Immediate response, confirmation of sending, processing occurs later.
{
  "data": {
    "createQuote": true
  }
}
  • With Sync header = true → Later response, but with the full quote result.
{
    "data": {
    "createQuote": [
        {
            "decision": "VOLUNTARY",
            "refundCandidate": {
                "ticketId": 464159578,
                "status": "REVIEW",
                "isAdminFeeApplicable": true,
                "refundableBaseFareAmount": 460,
                "refundAmount": 487.14,
                "refundCurrencyCode": "EUR",
                "refundFareAmount": 460,
                "refundTaxAmount": 87.14,
                "refundPenaltyAmount": 60,
                "refundType": "FULL FARE REFUND",
                "isGuaranteedRefund": false,
                "overrideRefundRoute": "GDS",
                "product": "ARP",
                "isVoluntaryRefund": true,
                "waiverForceFareRefundWithoutPenalty": true,
                "overrideTaxCalculations": false,
                "shouldCancelItinerary": false,
                "extraParams": {
                    "currentDate": 1759443208259,
                    "refundReason": "VOLUNTARY",
                    "refundability": {
                        "decision": [],
                        "buildSegments": true,
                        "fetchFareRules": true,
                        "invokeRudder": true,
                        "involuntary": false,
                        "reason": "VOLUNTARY",
                        "refundable": true,
                        "refundPartialSegments": false,
                        "roundDigits": 2,
                        "usdot": false,
                        "useFareRules": true
                    },
                    "fareBreakdown": {
                        "totalPaidFare": 460,
                        "openFare": 460,
                        "usedFare": 0,
                        "nonRefundableFare": 0,
                        "refundableFare": 460,
                        "totalPenaltyAmount": 60
                    },
                    "penaltyBreakdown": {
                        "currency_code": "EUR",
                        "fare_rules": 60,
                        "non_refundable_fare": 0,
                        "fixed_fees": 0,
                        "vat_fees": 0,
                        "admin_fees": 0,
                        "historical_pricing_fee": 0
                    },
                    "segments": [
                        {
                            "segmentIdx": 1,
                            "couponIdxs": [
                                1
                            ],
                            "couponStatuses": [
                                "OPEN"
                            ],
                            "segmentStatus": "OPEN",
                            "origin": "PAR",
                            "destination": "BUH",
                            "stopovers": [],
                            "originCountry": "FR",
                            "destinationCountry": "RO",
                            "stopoversCountries": [],
                            "departedAt": "2025-09-20T12:00:00.000Z",
                            "fareBasis": "IOWSFXFR",
                            "fare": 459.99549596,
                            "surcharge": 0,
                            "currencyCode": "EUR",
                            "marketingAirlineCode": "RO",
                            "penalties": [],
                            "extraParams": {
                                "roe": "0.883723",
                                "isNoShow": false,
                                "currencyExchangeDetails": {
                                    "input": {
                                        "amount": 520.52,
                                        "currencyCode": "NUC"
                                    },
                                    "output": {
                                        "amount": 459.99549596,
                                        "currencyCode": "EUR"
                                    },
                                    "rate": 0.883723,
                                    "date": "2025-06-13",
                                    "source": "gds"
                                },
                                "currencyExchange": {
                                    "amount": 459.99549596,
                                    "currencyCode": "EUR"
                                },
                                "originalCurrencyExchange": {
                                    "amount": 520.52,
                                    "currencyCode": "NUC"
                                }
                            }
                        }
                    ],
                    "reissue": false,
                    "lineageCount": 0,
                    "flightType": "INTERNATIONAL",
                    "safeBadge": true,
                    "autogenNotes": "⁣"
                },
                "notes": ""
            },
            "refundCandidateCoupons": [
                {
                    "couponIdx": 1,
                    "fare": 459.99549596,
                    "currencyCode": "EUR",
                    "extraParams": {
                        "isOpen": true,
                        "iataAreaOrigin": "2",
                        "countryOfOrigin": "FR",
                        "currencyExchange": {
                            "amount": 459.99549596,
                            "currencyCode": "EUR"
                        },
                        "countryAreaOrigin": "EUROPE",
                        "alternativeOrigins": [
                            "CDG",
                            "PAR"
                        ],
                        "cityIataCodeOrigin": "PAR",
                        "countryOfOriginName": "France",
                        "iataAreaDestination": "2",
                        "countryOfDestination": "RO",
                        "countryAreaDestination": "EUROPE",
                        "alternativeDestinations": [
                            "OTP",
                            "BUH"
                        ],
                        "cityIataCodeDestination": "BUH",
                        "currencyExchangeDetails": {
                            "input": {
                                "amount": 520.52,
                                "currencyCode": "NUC"
                            },
                            "output": {
                                "amount": 459.99549596,
                                "currencyCode": "EUR"
                            },
                            "rate": 0.883723,
                            "date": "2025-06-13",
                            "source": "gds"
                        },
                        "countryOfDestinationName": "Romania",
                        "originalCurrencyExchange": {
                            "amount": 520.52,
                            "currencyCode": "NUC"
                        }
                    }
                }
            ],
            "refundCandidateTaxes": [
                {
                    "taxCode": "YQ",
                    "segmentIdx": 1,
                    "couponIdx": 1,
                    "status": "OPEN",
                    "segmentStatus": "OPEN",
                    "segmentIsRefundable": true,
                    "amount": 25,
                    "currencyCode": "EUR",
                    "remittance": "fare complement",
                    "isValid": true,
                    "willRefund": true,
                    "isRefundable": true,
                    "isOpen": true,
                    "extraParams": {
                        "originalRemit": "fare complement"
                    }
                },
                {
                    "taxCode": "FR",
                    "segmentIdx": 1,
                    "couponIdx": 1,
                    "status": "OPEN",
                    "segmentStatus": "OPEN",
                    "segmentIsRefundable": true,
                    "amount": 18.19,
                    "currencyCode": "EUR",
                    "remittance": "transporting",
                    "isValid": true,
                    "willRefund": true,
                    "isRefundable": true,
                    "isOpen": true,
                    "extraParams": {
                        "explanation": {
                            "source": "RUDDER_TS",
                            "adjustments": [
                                {
                                    "type": "AMOUNT_RECONCILIATION",
                                    "reason": "Adjusted to match input sums"
                                }
                            ],
                            "ruleId": "48398136",
                            "segmentIdxAtSource": 1,
                            "couponIdxAtSource": 1
                        },
                        "originalRemit": "transporting"
                    }
                },
                {
                    "taxCode": "O4",
                    "segmentIdx": 1,
                    "couponIdx": 1,
                    "status": "OPEN",
                    "segmentStatus": "OPEN",
                    "segmentIsRefundable": true,
                    "amount": 30,
                    "currencyCode": "EUR",
                    "remittance": "transporting",
                    "isValid": true,
                    "willRefund": true,
                    "isRefundable": true,
                    "isOpen": true,
                    "extraParams": {
                        "explanation": {
                            "source": "RUDDER_TS",
                            "adjustments": [
                                {
                                    "type": "AMOUNT_RECONCILIATION",
                                    "reason": "Adjusted to match input sums"
                                }
                            ],
                            "ruleId": "44474192",
                            "segmentIdxAtSource": 1,
                            "couponIdxAtSource": 1
                        },
                        "originalRemit": "transporting"
                    }
                },
                {
                    "taxCode": "QX",
                    "segmentIdx": 1,
                    "couponIdx": 1,
                    "status": "OPEN",
                    "segmentStatus": "OPEN",
                    "segmentIsRefundable": true,
                    "amount": 13.95,
                    "currencyCode": "EUR",
                    "remittance": "transporting",
                    "isValid": true,
                    "willRefund": true,
                    "isRefundable": true,
                    "isOpen": true,
                    "extraParams": {
                        "explanation": {
                            "source": "RUDDER_TS",
                            "adjustments": [
                                {
                                    "type": "AMOUNT_RECONCILIATION",
                                    "reason": "Adjusted to match input sums"
                                }
                            ],
                            "ruleId": "49169923",
                            "segmentIdxAtSource": 1,
                            "couponIdxAtSource": 1
                        },
                        "originalRemit": "transporting"
                    }
                }
            ],
            "refundCandidateFulfillment": {
                "totalFare": 460,
                "usedFare": 0,
                "nonRefundableFare": 0,
                "fareToRefund": 460,
                "totalTaxes": 87.14,
                "usedTaxes": 0,
                "nonRefundableTaxes": 0,
                "taxesToRefund": 87.14,
                "fareRulePenalty": 60,
                "vatOnPenalty": 0,
                "serviceFee": 0,
                "totalPenalties": 60,
                "totalRefundAmount": 487.14,
                "currency": "EUR"
            },
            "refundability": {
                "decision": [],
                "buildSegments": true,
                "fetchFareRules": true,
                "invokeRudder": true,
                "involuntary": false,
                "reason": "VOLUNTARY",
                "refundable": true,
                "refundPartialSegments": false,
                "roundDigits": 2,
                "usdot": false,
                "useFareRules": true
            },
            "isSafeForRefund": true
        }
    ]
	}
}

3.2.2 UpdateQuote:

This mutation is used to update an existing quote with new request parameters.

mutation UpdateQuote($request: quoteUpdateRequest!, $requote: Boolean) {
    updateQuote(request: $request, requote: $requote)
}

 Minimal variables:

{
  "request": { "ticketNum": "1282132019309" }
}

quoteUpdateRequest supports many updatable fields using { from, to } envelopes (e.g., waiver, freeText, clientVisibility, fulfillment, taxes, etc.).

Updating the waiver of a quote

  • null → value or value → null: send requote: true.
{
  "request": {
    "ticketNum": "1282132019309",
    "waiver": { "from": null, "to": "Sample Waiver" }
  },
  "requote": true
}
  • value → different value: requote can be omitted or false.
{
    "request": {
        "ticketNum": "1282132019309",
        "waiver": { "from": "Old", "to": "New" }
    },
    "requote": false
}
  •  no change (both null): omit requote or false.

3.2.3 CancelQuote:

mutation CancelQuote($ticketNum: String!) {
    cancelQuote(ticketNum: $ticketNum)
}

 Variables:

{ "ticketNum": "1282132019309" }

3.3 How do I paginate or filter results?

For filtering use filter inputs decorated with @filter-enabled fields. Operators include equality and generated variants _like _not, _in, _contains, _lt/_lte/_gt/gte, etc. You can also combine with AND/OR.

Example (roles where name contains "admin"):

query Roles($limit: Int, $offset: Int, $roleFilter: RoleFilter) {
    roles(limit: $limit, offset: $offset, roleFilter: $roleFilter) {
        edges {
            node {
                id
                name
                description
            }
        }
        pageInfo {
            total
            perPage
            totalPages
            hasNextPage
            hasPreviousPage
        }
    }
}

Variables:

{ "limit": 10, "offset": 0, "roleFilter": { "name_contains": "admin" } }

For pagination (limit & offset), fields annotated with @paginate accept limit and offset and return

{
  edges {
    cursor
    node
  },
  pageInfo {
    total
    perPage
    totalPages
    hasNextPage
    hasPreviousPage
  }
}

Defaults: limit 10, offset 0.

Example (second page of roles):

{ "limit": 10, "offset": 10, "roleFilter": {} }

3.4 Do you support idempotent operations to prevent duplicates?

Yes. When a new record is created for a ticket/order, it is marked as the current active record and any previous current is unset, ensuring a single active record.

3.5 How do I request a refund?

  • Step 1: Make sure you have a quote for the ticket in question.

  • Step 2: In GraphQL, run the processRefund mutation.

    mutation ProcessRefund($input: [processFulfillmentRequest]) {
      processRefund(input: $input)
    }

    Minimal variables:

    {
      "input": [
        {
          "fulfillmentRequest": {
            "ticketNum": "1739240193092"
          }
        }
      ]
    }

    You can submit one or multiple refund requests in a single call.

    {
      "input": [
        {
          "fulfillmentRequest": {
            "ticketNum": "1739240193923"
          }
        },
    		{
          "fulfillmentRequest": {
            "ticketNum": "1739240193092"
          }
        }
      ]
    }

    Optional fields: gds, iata, and issueDate. If you don’t know them, you can omit them (they’ll be filled in from the ticket number when possible).

    {
      "input": [
        {
          "fulfillmentRequest": {
            "ticketNum": "1739240193923",
            "issueDate": null,
            "forceCashFopInBSP": null,
            "isEmd": null,
            "pnr": null,
            "refundMode": null,
            "testingMode": null
          },
          "gds": null,
          "iata": null
        }
      ]
    }

    On success, you’ll receive a per-ticket summary for each submitted ticket.

    All tickets successfully enqueued for processing.

    {
      "data": {
        "processRefund": {
          "success": true,
          "message": "All documents processed successfully",
          "results": [
            {
              "ticketNum": "1739240193923",
              "success": true,
              "message": "Queued for processing"
            }
          ]
        }
      }
    }

    Partial success.

    {
      "data": {
        "processRefund": {
          "success": false,
          "message": "Some documents processed; see results",
          "results": [
            {
              "ticketNum": "23260543607",
              "success": false,
              "message": "Invalid ticket num"
            },
            {
              "ticketNum": "0722989792111",
              "success": true,
              "message": "Queued for processing"
            }
          ]
        }
      }
    }

    No tickets were enqueued for processing.

    {
      "data": {
        "processRefund": {
          "success": false,
          "message": "No valid requests to process",
          "results": [
            {
              "ticketNum": "23260543607",
              "success": false,
              "message": "Invalid ticket num"
            },
            {
              "ticketNum": "07229897111",
              "success": false,
              "message": "Invalid ticket num"
            }
          ]
        }
      }
    }
  • Step 3: Your refund request is complete; the status should be visible in a few seconds.

3.6 How do I search the refund details?

Once your refund request has been created, you can verify and review its information using the following query.

This query allows you to retrieve the details of a specific refund — including its status, associated files, and request metadata. You can also extend the query to include additional related data as needed, depending on your integration or data requirements.

query SearchRefundDetails($filter: DocumentFilter) {
   documents(filter: $filter) {
     edges {
       node {
         ticketNum
         iataCode
         commissionPercent
         quote {
           product
           refundRoute
           taxInfo {
             code
             refundAmount {
               quantity
               currencyCode
             }
           }
         }
         unifiedRefund {
					 via
           requestDate
           authorizationDate
           fopType
           totalRefund
           totalFare
           totalTax
           totalPenalty
           currencyCode
           document
           status
           rejectionDate
           updatedDate
           settlementPeriod
         }
       }
     }
   }
}